0x00背景介绍
PT是PrivateTracker(私用种子服务器)的简称,可以统计用户的上传和下载量,计算用
户的分享率。你可以简单将它理解为BT的升级版,在拥有BT所有功能的同时,需要达到一
定的分享率才能不被删除帐号。PT其实也是Bt下载的一种,但有两个明显的改进:一是私
密的小范围下载,二是进行流量统计,根据上载量决定你的权限。其通过禁用DHT有要求地
选择并控制用户数量,这样,在有限的范围内,下载的用户基本上都可以达到自己的宽带上
限,PT下载还通过论坛等方式的约束机制将BT下载的理念现实化,真正让用户做到下载的
过程中努力上传。(摘自百度百科)
以笔者所注册的PT站点为例。由于PT协议会统计下载量和上传量,因此会有一个叫做分享
率(上传量比下载量)的数值。账号的级别与分享率、下载量、上传量三者都有关。分享率
过低会导致封号等后果。可是PT协议真的可靠吗?请看笔者一一分析而来。如果对原理不
感兴趣,请直接跳到0x03。
0x01服务端源码分析
目前大部分的PT站都是用的nexusphp,笔者以nexusphp.v1.5.beta5.20120707版本
为例进行分析。
服务端接收的比较重要的数据有:passkey,info_hash,port,uploaded,downloaded,
left,event。接下来一项一项进行说明:
Passkey:用来标识用户的唯一值
info_hash:用来标识当前资源的唯一值
port:客户端连接服务端的端口
uploaded:已经上传的数量(单位byte)
downloaded:已经下载的数量(单位byte)
left:下载未完成的数量(单位byte)
event:当前状态(重要状态有stopped、completed、started)
服务端继承了数据更新、作弊检测等信息,对应文件为./announce.php。
我们首先看数据更新这部分。对应文件231行到316行。在通过一系列验证之后,会有类似
的两行代码:
$USERUPDATESET[]="uploaded=uploaded+$upthis";
$USERUPDATESET[]="downloaded=downloaded+$truedownthis";
在文件389行有:
sql_query("UPDATEusersSET".join(",",$USERUPDATESET)."WHEREid=".$u serid);
即更新users表后,上传量变为了原上传量与本次上传量之和,下载量变为了原下载量与本
次下载量之和。
接下来我们看作弊检测部分的代码。
第一个验证的地方是USER_AGENT。见announce.php第6行:
$agent=$_SERVER["HTTP_USER_AGENT"];
block_browser();
block_browser函数见./include/functions_announce.php。
functionblock_browser()
{
$agent=$_SERVER["HTTP_USER_AGENT"];
if(preg_match("/^Mozilla/",$agent)||preg_match("/^Opera/",$agent) ||
preg_match("/^Links/",$agent)||preg_match("/^Lynx/",$agent))
err("Browseraccessblocked!");
/
/checkheaders
if(function_exists('getallheaders')){//getallheaders()isonlysuppo rted
正则匹配一个或连续多个whenPHPisinstalledasanApachemodule
$headers=getallheaders();
//else
//$headers=emu_getallheaders();
if($_SERVER["HTTPS"]!="on")
{
if(isset($headers["Cookie"])||isset($headers["Accept-Language"])| |
isset($headers["Accept-Charset"]))
err("Anti-Cheater:Youcannotusethisagent");
}
}
}
其中禁止了几种常见浏览器的USER_AGENT,并对HTTP请求头中的Cookie、Accept-Language、
Accept-Charset这几项进行检查。如果HTTP请求头有Cookie、Accept-Language、
Accept-Charset这几项,则会出错。
第二个验证的地方是端口port。见announce.php第35行:
//checkportandconnectable
if(portblacklisted($port))
err("Port$portisblacklisted.");
跟踪函数portblacklisted,在./include/functions_announce.php中,即限制了端口的
范围。但是,$port变量是通过GET方式得到的,我们可以进行伪造。
然后是各种身份信息、种子信息的获取及验证,略过。在服务端会动态维护一个peer的数
据表,来记录当前的连接信息(session)。
接下来是第三个验证的地方,对announce时间间隔的验证。见announce.php 第163行:
//minannouncetime
if(isset($self)&&$self['prevts']>(TIMENOW-$announce_wait))
err('Thereisaminimumannouncetimeof'.$announce_wait.'seconds');
其中$announce_wait在第100行有定义,$announce_wait
能小于30秒。$self为peer表中的内容。
第四个验证的地方在announce.php第219、220行:
=30。即两次announce间隔不
$upthis=$trueupthis=max(0,$uploaded-$self["uploaded"]);
$downthis=$truedownthis=max(0,$downloaded-$self["downloaded"]);
其中$self["uploaded"]和$self["downloaded"]是peer表中的内容,$uploaded
$downloaded是服务端GET方式得到的数据。这两行大致意思为在当前活动的session中,
$uploaded和$downloaded这两个变量的值必须是不断增加的。
接下来是比较重要的一个验证步骤,check_cheater函数。此函数在./
include/functions_announce.php中定义。
check_cheater函数中注释写的比较清楚,本质为不同情况下对上传速度的判断。在默认的
安全级别下,首先,如果上传速度大于100MByte/S,很明显这一定是在作弊,系统会自动
disable你的账号的;然后,如果你以MByte/S的速度上传了1GB,那你可能在作弊。如果
管理员设置了更高的安全级别,则会进行当前下载peer数的检查,若正在下载的peer数较
小但是你却以一个较高的速度在上传的话,那你就有可能在作弊。对于可能作弊的情况,如
果在24小时之内cheater表没有你的记录的话会新增一条记录,若已经有记录的话记录中
的hit数会增加1。
该函数只检查了上传有关的参数,并没有检查下载时的情况。因此我们可以伪造下载量或者
不产生下载量。
作弊检测部分的代码到此基本结束了。最后来看与当前状态(event)有关的值。
Stopped相当于你退出客户端时的状态,停止下载,停止做种,系统将你的信息从peer表
中删除。
Completed表示当前种子已经下载完成,在种子状态中可以看到。若未发送Completed
则表示还在下载或者中途删掉,表示为“未完成”状态。
0x02客户端抓包验证
笔者用uTorrent3.1.3进行测试。
首先在uTorrent中设置代理,使其通过brup,方便我们进行抓包。其中我们只需要对
主机名查询使用代理,抓取连接服务器时的数据包。
下载种子,载入,在高级选项中会看到tracker列表。其中tracker所对应的文件即为
0x01中服务端的脚本。
点击确定开始下载,用brup抓包。
第一个包是以GET方式发往scrape.php,该文件作用为判断种子是否存在。
GET

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。