首页 > 安全 > 网络安全 >

PT协议漏洞分析及利用

2013-01-12

0x00背景介绍PT是PrivateTracker(私用种子服务器)的简称,可以统计用户的上传和下载量,计算用户的分享率。你可以简单将它理解为BT的升级版,在拥有BT所有功能的同时,需要达到一定的分享率才能不被删除帐号。...

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=".$userid);

即更新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()isonlysupported

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,方便我们进行抓包。其中我们只需要对

主机名查询使用代理,抓取连接服务器时的数据包。

PT协议漏洞分析及利用

下载种子,载入,在高级选项中会看到tracker列表。其中tracker所对应的文件即为

0x01中服务端的脚本。

PT协议漏洞分析及利用

点击确定开始下载,用brup抓包。

第一个包是以GET方式发往scrape.php,该文件作用为判断种子是否存在。

GET

/scrape.php?passkey=xxx&info_hash=%d5%bb%80%2a%c3v%ac%3d%5e%01%90%7fu%9c%a4%bc%

afK7%81&info_hash=%12%3f%cc1%a5%8c5M%d7%9e%1b%40Q%cb%2a%14%bf%a7%f09HTTP/1.1

Host:xxx

User-Agent:uTorrent/3130(27385)

Accept-Encoding:gzip

Connection:Close

接着在资源存在的情况下发送第二个包,此数据包发往announce.php,即服务端主脚本。

以后的数据包都发往announce.php。在网站上看到该种子状态为未完成。

GET

/announce.php?passkey=xxx&info_hash=%d5%bb%80%2a%c3v%ac%3d%5e%01%90%7fu%9c%a4%b

c%afK7%81&peer_id=-UT3130-%f9j%b7J%24%e6%b9%85%9a%d1zv&port=41677&uploaded=0&do

wnloaded=0&left=137201853

&corrupt=0&key=03731F6C&event=started&numwant=200&compact=1&no_peer_id=1&ipv6=x

xxxHTTP/1.1

Host:xxxx

User-Agent:uTorrent/3130(27385)

Accept-Encoding:gzip

Connection:Close

由此包我们可以看出,状态event=started,uploaded=0,downloaded=0,left=137201853。

我们继续来看:

GET

/announce.php?passkey=xxx&info_hash=%d5%bb%80%2a%c3v%ac%3d%5e%01%90%7fu%9c%a4%b

c%afK7%81&peer_id=-UT3130-%f9j%b7J%24%e6%b9%85%9a%d1zv&port=41677&uploaded=0&do

wnloaded=52953088&left=83036349&corrupt=0&key=03731F6C&numwant=200&compact=1&no

_peer_id=1&ipv6=xxxHTTP/1.1

Host:xxx

User-Agent:uTorrent/3130(27385)

Accept-Encoding:gzip

Connection:Close

这次有了上传和下载的信息。uploaded=0,downloaded=52953088,left=83036349。

等到下载完成后,我看可以看到event=completed。在网站上看到该种子状态为已完成。

GET

/announce.php?passkey=xxx&info_hash=%d5%bb%80%2a%c3v%ac%3d%5e%01%90%7fu%9c%a4%b

c%afK7%81&peer_id=-UT3130-%f9j%b7J%24%e6%b9%85%9a%d1zv&port=41677&uploaded=0&do

wnloaded=137201853&left=0&corrupt=0&key=03731F6C&event=completed&numwant=200&co

mpact=1&no_peer_id=1&ipv6=xxxHTTP/1.1

Host:xxx

User-Agent:uTorrent/3130(27385)

Accept-Encoding:gzip

Connection:Close

当退出uTorrent客户端时,发送数据包如下:

GET

/announce.php?passkey=xxx&info_hash=%d5%bb%80%2a%c3v%ac%3d%5e%01%90%7fu%9c%a4%b

c%afK7%81&peer_id=-UT3130-%f9j%b7J%24%e6%b9%85%9a%d1zv&port=41677&uploaded=7438

