大洲的小偷程序非常让人眼馋,无奈本diao丝程序员,一无RMB,二无论坛币,只能望洋兴叹,所幸我有web程序开发的经验,对于这个小偷程序的基本原理能猜到不少,本着自力更生,服务大众的精神,我自己实现了一个简易版,在此开源给大家,希望能赚点论坛币,早日进入email版见见世面。
Q9 v0 ^0 s/ e! |2 K6 r
& Y4 e( j; R) ~8 A1 k一、原理
& m4 A0 d- O5 a0 m% t1.用户访问流程:2 L6 ~' B3 i6 _9 q/ z; v
(1)用户访问我们的冒牌站(A.com)
# h: h, ]+ p6 A& z! Y. V(2)网站后台程序根据用户的query参数(包括get/post/cookie)构造原始网站B.com的url,用后台程序去访问该url,此时可以拿到原始网站的html和header输出。这里有一点需要注意的是原始网站输出的头也不可以忽略,里面的set-cookie信息也可以转发给用户的,这样就可以实现注册和登陆原网站啦。# I& X1 h9 T8 e5 A
(3)对原始网站的html输出和header输出按某些规则做替换,比如把某些广告去掉啦,把B.com的地址替换成A.com啦,其实这一步是最关键的,也是玩法最多最好玩的部分! V! @/ I6 F3 \3 a* b
(4)将替换后的html和header输出给用户。
' K+ [' c$ O7 N8 X
) a$ d1 V( L6 H6 Y5 l2.规则替换的几种玩法:
# t+ d8 ~" h; L$ x2 N8 F: w" l8 W5 Q9 d, s(1)最简单的当然是字符串和正则表达式了,这就不多说了
f; ?4 w' f6 ~5 t2 l ](2)用html解析库对html的dom节点做操作,然后重新生成html,比如可以把页面中的text node翻译成另一种语言,或者做文章重写,这样比较容易逃过搜索引擎的法眼。
" l* Z; H7 ?9 I据我所知每种语言都由若干个html库,比如php的有DOM、phpQuery等,java的有htmlcleaner等
( i7 @+ P; [) j2 F# ?1 S! M(3)在原始html代码的后面加入一些javascript代码,用来隐藏一些页面元素,或加入一些广告代码等4 d( [- E9 a, Q( O, W5 i+ c3 b
* ]- N3 f& U7 M( L. w% @4 `7 E) l7 X9 T
3.关于速度和性能:
K+ f; U0 f' ?- n5 \' \2 Q4 a/ f1 O2 ](1)提到性能第一个想到的当然是缓存啦,我觉得最适合加缓存的地方就是上文1.1.2中提到的生成原始网站url后,这里可以对原始url做md5编码,访问一次改url后就把它的内容和头存到硬盘上,这样就不用每次都去原网站拉取了。做缓存的另一个好处是不用担心被原网站屏蔽。; T, p6 _# E, a5 g8 [
: Y3 `2 Y& u4 |8 q$ |5 B# z
(2)对于css,图片,js等静态文件,其实不用每个文件都让php访问原网站拉取,可以直接返回个302,让浏览器直接去原网站拉取。
( m4 Y! }/ b) W8 b2 K* E: F( J3 J/ [8 m) \
0 A& L3 o- _+ g) S1 F, i# V
二、实现
- \% T; ?" \' \# I; Y1.程序语言:+ K2 g, P6 }- T- }/ P
其实这个东西哪种语言都能搞定,也都不麻烦,我对php比较熟,就选了php。( X) R5 i: H9 I) V
2.一些准备工作:
3 w8 l o; |4 g(1)修改apache的rewrite规则,因为我们的程序只有一个文件,我们必须把所有接收到的请求都重定向到这个文件,这里我假设重定向到index.php,在apache的<VirtualHost>中加入这几句,如果是虚拟主机的话就修改.htaccess吧,不过我没试过,所以不知道怎么写re它的write规则5 w. D; {+ F# N" y) z$ _: g
RewriteEngine on1 ^2 x3 k$ r) N# A
RewriteCond %{DOCUMENT_ROOT}%{SCRIPT_FILENAME} -s [OR]
, b8 l4 `, w0 b! E" m9 yRewriteCond %{DOCUMENT_ROOT}%{SCRIPT_FILENAME} -l [OR]
3 n& ^* a ?$ c% ^ RewriteCond %{DOCUMENT_ROOT}%{SCRIPT_FILENAME} -d
) ]- y9 U7 C8 O9 L0 j8 V$ f% e9 A# E RewriteRule ^.*$ - [NC,L]) e# H N3 ^( |; }$ J# ^# Q
RewriteRule ^.*$ /index.php [NC,L]
* n2 U1 n4 [+ b* o! h6 i; g+ t
& P* N F9 p6 L7 c! X% v(2)安装php的http模块
# o; \! ~6 L- C {' z1 l6 Qphp发http请求的函数库找了好几个,发现http模块是用起来最简单的,不过需要你会linux操作哦,安装方法在这里http://php.net/manual/en/http.install.php5 D+ `5 i3 t" F" ]/ f
ps:如果安装不上或没有vps,请把下面程序的http模块的函数换成phpcurl等http lib
: W2 [" R6 A/ j: [' [
, T2 z9 b. _- z3.index.php的代码:
9 Z7 `5 x$ Z: q" F) |# d" [1 x- b! n0 p7 Z1 c2 T2 r& {! r6 c
7 w" c: V9 ]) t7 Y, N: o4 f- ]. }$host = $_SERVER['HTTP_HOST'];5 M% m* C1 Z j* P0 w" i
//这里把假站的域名替换成原始网站的,用于生成原始url" F3 r/ z/ ^: Z5 V
$host = str_ireplace('fake.com', "true.com", $host);) a( x: R" e; n8 k
$toUrl = sprintf("http://%s%s", $host,$_SERVER['REQUEST_URI']);
) ]4 i1 M3 O( G4 ` j
7 L! W8 }2 w7 L$script_name = $_SERVER['SCRIPT_NAME'];; ]* E# U7 E- E8 v" \- ~
$arr = explode(".", $script_name);4 X N% c0 O8 s$ V, }- t' H
$endName = $arr[count($arr) - 1];
8 ?" `# ~0 j2 r: W. X9 s7 A5 ?6 J6 T6 l7 j( H2 M
/ G- f1 h: c/ d% b. i//这些后缀结尾的url直接返回302
5 L* d7 Z/ h( u$STATIC_END_NAME = array('css','xml','rss','gif','jpg','jpeg','js','axd','atom',8 o6 U' [4 q0 O; t5 r
'mml','txt','jad','htc',
7 n2 D m2 i7 b 'png','tif','tiff','wbmp','ico','jng','bmp','svg',
# {4 v/ U+ F# q- o ]/ h1 A 'jar','war','ear','hqx','doc','pdf','ps','eps','ai',1 `8 L/ I/ H# Y0 z' A% c7 {
'rtf', 'xls', 'ppt', 'wmlc', 'xhtml', 'cco', 'jardiff',
% B* {6 w3 O% R 'jnlp', 'run', 'pl', 'pm', 'prc', 'pdb', 'rar', 'rpm',
4 q D% c) L8 e7 o1 s 'sea', 'swf', 'sit', 'tcl', 'tk', 'der', 'der', 'crt',7 }/ E# [7 J# B
'xpi', 'zip', 'bin', 'exe', 'dll' ,'deb', 'dmg', 'eot',
, `) ]2 \" P- C4 M 'iso', 'img', 'msi', 'msp', 'msm' ,'mid', 'midi', 'kar',+ a# G5 s8 ~6 q" O7 \, ^% a
'mp3', 'ra', '3gpp', '3gp', 'mpeg', 'mpg', 'mov', 'flv',
1 q, G& e" M8 _$ G6 N% h 'mng', 'asx', 'asf', 'wmv', 'avi');/ y l ^6 o$ r# d5 ^0 L
6 h/ O+ r8 G4 m1 ?2 V" _7 s( D
if(in_array($endName ,$STATIC_END_NAME)), |1 H- e; E/ ?
{" ]8 z4 T! V9 q1 _) B1 S: Y/ d0 j
$headerStr = sprintf("Location: %s", $toUrl);, x5 m' h+ N3 `' Q' W/ E4 f/ F
header( $headerStr, true, 302);
& Y- h& R8 D7 ` exit;
3 e) |! \/ {2 w/ e5 U6 [, N}
4 r" [* S/ W2 V9 N& L% z6 e
. H# z; W9 X i1 V. W//一个简单的cache7 J; R, m! X+ Z- n, C6 e5 G" \
function GetFromCache( $url)4 U5 Q2 V* l0 t% F' q. L
{( W4 q% P4 ~$ z7 `& K2 [' w
$current_dir = dirname(__FILE__);# S9 E" e, a- b/ i, W9 o: F
$cache_dir = $current_dir . "/cache/";
; m. `2 L- U& l, c/ C' F if( !is_dir( $cache_dir))3 K, a9 ^( S- r, A$ a; j0 e& d; o
{. _$ c: ^/ ?# Q
, ^5 E+ n0 m9 u2 F* W1 I mkdir($cache_dir);- F, k8 S, t' ^$ U A
}
2 g7 Q2 I7 ~; I/ B/ g6 x% C/ |: f- E* h' f5 ~5 [
$cache_file = $cache_dir . md5($url);% ?& O/ S. x3 j. f! R! g
if(file_exists( $cache_file))7 J f ]1 z5 B* J
{, h' [: ]1 c4 Z+ r" C! O9 M2 r
$html = file_get_contents( $cache_file);
! R7 E8 e5 z- v% V" d' e; k& S if($html == false)
( m; m. l: x5 i5 w& u' d7 k) x3 f {' W6 h7 K( L$ {2 o/ p
$html = "";7 {4 |" |6 g5 ?0 z! [
}# O0 Q/ W& `' l# H, y8 J
}else% @) s: S7 X5 f3 `( s; I
{
3 m7 f% E6 W @; B ] //访问原始网站
# e( F* P- n2 ^5 Q. @$ d $data = http_get($url ,array('redirect' => 5, 'timeout' => 10), $http_info );' {+ u6 r$ }& P, M$ ]! K; p/ w$ ^
$message = http_parse_message($data); H, K0 X3 B9 [- a: f! w$ X
0 ?+ a/ Y5 x" k, Y! ?/ _
$html = trim($message->body);
* Q9 n$ l! \0 [6 k* i
* I; e! | C; s O5 s8 ] file_put_contents( $cache_file, $html);3 Z) R# r, C$ k3 S+ q
}
. m8 H' G# O; i! C
# v% ?& \; Q& q- l4 s( ~ return $html;
8 C/ a; h# z* ^0 c$ a2 M" ^9 Z}
( U* V, L: Z' ~ ^& \
% I7 Y$ V! H! X3 l$html = GetFromCache( $toUrl );
9 E% \" a& [$ f6 @$ d* @
# ~* |% U9 W/ i7 D# M% b$ d! U" N: K+ @ m" {
$html = str_replace("circleid.com", "circleid.us", $html);
2 [9 t, L, y1 j2 K8 a8 `& I9 A( d% ~8 y. M( T2 M- E' t% m
$html = preg_replace('/<meta name=.*>/', "", $html);
( s# S0 t+ A" ]+ ], E3 u, @1 _* P4 O+ s9 c& n
- {; X9 J/ C: z//注释的这两句是用phpquery操作
8 y3 _4 W& f: G0 o2 _//$body = htmlqp($body)->find('#header')->remove()->html();- d6 R6 s& {/ @
//$html = htmlqp($html)->find('#header')->remove()->document->saveHTML();& @6 S6 Y7 `$ n/ y5 K) f$ g
Y- d. C3 L# o. h- X
$script = <<<EOD
6 ~! \" ]9 L2 j: J- A' k/ Z<script>
( C! |: X. i; e$ w$ A' r, B& e$(document).ready(function() {) u6 ? O. M# E% J
$("#footer").remove();0 C# N) F' U9 i
' I& C8 q# ~' X) F' I
});
' R$ |/ S3 c& o2 A/ _7 d& R% f0 C |
</script>
9 L) y+ h/ M3 t4 _; f0 F/ Q: E8 R" X' D2 Q1 P
EOD;" ~: r. |) \6 \2 B7 J
6 r- t0 m( z3 B: B& u$ T# q
echo($html . $script);" Q3 U* e- E/ c K/ f$ z7 B, u5 e
* {/ J! ]) t* F3 E5 _$ C
( \# |5 I1 p" {
三、最后' O$ C8 B+ |; B( Z( K
1.总之,这个程序还很简陋,没有处理post和cookie参数,也没有配置管理模块,距离大洲的程序差距有一个大洲那么大,仅适合稍微懂点程序又有点好奇心的新手玩玩: U( T( |, o, V% e# u
2.最后当然是希望大家不令赐分啦,您的论坛币是我继续分享的动力,哈哈1 A. ~, d& F( Q5 z! P
& z; |! I% e* N3 j9 ^: ]
|