目录

环境搭建

无锁无事务的竞争攻击复现

无锁有事务的竞争攻击复现

悲观锁进行防御

乐观锁进行防御


环境搭建

首先我们安装源码包:GitHub – phith0n/race-condition-playground: Playground for Race Condition attack

然后源码上传到Ubuntu

为了方便使用我们可以对文件进行重命名

解压

unzip race-condition-playground-main.zip

备份env文件

root@utuntu000:~/race-condition# cp .env.default .env.default.bak
root@utuntu000:~/race-condition# mv .env.default .env

修改env文件内容

原:DEBUG=true //因为这里不对
修改后:DEBUG=True

安装需要的库:

pip3 install -r requirements.txt 

注:可以使用豆瓣源来下载速度更快

生成数据表migrate

python3 manage.py migrate

 

使用python生成前端代码

python3 manage.py collectstatic

使用python创建用户

python3 manage.py createsuperuser

运行

gunicorn -w 2 -k gevent -b 0.0.0.0:8080 race_condition_playground.wsgi
[2023-11-13 16:44:25 +0800] [9072] [INFO] Starting gunicorn 21.2.0
[2023-11-13 16:44:25 +0800] [9072] [INFO] Listening at: http://0.0.0.0:8080 (9072)
[2023-11-13 16:44:25 +0800] [9072] [INFO] Using worker: gevent
[2023-11-13 16:44:25 +0800] [9075] [INFO] Booting worker with pid: 9075
[2023-11-13 16:44:25 +0800] [9076] [INFO] Booting worker with pid: 9076

注:如果没有gunicorn工具,可以使用pip3 linstall安装

然后我们就可以尝试访问这个后台

然后我们就可以尝试访问一下admin

我们输入账号密码成功登录到了后台页面

我们现在就可以给用户增加一些钱:

然后我们在URL中访问

http://192.168.159.219:8080/ucenter/1/

 

我们尝试amount中输入100

这里可以看到我们提交金额大于所拥有的金额,会直接报错

无锁事务的竞争攻击复现

我们首先进入到:/root/racecondition/templates

form表单提交方式修改formdata流的形式

输入金额

先使用Burpsuite进行抓包浏览器开启代理

点击提交

赋值内容,然后DROP这个

关闭代理,再去查看一下金额发现金额没有改变

然后打开Yakit软件

点击本地这个项目->打开项目,或看到这样一个页面

然后就来到了这里,然后将前面抓到的数据粘贴这里

POST /ucenter/1/ HTTP/1.1
Host: 192.168.159.219:8000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Referer: http://192.168.159.219:8000/ucenter/1/
Content-Type: multipart/form-data; boundary=---------------------------366213157039382255462597162624
Content-Length: 366
Origin: http://192.168.159.219:8000
Connection: close
Cookie: __tins__21208037=%7B%22sid%22%3A%201699867069692%2C%20%22vd%22%3A%2011%2C%20%22expires%22%3A%201699870531399%7D; __51cke__=; __51laig__=11; csrftoken=PqAPXKFwTwIlbNyqhrelYxqbWgKPtsKjXdlcwxe3TqCfxT44ecNu3QLFhZWnRiaQ; sessionid=3kx07mweulpr4559s5gyfte6d2whwfna
Upgrade-Insecure-Requests: 1
​
-----------------------------366213157039382255462597162624
Content-Disposition: form-data; name="amount"
​
10
-----------------------------366213157039382255462597162624
Content-Disposition: form-data; name="csrfmiddlewaretoken"
​
2s3TnpbX4HE23G8XhBfoAaoyTXKUklEmafOgWcKu4ByWpMEBemOxFtJ2eGWsIb4T
-----------------------------366213157039382255462597162624--

可以将一些没有用的东西删除掉,删除完成后:

POST /ucenter/1/ HTTP/1.1
Host: 192.168.159.219:8000
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0
Content-Type: multipart/form-data; boundary=---------------------------366213157039382255462597162624
Cookie: __tins__21208037=%7B%22sid%22%3A%201699867069692%2C%20%22vd%22%3A%2011%2C%20%22expires%22%3A%201699870531399%7D; __51cke__=; __51laig__=11; csrftoken=PqAPXKFwTwIlbNyqhrelYxqbWgKPtsKjXdlcwxe3TqCfxT44ecNu3QLFhZWnRiaQ; sessionid=3kx07mweulpr4559s5gyfte6d2whwfna
Upgrade-Insecure-Requests: 1
​
-----------------------------366213157039382255462597162624
Content-Disposition: form-data; name="amount"
​
10
-----------------------------366213157039382255462597162624
Content-Disposition: form-data; name="csrfmiddlewaretoken"
​
2s3TnpbX4HE23G8XhBfoAaoyTXKUklEmafOgWcKu4ByWpMEBemOxFtJ2eGWsIb4T
-----------------------------366213157039382255462597162624--

然后进行并发配置,然后发送

但是这里并没有测试成功,我们删除这条日志

然后再为yps用户增加10块钱用于测试

然后我们可以再次测试

我们可以将重复发包数修改为1000再次尝试,但是还是没有成功(重复以上操作,直到成功)

可以看到这里转发两次,我们再看看日志

这里很明显购买了两次,我们只有10块钱,却购买了两次10块钱的东西,这里成功的利用竞争漏洞实现了攻击!

无锁事务的竞争攻击复现

我们可以在源代码中增加事务(注:本代码中已经有了,不需要手动添加):

class WithdrawView2(BaseWithdrawView):
    success_url = reverse_lazy('ucenter:withdraw2')
 
    @transaction.atomic
    def form_valid(self, form):
        amount = form.cleaned_data['amount']
        self.request.user.money -= amount
        self.request.user.save()
        models.WithdrawLog.objects.create(user=self.request.user, amount=amount)
 
        return redirect(self.get_success_url())

然后删除之前的日志,然后为用户增加10元

重新抓包相同方法放到Yakit软件

然后还是一样反复的使用对线程并发发送请求:(多试试几次)

可以看到还是出现多个302跳转说明事务无法阻止竞争型漏洞

从日志中也可以看到,成功了!

悲观锁进行防御

代码中的3页面就是使用了悲观锁进行防御

还是像上面一样来测试

这里就只展示多线程访问结果

可以看到只有一个302跳转,我们尝试多次也是这个结果说明成功的访问到了

查看日志也可以看到是正常的:

但是这里还有一个问题就是悲观锁会把读和写都锁住性能收到影响,那么我们就可以使用乐观锁进行防御

乐观锁进行防御

代码中的4页面就是使用了乐观锁进行防御

代码中的3页面就是使用了悲观锁进行防御

还是像上面一样来测试

这里就只展示多线程访问结果

这里的结果悲观锁的结果是差不多的只有一个302跳转,我们尝试多次也是这个结果

乐观锁就是我们结果这个Race Condition漏洞的防御方案了!

但是我们还是知道的是乐观锁并没有悲观锁安全,但是乐观锁的性能比悲观锁好

原文地址:https://blog.csdn.net/qq_68163788/article/details/134384147

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_45618.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注