336&downloaded=137201853&left=0&corrupt=0&key=03731F6C&event=stopped&numwant=0&

compact=1&no_peer_id=1HTTP/1.1

Host:xxx

User-Agent:uTorrent/3130(27385)

Accept-Encoding:gzip

Connection:Close

我看可以看到此时event=

stopped。

我们重新来看这些数据包,它们的特点是User-Agent为

uTorrent/3130(27385),没有

Cookie、Accept-Language、Accept-Charset等信息。这正通过了服务端第一个验证。Port

数值在服务端允许的范围内,这是第二个验证。经过比较抓包时间,发现下载完成前发包频

率大约为1个/分钟,下载完成之后发包频率为30分钟,即tracker的更新时间。这即保证

了下载时能随时得到足够的peer,又能使完成的peer不占用太多的服务器资源。第三个验证也顺利通过。第四个验证和最后一个验证由于无法直观的看出,在此不予说明。

0x03PT协议漏洞及利用

经过以上的分析,我们可以总结出PT协议的漏洞。

1.上传下载的信息靠客户端发送GET请求包来完成,我们可以进行伪造;

2.PT对用户的识别只有passkey这一个信息,passkey的生成算法为MD5(用户名+时间

+passhash)。Passkey存在于下载后的种子里,虽然不能伪造,但是可以进行提取;

3.作弊检测只有上传的部分,未对下载部分进行检测,有实现可以不计下载量下载的可能;

4.一个种子可以包含多个tracker,而服务器并没有或者说无法对此状态进行检测,客户

端tracker进行更新的时候会向列表中所有的tracker发送同样的上传下载量信息。这样便

能导致刷流量的可能;

5.所有的信息都由tracker进行处理,而处理过程中多次查询数据库,有CC攻击的可能,

一旦成功,整个服务器便无法工作。

对于第一个漏洞的利用方法是人工发送数据包,只要满足之前所说的验证的规则就可以,即

注意发包格式、请求内容、发包间隔、数据速率控制、安全级别高时还要关注当前下载者的

数量等等。当前下载者的数量可由特定页面进行查询,正则匹配信息即可。由于本人才学疏

浅,利用工具并没写出。

对于第二个漏洞,我们可以向一个不知情的用户要一个下载好的种子,用uTorrent载入,

点高级查看tracker信息,记录下其passkey。当以后自己需要下载种子而又不想耗费自己

的下载量的时候,可以将自己种子的tracker替换成受害者的。这样tracker更新时传送的

信息为受害者的信息,计入受害者的下载量。当下载完毕后,重启uTorrent,把之前的下

载信息清除,然后将tracker改为自己的tracker,这样上传量计入自己的账号。

对于第三个漏洞,我们可以在刚开始下载时tracker更新获得peer之后将tracker删除掉,

这样即有peer传送文件给自己,又不会向服务器发送流量信息。等下载完成后,重启

uTorrent,将tracker加入,继续上传,上传量计入自己的账号。(慎用,安全级别高时可

能会导致其他人封号!)

对于第四个漏洞,前提是有好基友多个或者妹子一枚。一个种子自己用各种途径下载完毕后,

重启uTorrent,在tracker列表中加入自己和对方的tracker,一个人做种,多个人获得上

传量。

对于第五个漏洞,不多解释,CC攻击是违法行为。

0x04后记

这个漏洞已经发现蛮长时间了,一直没有详细说明,毕竟整个作弊的思想与分享精神相抵触。

期间笔者也进行过几次尝试,其中一次炫耀过分,导致被封账号禁ip。之后便一直低调求

发展,用代理来突破ip限制默默下载上传资源。如果没有特殊的情况,希望大家还是能够

正常的遵守PT规则,在分享中得到自己的快乐。

以上方法仅为研究所用,如出现问题,后果自负,与笔者无关。

相关文章
最新文章
热点推荐