• [CISCN2019 华北赛区 Day1 Web2]ikun


    之前做题写做题思路过程一般都是做完了再写,不过这道题脑洞比较大而且涉及到的知识点比较多,所以边复现边写wp。

    靶场打开了之后比较有意思

    鸡你太美

    简单地看一下页面,是购物商城的网页

    应该是买B站的会员,页面有个提示,是一定要买到lv6,简单地翻了几页,没有发现lv6,于是写一个脚本根据网页地址的变化来查找

    import requests
    url="http://c8ffb0c4-125a-4140-ae54-0e34b707fb3f.node3.buuoj.cn/shop?page="
    for i in range(0,2000):
        r=requests.get(url+str(i))
        print url+str(i)
        if 'lv6.png' in r.text:
            print i
            break
    

    跑了一会就找到了

    181页,在url将page改成181之后刷新

    这么贵,我们的钱是远远不够的,使用商城薅羊毛的思路,抓包修改价格,发现这样会报错,所以我们修改折扣

    将折扣改的非常低,返回包403了,暴露了后台地址,访问之

    告诉我们只允许admin访问,抓包刷新该页面,查看身份认证信息

    发现包内有JWT,贴一个介绍的文章

    https://www.anquanke.com/post/id/145540

    我们将包里面的JWT解密一下

    https://jwt.io/

    可以看到显示了我们的username是test

    这个正是我之前注册的时候的用户名,很容易我们可以想到将username修改成admin,不过我们还需要找到JWT签名的密钥

    网上已经有大牛写好了破解工具了

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

    这里涉及了一个小的知识点,在Ubuntu上面下载github代码

    我们可以先下载git,方便从gituhb上面抓取项目

    apt-get install git

    因为我这里是kali,直接就是root权限,所以就没有sudo了

    比如我们现在需要下载c-jwt-cracker 项目代码,使用如下命令

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

    以后在github上下载项目都是 git clone url

    下载到本地之后到c-jwt-cracker使用make命令

    文件夹下就生成了jwtcrack程序

    对于加密后的jwt, HS256加密我们可以尝试一下爆破

    ./jwtcrack 加密后的结果

    这里运行之后可以看到

    密钥是1Kun

    有了密钥之后将username修改成admin,重新加密

    将修改后的jwt重新发包修改

    OK,可以看到已经使用admin的身份登陆成功了

    点击一键成为大会员好像没有什么用

    那我们查看源代码,发现有源代码泄露

    下载之后来审代码

    源代码里面有一个hint,一看就知道是unicode编码,在线解码一下

    提示我们有后门,于是继续审计代码,查找后门在哪里

    Admin.py里面有反序列化操作

    python反序列化以前没有遇到过

    pickle提供了一个简单的持久化功能。可以将对象以文件的形式存放在磁盘上。
     
    pickle模块只能在python中使用,python中几乎所有的数据类型(列表,字典,集合,类等)都可以用pickle来序列化,
    pickle序列化后的数据,可读性差,人一般无法识别。
    
    p = pickle.loads(urllib.unquote(become))
    
    urllib.unquote:将存入的字典参数编码为URL查询字符串,即转换成以key1 = value1 & key2 = value2的形式
    pickle.loads(bytes_object): 从字节对象中读取被封装的对象,并返回

    我看了师傅们的博客之后的理解就是,我们构建一个类,类里面的__reduce__python魔术方法会在该类被反序列化的时候会被调用

    Pickle模块中最常用的函数为:
    
    (1)pickle.dump(obj, file, [,protocol])
    
            函数的功能:将obj对象序列化存入已经打开的file中。
    
           参数讲解:
    
        obj:想要序列化的obj对象。
        file:文件名称。
        protocol:序列化使用的协议。如果该项省略,则默认为0。如果为负值或HIGHEST_PROTOCOL,则使用最高的协议版本。
    
    (2)pickle.load(file)
    
            函数的功能:将file中的对象序列化读出。
    
            参数讲解:
    
        file:文件名称。
    
    (3)pickle.dumps(obj[, protocol])
    
           函数的功能:将obj对象序列化为string形式,而不是存入文件中。
    
           参数讲解:
    
        obj:想要序列化的obj对象。
        protocal:如果该项省略,则默认为0。如果为负值或HIGHEST_PROTOCOL,则使用最高的协议版本。
    
    (4)pickle.loads(string)
    
           函数的功能:从string中读出序列化前的obj对象。
    
           参数讲解:
    
        string:文件名称。
    
         【注】 dump() 与 load() 相比 dumps() 和 loads() 还有另一种能力:dump()函数能一个接着一个地将几个对象序列化存储到同一个文件中,随后调用load()来以同样的顺序反序列化读出这些对象。

    而在__reduce__方法里面我们就进行读取flag.txt文件,并将该类序列化之后进行URL编码

    EXP如下

    当__reduce__被定义之后,该对象被Pickle时就会被调用

    我们这里的eval用于重建对象的时候调用,即告诉python如何pickle他们

    供eval使用的即打开的文件flag.txt

    其他的参数我们可以不填

    payload有很多种写法,这算是一种通用型写法

    我们在本地python2的环境下运行

    得到了序列化之后并且url编码之后的结果

    点击页面一键成为大会员,抓包

    接着将python2得到的结果替换掉become的内容

    返回包里面就有flag了

    贴上参考的博客

    https://xz.aliyun.com/t/2289#toc-4
    https://blog.csdn.net/bluehawksky/article/details/79027055
    https://blog.csdn.net/weixin_43345082/article/details/97817909
    http://www.zjun.info/2019/10/17/ikun/
    https://www.cnblogs.com/chrysanthemum/p/11786132.html
    http://www.polaris-lab.com/index.php/archives/178/
    http://www.cl4y.top/buuctf_wp/#toc-head-24
  • 相关阅读:
    初认识AngularJS
    (imcomplete) UVa 10127 Ones
    UVa 10061 How many zero's and how many digits?
    UVa 11728 Alternate Task
    UVa 11490 Just Another Problem
    UVa 10673 Play with Floor and Ceil
    JSON对象和字符串的收发(JS客户端用typeof()进行判断非常重要)
    HTML.ActionLink 和 Url.Action 的区别
    EASYUI TREE得到当前节点数据的GETDATA方法
    jqueery easyui tree把已选中的节点数据拼成json或者数组(非常重要)
  • 原文地址:https://www.cnblogs.com/Cl0ud/p/12177062.html
Copyright © 2020-2023  润新知