TL; DR本文介绍了在这种类型的攻击中不常用的不受欢迎的竞争条件技巧。 根据研究结果,我们为Racepwn攻击建立了自己的框架。
Vasya想要转移他在Petya帐户中拥有的100美元。 他转到“转账”选项卡,将Petin昵称带入需要转账的资金数量-数量100。然后,单击“转账”按钮。 向谁发送数据以及向谁发送多少数据到Web应用程序。 内部会发生什么? 程序员需要做什么才能使一切正常工作?
有必要获取用户当前余额的值,如果该值小于他要转移的金额,请告诉他。 考虑到我们的网站不提供贷款并且不应减少余额的事实。
有必要记下当前用户的余额并扣除转账金额。 是100,变成100-100 = 0。
相反,Petya为0,则变为0 + 100 = 100。
在编写程序时,一个人采用最简单的算法,将其组合成一个图,它将成为程序的脚本。 在我们的案例中,程序员的任务是在Web应用程序中编写从一个人到另一个人的汇款(点,积分)的逻辑。 在逻辑的指导下,您可以创建由多个检查组成的算法。 想象一下,我们只是删除了所有不必要的内容并编译了一个伪代码。
(. >= _) .=.-_ .=.+_ () ()
但是,如果一切都依次发生,一切都会很好。 但是一个站点可以同时为许多用户提供服务,并且不会在一个线程中发生,因为现代Web应用程序使用多处理和多线程进行并行数据处理。 随着多线程的出现,程序具有一个有趣的体系结构漏洞-竞争条件(或竞争条件)。
现在想象一下,我们的算法可以同时工作3次。
Vasya的平衡点仍然是100分,只是以某种方式他同时在三个线程中使用了Web应用程序(两次请求之间的时间间隔最短)。 这三个流均检查用户是否为Petya,并检查Vasya是否有足够的余额来进行传输。 在算法检查余额的那一刻,它仍然等于100。验证完成后,将3次从当前余额中减去100,然后添加Pete。
我们有什么? Vasya的帐户中有负余额(100-300 = -200点)。 同时,Petya得到300分,尽管实际上应该是100分。这是利用种族条件的典型示例。 这可与多个人一次通过一遍的事实相媲美。 下面是
4lemon这种情况的屏幕截图

竞争条件可以存在于多线程应用程序中,也可以存在于运行它们的数据库中。 例如,不一定在Web应用程序中,这是操作系统中特权升级的通用标准。 尽管Web应用程序具有成功运行的自身特征,但我想谈一谈。
典型的比赛条件操作
一名黑客进入水烟房,一个任务和一个酒吧,对他来说-您有种族问题! 奥马尔·加涅耶夫(Omar Ganiev)
在大多数情况下,多线程软件用作检查/操作竞争条件的客户端。 例如,Burp Suite及其入侵者工具。 他们发出一个HTTP请求进行重复,安装了许多流并打开了洪水。 如
本文中的示例。 或
在此 。 如果服务器允许对其资源使用多个线程,这是一种相当有效的方法,并且如上面文章中所述,如果服务器不起作用,请重试。 但是事实是,在某些情况下,这可能无效。 特别是当您回想起此类应用程序如何访问服务器时。
服务器上有什么
每个线程建立一个TCP连接,发送数据,等待响应,关闭连接,再次打开,发送数据等等。 乍看之下,所有数据都是同时发送的,但是由于传输层的性质,建立安全连接(HTTPS)和解析DNS(不是burp的情况)以及许多层的原因,HTTP请求本身可能不会同步到达并且不一致在将数据发送到网络设备之前传递数据的抽象。 以毫秒为单位,这可以起到关键作用。
HTTP管道
您可以回想起HTTP-Pipelining,您可以在其中使用单个套接字发送数据。 您可以使用netcat实用程序亲自查看它的工作方式(您拥有GNU / Linux,对吗?)。
实际上,由于许多原因,您需要使用linux,因为存在一个更现代的TCP / IP堆栈,操作系统内核支持该堆栈。 服务器很可能也在其上。例如,运行
nc google.com 80并在其中插入行
GET / HTTP/1.1 Host: google.com GET / HTTP/1.1 Host: google.com GET / HTTP/1.1 Host: google.com
因此,在一个连接内,将发送三个HTTP请求,您将收到三个HTTP响应。 此功能可用于最小化两次请求之间的时间。
服务器上有什么
Web服务器将顺序接收请求(关键字),并按优先级顺序处理响应。 此功能可用于分几个步骤进行攻击(需要在最短的时间内顺序执行两个操作),或者例如,在第一个请求中降低服务器速度,以提高攻击的成功率。
窍门-您可以通过加载服务器的DBMS来阻止服务器处理您的请求,尤其是在使用INSERT / UPDATE的情况下。 较重的请求会“减慢”您的负担,因此,您更有可能赢得这场比赛。
将HTTP请求分为两部分
首先,请记住如何生成HTTP请求。 好吧,如您所知,第一行是方法,路径和协议版本:
GET / HTTP/1.1
接下来是换行符之前的标题:
Host: google.com
Cookie: a=1
但是,Web服务器如何知道HTTP请求已结束?
让我们看一个例子,输入
nc google.com 80 ,然后
GET / HTTP/1.1
Host: google.com
GET / HTTP/1.1
Host: google.com
,按ENTER后,将不会发生任何事情。 再次单击-您将看到答案。
也就是说,要使Web服务器接受HTTP请求,必须有两个换行符。 一个有效的查询如下所示:
GET / HTTP/1.1\r\nHost: google.com\r\n\r\n
如果这是POST方法(不要忘记Content-Length),那么正确的HTTP请求将如下所示:
POST / HTTP/1.1
Host: google.com
Content-Length: 3
a=1
或
POST / HTTP/1.1\r\nHost: google.com\r\nContent-Length: 3\r\n\r\na=1
尝试从命令行发送类似的请求:
echo -ne "GET / HTTP/1.1\r\nHost: google.com\r\n\r\n" | nc google.com 80
结果,由于我们的HTTP请求已完成,您将收到响应。 但是,如果您删除最后一个\ n字符,则不会得到答案。
实际上,许多Web服务器只需要使用\ n进行传输,因此不要交换\ r和\ n很重要,否则进一步的技巧可能不起作用。
它有什么作用? 您可以同时打开与资源的许多连接,发送99%的HTTP请求,并保留未发送的最后一个字节。 服务器将等待,直到您到达最后一个换行。 在将清除数据的主要部分之后,发送最后一个字节(或几个字节)。
当涉及到较大的POST请求时(例如,必须上传文件时),这一点尤其重要。 但是,即使在很小的请求中,这也是有道理的,因为传递几个字节比同时发送数千个字节的信息要快得多。
在发送请求的第二部分之前延迟
根据
Vlad Roskov的研究,不仅有必要拆分请求,而且在发送数据的主要部分和最后部分之间延迟几秒钟也很有意义。 所有这些都是因为Web服务器甚至在它们完全接收到请求之前就开始解析请求。

