[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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM