• Django下的Race Condition漏洞


    目录

    环境搭建

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

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

    悲观锁进行防御

    乐观锁进行防御


    环境搭建

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

    然后将源码包上传到Ubuntu

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

    解压

    unzip race-condition-playground-main.zip

    备份env文件

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

    修改env文件内容:

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

    安装需要的库:

    pip3 install -r requirements.txt 

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

    生成数据表:migrate:

    python3 manage.py migrate

     

    使用python生成前端代码:

    python3 manage.py collectstatic

    使用python创建用户:

    python3 manage.py createsuperuser

    运行:

    1. gunicorn -w 2 -k gevent -b 0.0.0.0:8080 race_condition_playground.wsgi
    2. [2023-11-13 16:44:25 +0800] [9072] [INFO] Starting gunicorn 21.2.0
    3. [2023-11-13 16:44:25 +0800] [9072] [INFO] Listening at: http://0.0.0.0:8080 (9072)
    4. [2023-11-13 16:44:25 +0800] [9072] [INFO] Using worker: gevent
    5. [2023-11-13 16:44:25 +0800] [9075] [INFO] Booting worker with pid: 9075
    6. [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/race-condition/templates

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

    输入金额

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

    点击提交后

    赋值内容,然后DROP这个包

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

    然后打开Yakit软件

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

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

    1. POST /ucenter/1/ HTTP/1.1
    2. Host: 192.168.159.219:8000
    3. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0
    4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
    5. 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
    6. Accept-Encoding: gzip, deflate
    7. Referer: http://192.168.159.219:8000/ucenter/1/
    8. Content-Type: multipart/form-data; boundary=---------------------------366213157039382255462597162624
    9. Content-Length: 366
    10. Origin: http://192.168.159.219:8000
    11. Connection: close
    12. 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
    13. Upgrade-Insecure-Requests: 1
    14. -----------------------------366213157039382255462597162624
    15. Content-Disposition: form-data; name="amount"
    16. 10
    17. -----------------------------366213157039382255462597162624
    18. Content-Disposition: form-data; name="csrfmiddlewaretoken"
    19. 2s3TnpbX4HE23G8XhBfoAaoyTXKUklEmafOgWcKu4ByWpMEBemOxFtJ2eGWsIb4T
    20. -----------------------------366213157039382255462597162624--
    
    

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

    1. POST /ucenter/1/ HTTP/1.1
    2. Host: 192.168.159.219:8000
    3. User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/119.0
    4. Content-Type: multipart/form-data; boundary=---------------------------366213157039382255462597162624
    5. 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
    6. Upgrade-Insecure-Requests: 1
    7. -----------------------------366213157039382255462597162624
    8. Content-Disposition: form-data; name="amount"
    9. 10
    10. -----------------------------366213157039382255462597162624
    11. Content-Disposition: form-data; name="csrfmiddlewaretoken"
    12. 2s3TnpbX4HE23G8XhBfoAaoyTXKUklEmafOgWcKu4ByWpMEBemOxFtJ2eGWsIb4T
    13. -----------------------------366213157039382255462597162624--

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

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

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

    然后我们可以再次测试:

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

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

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

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

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

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

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

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

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

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

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

    悲观锁进行防御

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

    还是像上面一样来测试

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

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

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

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

    乐观锁进行防御

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

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

    还是像上面一样来测试

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

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

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

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

  • 相关阅读:
    微信小程序隐私授权
    服务器系统和普通系统的区别
    Ubuntu Linux 24.04 安装apache web server操作记录
    抖店token的生成和刷新的实际开发笔记
    Java精进-手写持久层框架
    【数据结构初阶】常见的排序算法
    React Server Component: 混合式渲染
    《安全物联网系统设计》:我强烈建议你给你的物联网系统加一把安全锁
    敏捷.敏捷项目管理第二版.Jim Highsmith
    新年学新语言Go之四
  • 原文地址:https://blog.csdn.net/qq_68163788/article/details/134384147