服务器上有什么
例如,当接收到HTTP请求头时,nginx将开始解析它们,缓存有缺陷的请求。 当最后一个字节到达时,Web服务器将接收部分处理的请求并将其直接发送到应用程序,从而减少了请求的处理时间,这增加了攻击的可能性。
怎么处理
首先,这当然是一个体系结构问题,如果正确设计Web应用程序,则可以避免此类竞争。
通常,使用以下攻击控制方法:
该操作将阻止对DBMS中锁定对象的访问,直到取消锁定为止。 其他人则站在一边观望。 有必要正确使用锁,而不要阻塞任何多余的东西。
有序事务(可序列化)-确保严格按顺序执行事务,但是,这可能会影响性能。
拿点东西(例如etcd)。 在调用函数时,将创建带有键的条目,如果无法创建条目,则该条目已经存在,然后请求被中断。 在处理请求的最后,记录被删除。
总的来说,我喜欢
辛勤工作的Ivan制作的有关锁和交易的
视频 ,内容非常丰富。
比赛条件下的比赛特征
届会的特点之一可能是它本身会干扰比赛的利用。 例如,在PHP中,在session_start()之后,会话文件被锁定,并且仅在脚本末尾(如果没有对
session_write_close的调用)进行解锁。 如果此时调用了另一个使用会话的脚本,它将等待。
为了规避此功能,您可以使用一个简单的技巧-进行多次身份验证。 如果Web应用程序允许您为一个用户创建许多会话,则只需收集所有PHPSESSID并使每个请求具有自己的标识符即可。
靠近服务器
如果要在其上运行竞争条件的站点托管在AWS中-请在AWS中开车。 如果在DigitalOcean中-随身携带。
当任务是发送请求并最小化它们之间的发送间隔时,毫无疑问,与Web服务器的直接接近将是一个加号。
毕竟,在ping服务器200和10毫秒时会有区别。 如果幸运的话,甚至可以在同一台物理服务器上运行,那么飞行起来会容易一些:)
总结一下
对于成功的比赛条件,您可以应用各种技巧来增加成功的可能性。 一次发送多个保持活动请求,从而降低了Web服务器的速度。 将请求分为几部分,并在发送之前创建延迟。 减少到服务器的距离和到网络接口的抽象数量。
分析的结果是,我们与Michail Badin一起开发了
RacePWN工具
它由两个部分组成:
- C librace库,该库在最短的时间内使用本文中的大多数功能将大量HTTP请求发送到服务器
- 实用程序racepwn,它接受json配置并通常引导该库
RacePWN可以集成到其他实用程序中(例如,在Burp Suite中),或者您可以创建用于管理航班的网络界面(仍然无法使用)。 好好享受
但实际上,仍有增长的空间,您可以回想起HTTP / 2及其攻击前景。 但是目前,HTTP / 2的大多数资源仅具有对良好的旧HTTP / 1.1的前端代理请求。
也许您知道其他一些细微之处?
原来的