Django下的Race Condition漏洞

目录

环境搭建

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

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

悲观锁进行防御

乐观锁进行防御


环境搭建

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

然后将源码包上传到Ubuntu

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

解压

bash 复制代码
unzip race-condition-playground-main.zip

备份env文件

bash 复制代码
root@utuntu000:~/race-condition# cp .env.default .env.default.bak
root@utuntu000:~/race-condition# mv .env.default .env

修改env文件内容:

bash 复制代码
原:DEBUG=true //因为这里不对
修改后:DEBUG=True

安装需要的库:

bash 复制代码
pip3 install -r requirements.txt 

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

生成数据表:migrate:

bash 复制代码
python3 manage.py migrate

使用python生成前端代码:

bash 复制代码
python3 manage.py collectstatic

使用python创建用户:

bash 复制代码
python3 manage.py createsuperuser

运行:

bash 复制代码
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中访问

bash 复制代码
http://192.168.159.219:8080/ucenter/1/

我们尝试在amount中输入100

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

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

我们首先进入到:/root/race-condition/templates

将form表单的提交方式修改为form-data流的形式

输入金额

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

点击提交后****

赋值内容,然后DROP这个包

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

然后打开Yakit软件

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

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

bash 复制代码
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--
复制代码

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

bash 复制代码
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块钱的东西,这里成功的利用竞争漏洞实现了攻击!

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

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

bash 复制代码
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漏洞的防御方案了!

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

相关推荐
qq_251836457几秒前
基于springboot vue3 在线考试系统设计与实现 源码数据库 文档
数据库·spring boot·后端
向上的车轮5 分钟前
Django学习笔记四:urls配置详解
笔记·学习·django
2401_8581205321 分钟前
古典舞在线交流平台:SpringBoot设计与实现详解
java·spring boot·后端
紫队安全研究31 分钟前
《Web3 安全:攻击与防御全景指南》
安全·web3
赐你岁月如歌33 分钟前
如何使用ssm实现基于web的网站的设计与实现+vue
java·后端·ssm
model200540 分钟前
android + tflite 分类APP开发-1
python·tflite·model maker
感谢地心引力2 小时前
【Qt】Qt安装(2024-10,QT6.7.3,Windows,Qt Creator 、Visual Studio、Pycharm 示例)
c++·windows·python·qt·visual studio
或许,这就是梦想吧!2 小时前
## jupyter_server
ide·python·jupyter
Bruce_Liuxiaowei2 小时前
Python小示例——质地不均匀的硬币概率统计
开发语言·python·概率统计
黄焖鸡能干四碗2 小时前
【需求分析】软件系统需求设计报告,需求分析报告,需求总结报告(原件PPT)
大数据·人工智能·安全·测试用例·需求分析