大洲的小偷程序非常让人眼馋,无奈本diao丝程序员,一无RMB,二无论坛币,只能望洋兴叹,所幸我有web程序开发的经验,对于这个小偷程序的基本原理能猜到不少,本着自力更生,服务大众的精神,我自己实现了一个简易版,在此开源给大家,希望能赚点论坛币,早日进入email版见见世面。; a& Y B, @- ` z
D o G0 d+ Y- l6 g
一、原理* c, m2 I' }& H
1.用户访问流程:, @: t9 x6 v: w+ v5 ?% o/ {1 `
(1)用户访问我们的冒牌站(A.com)
0 M1 K9 m$ C8 B# P b- Q(2)网站后台程序根据用户的query参数(包括get/post/cookie)构造原始网站B.com的url,用后台程序去访问该url,此时可以拿到原始网站的html和header输出。这里有一点需要注意的是原始网站输出的头也不可以忽略,里面的set-cookie信息也可以转发给用户的,这样就可以实现注册和登陆原网站啦。
$ g+ W# i# Z9 B- K- f+ j# D(3)对原始网站的html输出和header输出按某些规则做替换,比如把某些广告去掉啦,把B.com的地址替换成A.com啦,其实这一步是最关键的,也是玩法最多最好玩的部分
8 J% j) d, z% j" [* d0 S. F! d(4)将替换后的html和header输出给用户。) G' ]# V( [# @3 P- c. b
' e5 v3 x+ \4 K) J2.规则替换的几种玩法:0 `, o8 K5 C3 |) i8 p
(1)最简单的当然是字符串和正则表达式了,这就不多说了
9 V* _ Y7 k4 ]8 `" I, H: ]7 I(2)用html解析库对html的dom节点做操作,然后重新生成html,比如可以把页面中的text node翻译成另一种语言,或者做文章重写,这样比较容易逃过搜索引擎的法眼。0 f0 h, H, Y, _+ V
据我所知每种语言都由若干个html库,比如php的有DOM、phpQuery等,java的有htmlcleaner等: T. e+ ]0 l- w2 q& v
(3)在原始html代码的后面加入一些javascript代码,用来隐藏一些页面元素,或加入一些广告代码等- A& q- a$ f3 s1 A+ i. c9 L
$ e% E/ Y O4 ]" g& p8 G, u3.关于速度和性能:
* f, k9 d2 V2 G, J- _(1)提到性能第一个想到的当然是缓存啦,我觉得最适合加缓存的地方就是上文1.1.2中提到的生成原始网站url后,这里可以对原始url做md5编码,访问一次改url后就把它的内容和头存到硬盘上,这样就不用每次都去原网站拉取了。做缓存的另一个好处是不用担心被原网站屏蔽。
8 j# \6 C+ r& G& m8 Q, U0 H
?2 Z$ P# C8 l6 C, }(2)对于css,图片,js等静态文件,其实不用每个文件都让php访问原网站拉取,可以直接返回个302,让浏览器直接去原网站拉取。. B. L" L7 X! H: `
+ U0 i7 X3 ^9 i( T1 j$ L* ]
9 T( q3 r, X0 U, i" A二、实现
0 O j) i8 U& Q4 K4 |& m8 R1.程序语言:
" z/ ^$ W8 ]5 [. A( Q, _其实这个东西哪种语言都能搞定,也都不麻烦,我对php比较熟,就选了php。" S/ T0 `0 x+ ^4 g7 o) g- w4 G
2.一些准备工作:2 d" M# [7 w2 {% O4 K a
(1)修改apache的rewrite规则,因为我们的程序只有一个文件,我们必须把所有接收到的请求都重定向到这个文件,这里我假设重定向到index.php,在apache的<VirtualHost>中加入这几句,如果是虚拟主机的话就修改.htaccess吧,不过我没试过,所以不知道怎么写re它的write规则
$ E- g1 T# H' L: O7 e) n2 F RewriteEngine on# A2 F. }( G0 X
RewriteCond %{DOCUMENT_ROOT}%{SCRIPT_FILENAME} -s [OR] q# H/ U+ H8 u# _0 S7 Q
RewriteCond %{DOCUMENT_ROOT}%{SCRIPT_FILENAME} -l [OR]; a9 p q. Q: Z0 T% m( T8 M* I7 X, ?
RewriteCond %{DOCUMENT_ROOT}%{SCRIPT_FILENAME} -d
: m3 ]7 K* I1 W h RewriteRule ^.*$ - [NC,L]) S) u$ j% s% ^7 n) ]$ m6 X
RewriteRule ^.*$ /index.php [NC,L]1 G v$ [- q( L. b) F1 R$ E6 H+ z0 R
/ s3 A K2 r! i; D8 h7 @+ i( R(2)安装php的http模块
& @5 e! Y. h: u( n aphp发http请求的函数库找了好几个,发现http模块是用起来最简单的,不过需要你会linux操作哦,安装方法在这里http://php.net/manual/en/http.install.php) _- F- s% X2 ^4 [6 ^1 [9 r6 c
ps:如果安装不上或没有vps,请把下面程序的http模块的函数换成phpcurl等http lib- J' c9 o: e l$ p
& ^" u' H' y6 C5 u; P( [0 \5 M
3.index.php的代码:4 m# f% k4 M0 s: V# K' t
. i& I) r; b s5 [( T4 O& W
: K' R6 K) |2 c- ^0 Q9 w
$host = $_SERVER['HTTP_HOST'];% M. l0 A+ E. G6 n8 P
//这里把假站的域名替换成原始网站的,用于生成原始url3 r, g9 D9 H) ?
$host = str_ireplace('fake.com', "true.com", $host);, A- P2 |8 ^; J" d7 u
$toUrl = sprintf("http://%s%s", $host,$_SERVER['REQUEST_URI']);5 L0 i0 b& F0 ^6 V" }% [7 O
$ p8 X2 G' ]* v9 d: \$script_name = $_SERVER['SCRIPT_NAME'];
* G7 Z5 T9 S( Q+ V+ v$arr = explode(".", $script_name);5 D: [& y& ~! X! Z2 W+ \# A6 T
$endName = $arr[count($arr) - 1];& A7 Z- p8 }* N) ]+ `( }3 u
j5 s! K H" Z! x( L+ T( E. U- \6 B4 ^
//这些后缀结尾的url直接返回3024 U4 Y; b7 o6 F5 w( D, J& G1 f
$STATIC_END_NAME = array('css','xml','rss','gif','jpg','jpeg','js','axd','atom',
2 E* s7 [, `. h 'mml','txt','jad','htc',6 Q1 q- p6 O; P/ R8 C! I8 s# \
'png','tif','tiff','wbmp','ico','jng','bmp','svg',2 I8 p. f. r4 f9 q6 I& n6 R
'jar','war','ear','hqx','doc','pdf','ps','eps','ai',- ^9 c; E9 V. q
'rtf', 'xls', 'ppt', 'wmlc', 'xhtml', 'cco', 'jardiff',; s7 M7 w$ d: b) t9 a- _, N* k- x
'jnlp', 'run', 'pl', 'pm', 'prc', 'pdb', 'rar', 'rpm',
# x0 C% S p( B: P9 p } 'sea', 'swf', 'sit', 'tcl', 'tk', 'der', 'der', 'crt',
+ j0 G8 w; p9 \ 'xpi', 'zip', 'bin', 'exe', 'dll' ,'deb', 'dmg', 'eot',
# |9 N, L4 U6 B1 _8 D/ c+ e 'iso', 'img', 'msi', 'msp', 'msm' ,'mid', 'midi', 'kar',
' K8 y( W' c& {" }0 s8 {. I9 x$ _ 'mp3', 'ra', '3gpp', '3gp', 'mpeg', 'mpg', 'mov', 'flv',
) { Q0 U' J3 E2 o# J 'mng', 'asx', 'asf', 'wmv', 'avi');; ^ q* z. ^' U5 l& j
5 |: S7 [2 N8 _7 F
if(in_array($endName ,$STATIC_END_NAME))% e$ Z! g. o( y% e+ H
{
) u. I! _, J% d $headerStr = sprintf("Location: %s", $toUrl);
4 q) K2 A) U8 Y/ I header( $headerStr, true, 302);
7 r. U( B+ f/ p2 P( h" Y2 S4 Z exit;2 Q2 I+ |6 Z% p" t
}
( Z3 h7 T# m3 l, U/ g, k/ ~& C3 S" x
//一个简单的cache
; s/ A& s5 R+ P) Sfunction GetFromCache( $url)
! Y: \' }+ f( s& w0 e+ J" |( ]{/ Z% K. z' y2 s* O3 L- X% ?! n) v9 s9 S
$current_dir = dirname(__FILE__);9 d& l( U* L7 ]; ^( s
$cache_dir = $current_dir . "/cache/";( A+ \0 e. ?/ k
if( !is_dir( $cache_dir))4 T" b% K0 b' A) p
{
5 L; B) T) ]. ~9 G" o: x
& E8 c& _" ]9 [) u mkdir($cache_dir);
3 r' q: e; Z8 h4 ^4 B8 ` }) S% ^/ U& X# B7 K& v% e
+ j# B( X `7 c0 H1 @1 G
$cache_file = $cache_dir . md5($url);
7 W4 h) d" O" S if(file_exists( $cache_file))4 m/ F/ u6 Y& q! @7 T
{) c6 w2 J# D$ ]: Q6 h7 |. V
$html = file_get_contents( $cache_file);/ {5 x1 o( U7 z5 I" J0 k# {
if($html == false)
' r. E- q- ^, z9 C# s P3 { {
/ C3 s+ }9 q1 Z$ V3 i $html = "";
0 ?7 {& g; @3 ~5 D% G B }4 i) F7 F/ p" |2 y, `# m& Z
}else" s& ]& o; r. w
{
" O s, P9 l7 i: X4 N //访问原始网站
; \, N: c0 z& c. T1 u $data = http_get($url ,array('redirect' => 5, 'timeout' => 10), $http_info );$ s+ c2 D7 k, l* R3 F$ q/ R
$message = http_parse_message($data); M- |# _5 J; Z4 v' B
% F3 l s1 m4 W! F. R6 F $html = trim($message->body);) |# u% g5 E3 A2 N
; {5 d7 H" Q& h file_put_contents( $cache_file, $html);
1 X: c$ J7 A% ^% M: [) f5 S" t+ E }" P7 y* p2 `& V1 n
4 B* ?! i' B0 W$ T: P) D" p2 W return $html;
( n: O( t, I; P}
9 @: F! w5 r; V5 A8 w+ v U- n2 D% H: H
! k5 x8 \( E' d% E$html = GetFromCache( $toUrl );
. v0 r# g( d$ o+ p, r( E0 g/ L( _0 N2 @
1 F2 q# E0 ~' N
$html = str_replace("circleid.com", "circleid.us", $html);
% O% W2 ^+ n8 Q9 O4 G6 h. G9 [; p# v0 s5 {5 \' Q4 I
$html = preg_replace('/<meta name=.*>/', "", $html);
0 `5 S+ U/ |! f+ ~( I6 ]" c2 P7 H x/ j7 p8 }3 h) n) I0 l' _
, P" m8 f5 Y! P# I* R8 ] N% j3 P//注释的这两句是用phpquery操作 v5 A/ x( ]' ~7 o) M) A( T9 p
//$body = htmlqp($body)->find('#header')->remove()->html();) R/ F' w1 B8 p( F
//$html = htmlqp($html)->find('#header')->remove()->document->saveHTML();
6 ]# l3 l* `6 r! P/ y! o
# k! J" l: Z/ z2 y$script = <<<EOD
8 Z& t8 T6 x" s8 t<script>9 m$ ] l# @# [
$(document).ready(function() {
7 r; E# I7 N, k# E8 w! S, h $("#footer").remove();% T' d; z: N5 C. E' f8 E
" y! f4 o: B n
});
' v+ U9 x2 [* _, y5 {$ y2 u6 Z7 h+ T( `6 z# R# J8 g
</script>
- g6 x: W/ W, e& g/ T5 j/ T. u) `# [$ y5 P
EOD;5 ]4 E# g, v, d8 l& w# x
/ c8 w) q( N% n" Pecho($html . $script);
3 h. }# ^0 S0 s8 B. ]1 e/ R
6 i4 }/ k* S& q3 \+ I
& ~2 l% x; }/ e5 R三、最后; T {- \' W! ?+ w
1.总之,这个程序还很简陋,没有处理post和cookie参数,也没有配置管理模块,距离大洲的程序差距有一个大洲那么大,仅适合稍微懂点程序又有点好奇心的新手玩玩
3 U/ Z3 I, D8 H+ H9 b2.最后当然是希望大家不令赐分啦,您的论坛币是我继续分享的动力,哈哈
* p. B0 {* ^- ] Z( [4 u4 C8 ]2 \7 n+ |5 | g, q
|