大洲的小偷程序非常让人眼馋,无奈本diao丝程序员,一无RMB,二无论坛币,只能望洋兴叹,所幸我有web程序开发的经验,对于这个小偷程序的基本原理能猜到不少,本着自力更生,服务大众的精神,我自己实现了一个简易版,在此开源给大家,希望能赚点论坛币,早日进入email版见见世面。
6 }1 K% B1 ?3 Z/ W7 H$ W
6 n" r1 Y; ~1 h0 L9 c! M一、原理3 h4 G- ?: B- d C0 B
1.用户访问流程:8 l J9 C. ~( B7 y! c
(1)用户访问我们的冒牌站(A.com) ?8 Q9 W3 R7 E4 N
(2)网站后台程序根据用户的query参数(包括get/post/cookie)构造原始网站B.com的url,用后台程序去访问该url,此时可以拿到原始网站的html和header输出。这里有一点需要注意的是原始网站输出的头也不可以忽略,里面的set-cookie信息也可以转发给用户的,这样就可以实现注册和登陆原网站啦。2 e5 a' p; D) a% q1 ~
(3)对原始网站的html输出和header输出按某些规则做替换,比如把某些广告去掉啦,把B.com的地址替换成A.com啦,其实这一步是最关键的,也是玩法最多最好玩的部分
8 F# y6 O9 \* S5 I4 Y: o( m% Z(4)将替换后的html和header输出给用户。8 p; w. S2 D7 D L. h
, t# ?3 i& K( K8 S4 o
2.规则替换的几种玩法:
R& B/ f/ t$ L( d& |$ Y" [. @/ `9 r(1)最简单的当然是字符串和正则表达式了,这就不多说了
' ]: _0 [2 U: X' e6 R(2)用html解析库对html的dom节点做操作,然后重新生成html,比如可以把页面中的text node翻译成另一种语言,或者做文章重写,这样比较容易逃过搜索引擎的法眼。
. C' V) a6 c% C) K8 v* k据我所知每种语言都由若干个html库,比如php的有DOM、phpQuery等,java的有htmlcleaner等: E6 t* q* K3 n) d0 d W$ a
(3)在原始html代码的后面加入一些javascript代码,用来隐藏一些页面元素,或加入一些广告代码等. I' C9 R2 k7 J. Z4 ]1 ^
" l! F- r8 N" y& k& [* e
3.关于速度和性能:. M: H9 u, O. F
(1)提到性能第一个想到的当然是缓存啦,我觉得最适合加缓存的地方就是上文1.1.2中提到的生成原始网站url后,这里可以对原始url做md5编码,访问一次改url后就把它的内容和头存到硬盘上,这样就不用每次都去原网站拉取了。做缓存的另一个好处是不用担心被原网站屏蔽。' {: d ?+ `; e N" h6 W0 R* M/ n
1 {7 E4 P- J9 ?
(2)对于css,图片,js等静态文件,其实不用每个文件都让php访问原网站拉取,可以直接返回个302,让浏览器直接去原网站拉取。/ `' Y! t, Y6 g: `+ F$ G# K, X
+ U5 F% e) f) z! p8 r; C
9 `$ p( U( Z# a" P+ m) o$ g/ t二、实现
# m& ]2 S2 ~6 q4 ?1.程序语言:9 p: z' t1 H& ?. J
其实这个东西哪种语言都能搞定,也都不麻烦,我对php比较熟,就选了php。6 C( Z. N( {' H: d9 u# y. e6 v
2.一些准备工作:% {- O, r1 Z% V3 t; e9 _
(1)修改apache的rewrite规则,因为我们的程序只有一个文件,我们必须把所有接收到的请求都重定向到这个文件,这里我假设重定向到index.php,在apache的<VirtualHost>中加入这几句,如果是虚拟主机的话就修改.htaccess吧,不过我没试过,所以不知道怎么写re它的write规则
8 F$ V; S0 \& U+ j, X! d RewriteEngine on
: z: O' Z( B6 `# p+ b RewriteCond %{DOCUMENT_ROOT}%{SCRIPT_FILENAME} -s [OR]
# b P" I8 l; e0 U7 k+ iRewriteCond %{DOCUMENT_ROOT}%{SCRIPT_FILENAME} -l [OR]
4 w% o9 `6 D( r! F3 H! @ [ RewriteCond %{DOCUMENT_ROOT}%{SCRIPT_FILENAME} -d
* ~. l6 N, D* F! S( S RewriteRule ^.*$ - [NC,L]
8 G0 J+ O3 L1 J: r" C- k2 ` RewriteRule ^.*$ /index.php [NC,L]
$ ]$ f$ u8 Y+ D- m' I" b L
! T' V& q, O' U Q6 R! l2 }(2)安装php的http模块
% A. |8 W- k M0 P0 ?! [php发http请求的函数库找了好几个,发现http模块是用起来最简单的,不过需要你会linux操作哦,安装方法在这里http://php.net/manual/en/http.install.php
; ]1 f0 v$ U' ~+ Dps:如果安装不上或没有vps,请把下面程序的http模块的函数换成phpcurl等http lib
0 Q( v0 _* |" L
7 t0 F7 Q& {8 E/ i! j3.index.php的代码:$ d! v1 g+ x) z) X V, s
! b7 I7 x3 F& K8 s: [* [
I: E: t+ S1 }2 r7 p$host = $_SERVER['HTTP_HOST'];
& S3 j# c* g p0 r! Q//这里把假站的域名替换成原始网站的,用于生成原始url
3 I: `9 f$ f9 ~" H& ?9 P$host = str_ireplace('fake.com', "true.com", $host);5 U: i$ g% n; h, I4 L8 f2 u8 X# C
$toUrl = sprintf("http://%s%s", $host,$_SERVER['REQUEST_URI']);
7 R" g/ Q+ H* N0 f. p4 \* Z9 H7 S' ]; e* ~2 t
$script_name = $_SERVER['SCRIPT_NAME'];" M% [5 y: S) |$ b
$arr = explode(".", $script_name);
) A4 A# P& S/ i" N- n; `$endName = $arr[count($arr) - 1];
# t6 M' F, M) I W% [0 N8 B
7 {1 E6 b8 y+ f
) x) F6 p: I! ^9 w5 K9 ~//这些后缀结尾的url直接返回302
8 J7 @3 x0 K; \) @8 b% B- i; ?$STATIC_END_NAME = array('css','xml','rss','gif','jpg','jpeg','js','axd','atom',% A% X7 X" M% X
'mml','txt','jad','htc',2 ~- |; ^3 u& M
'png','tif','tiff','wbmp','ico','jng','bmp','svg'," `# c5 b# t2 z3 d0 @; f, g/ i
'jar','war','ear','hqx','doc','pdf','ps','eps','ai',
# R; r" ^7 N) W4 o! g3 \ 'rtf', 'xls', 'ppt', 'wmlc', 'xhtml', 'cco', 'jardiff',% U9 s0 y5 M* g. f' ~6 y0 X+ A
'jnlp', 'run', 'pl', 'pm', 'prc', 'pdb', 'rar', 'rpm',
M& {, j* U7 T& g* _ 'sea', 'swf', 'sit', 'tcl', 'tk', 'der', 'der', 'crt',5 _" B/ E0 O; z; h
'xpi', 'zip', 'bin', 'exe', 'dll' ,'deb', 'dmg', 'eot',
; W S: l5 p* C5 b7 G2 w$ h @ 'iso', 'img', 'msi', 'msp', 'msm' ,'mid', 'midi', 'kar',3 \7 G' _* ^ x2 a; g) g( t
'mp3', 'ra', '3gpp', '3gp', 'mpeg', 'mpg', 'mov', 'flv',
9 L( m/ x* Y3 i% d" J! A 'mng', 'asx', 'asf', 'wmv', 'avi');" E# h; g7 K% h4 p C
% v4 J* u5 Q J+ T3 [0 w3 h* Y7 ]if(in_array($endName ,$STATIC_END_NAME))* b o3 U- ]4 a' w- r
{" P9 G. Y% m7 ?" O2 n
$headerStr = sprintf("Location: %s", $toUrl);
# q* @; y1 ^% N+ l8 E header( $headerStr, true, 302);
: t! w. A. K6 `# U' x7 l exit;
+ h4 u9 Z, |8 R1 F/ o. O# p}
, X) D9 [- n8 G3 V, x0 j: m/ W
- C4 Z* [/ j b, C) h//一个简单的cache
& H# Z5 D! Q" t1 E+ `function GetFromCache( $url)
- F% y: N6 H, X! W2 R$ G( X+ R{
- F/ u, N) O3 f/ a0 ^3 ~ $current_dir = dirname(__FILE__);
) n& Y6 ~+ W, y2 s2 g7 r9 \ $cache_dir = $current_dir . "/cache/"; s5 ]) o/ j: y# R9 z1 J. V
if( !is_dir( $cache_dir))
- M6 m Q! G% W) D0 |* V2 D {
( Y8 t0 c$ ~3 y8 d1 a2 r" O0 z2 F& d0 ]
mkdir($cache_dir);
7 U: x+ S% k# d: e* s% y$ K" U }
8 k$ {& h _" P- d
* x5 o3 [. g3 d) F $cache_file = $cache_dir . md5($url);
7 ~4 R) l$ z; A: I if(file_exists( $cache_file))
3 V7 X% k- L( h! ~" n" S0 v2 E9 F# u {9 {; o5 c0 X4 [9 F9 Y M
$html = file_get_contents( $cache_file);8 W' v1 Z3 r# j8 P. Q
if($html == false)! r2 J' P7 F7 }
{2 J/ o( P; l" h: }( E
$html = "";
1 y2 |8 r7 ^- m6 D6 m8 X% F }
* ^( g2 c! z- o }else
7 }2 A5 F. ]& o* G1 W {: {+ b: m, R- t+ r* A! B
//访问原始网站
, ]( ~* e0 R+ y0 P# V $data = http_get($url ,array('redirect' => 5, 'timeout' => 10), $http_info );
. `) b' a. F: h% J" ^4 F" h $message = http_parse_message($data);4 {. h! a' I# J1 e
. E k T+ s Y* U
$html = trim($message->body);* m* _7 i T! i Y5 }! p
6 j& ~, R' s4 d7 H4 k file_put_contents( $cache_file, $html);
* _% }( v4 r4 `' W }3 l$ d0 s8 K6 _$ W
2 @" F2 Q, R: O# h return $html;% |9 d/ j" F/ v% N8 h
}+ D. H: I/ U( q7 I* \/ A
# O. X1 D8 e) P k
$html = GetFromCache( $toUrl );
9 }: o- b. ^7 K5 t' [) d! J; T4 V, e$ ], k8 w3 N
i/ X) L2 ~) Y; f* a1 l' F$ Q
$html = str_replace("circleid.com", "circleid.us", $html);8 Q4 w. n* v( Q- }3 r$ n( ^
4 U. T+ Z0 U- H6 z. _% u
$html = preg_replace('/<meta name=.*>/', "", $html);
: {5 r4 d% @8 u( H+ V4 I. R# {
: w9 W" _5 ~$ l8 Y9 J7 j
/ l* ~6 Y1 a4 I$ a0 |0 O3 D- r//注释的这两句是用phpquery操作+ l- F# m5 c5 x5 @% L
//$body = htmlqp($body)->find('#header')->remove()->html();
# b7 k) h5 @' Q' D/ B4 G9 ^9 R//$html = htmlqp($html)->find('#header')->remove()->document->saveHTML();
( b4 H( _" H; ~, Q6 h0 ~" U+ D. N! n; }, l% m: {' w1 Y
$script = <<<EOD
/ {6 u; C( v) v; |3 y3 H<script>4 `6 V% O' Y# P' v9 x) R
$(document).ready(function() {* i6 |' ~8 {% L1 A* X( `
$("#footer").remove();. T: R" T! f) J$ X
6 Q& Z3 [: f& g; c6 F5 H
});$ g8 l+ ?8 G. _1 Q0 |
3 b0 l" \. \+ ?4 x! ^2 o$ U4 P* \1 s6 T5 q</script>
8 @; l0 e- H' {5 u+ M. { d
& h# G: x* n# sEOD;; s, q1 E" n ^: D. Y
! P+ K: a; Y1 k Y3 f' P i9 p& zecho($html . $script);
" ~# r7 X, g( @
: O2 p1 p& \6 |2 @
" s- {3 P; I8 ?3 c& r三、最后
4 e2 A! T3 M( _+ S/ Y1 W% e1.总之,这个程序还很简陋,没有处理post和cookie参数,也没有配置管理模块,距离大洲的程序差距有一个大洲那么大,仅适合稍微懂点程序又有点好奇心的新手玩玩4 Q% @, h+ M8 S( C
2.最后当然是希望大家不令赐分啦,您的论坛币是我继续分享的动力,哈哈! _. p& x) e2 y8 o5 h* Z
. S: J/ T# y: d8 Y* Q6 _- c: Z |