AIS3 Pre-Exam 2023
tags: CTF
EOF2023
:::spoiler TOC [TOC] :::
Web
E-Portfolio baby
Recon
直接用Burp Suite可以繞過reCAPTCHA,而且About Guest的內容會被完整的render出來達到XSS
Login Panel
Recon
Reverse
Pwn
Simply Pwn
Recon
-
checksec
$ checksec pwn [*] Checking for new versions of pwntools To disable this functionality, set the contents of /home/sbk6401/.cache/.pwntools-cache-3.7/update to 'never' (old way). Or add the following lines to ~/.pwn.conf or ~/.config/pwn.conf (or /etc/pwn.conf system-wide): [update] interval=never [*] You have the latest version of Pwntools (4.9.0) [*] '/home/sbk6401/CTF/AIS3-Pre-Exam/PWN/Simply Pwn/pwn' Arch: amd64-64-little RELRO: Partial RELRO Stack: Canary found NX: NX disabled PIE: No PIE (0x400000) RWX: Has RWX segments
Misc
Welcome
縮小檔案就看的到flag了
Flag: AIS3{WELCOME-TO-2023-PRE-EXAM-&-MY-FIRST-CTF}
Robot
簡單的Script,但是題目敘述太不直覺了吧 :::spoiler Script
from pwn import *
context.arch = 'amd64'
r = remote("chals1.ais3.org", 12348)
r.recvline()
r.recvline()
for i in range(30):
question = r.recvline().decode().strip()
ans = eval(question)
sleep(1)
r.sendline(str(ans).encode())
print(r.recvline())
r.interactive()
:::
Flag: AIS3{don't_eval_unknown_code_or_pipe_curl_to_sh}
Crypto
Fernet
就直接按照decrypt的流程跑一次就好了 :::spoiler Source Code
import os
import base64
from cryptography.fernet import Fernet
from Crypto.Hash import SHA256
from Crypto.Protocol.KDF import PBKDF2
from pwn import *
def decrypt(ciphertext, password, salt):
key = PBKDF2(password.encode(), salt, 32, count=1000, hmac_hash_module=SHA256)
f = Fernet(base64.urlsafe_b64encode(key))
plaintext = f.decrypt(ciphertext)
return plaintext
leak_password = 'mysecretpassword'
ciphertext = 'iAkZMT9sfXIjD3yIpw0ldGdBQUFBQUJrVzAwb0pUTUdFbzJYeU0tTGQ4OUUzQXZhaU9HMmlOaC1PcnFqRUIzX0xtZXg0MTh1TXFNYjBLXzVBOVA3a0FaenZqOU1sNGhBcHR3Z21RTTdmN1dQUkcxZ1JaOGZLQ0E0WmVMSjZQTXN3Z252VWRtdXlaVW1fZ0pzV0xsaUM5VjR1ZHdj'
tmp = base64.b64decode(ciphertext)
salt = tmp[:16]
ciphertext = tmp[16:]
print(decrypt(ciphertext, leak_password, salt))
:::
Flag: FLAG{W3lc0m3_t0_th3_CTF_W0rld_!!_!!!_!}
2DES
-
meet in the middle attack
這一題沒有解出來,兩個exploit source code都有點問題導致無法實踐,但邏輯應該是對的
:::spoiler JS Source Code
const crypto = require('crypto') const assert = require('assert') const hint_pt = Buffer.from('AIS3{??????????}', 'utf8') let hint = '118cd68957ac93b269335416afda70e6d79ad65a09b0c0c6c50917e0cee18c93' const iv = Buffer.concat([Buffer.from('AIS3 三')]) console.log(iv) function encrypt(msg, key, iv) { const cipher = crypto.createCipheriv('des-cbc', key, iv) let encrypted = cipher.update(msg) encrypted = Buffer.concat([encrypted, cipher.final()]) return encrypted } function decrypt(msg, key, iv) { const decipher = crypto.createDecipheriv('des-cbc', key, iv) let decrypted = decipher.update(msg, 'nyan~') decrypted = Buffer.concat([decrypted, decipher.final()]) return decrypted } function intToHexStr(num) { var hexString = ''; for (var i = 0; i < 8; i++) { var byte = num & 0xff; // 获取低8位 var hex = byte.toString(16).padStart(2, '0'); // 转换为两位的十六进制字符串 hexString = hex + hexString; // 将转换后的字符串拼接到结果中 num = num >> 8; // 右移8位,处理下一个字节 } return hexString; } var key1_table = [] var key2_table = [] var key1 = key2 = Buffer.from(intToHexStr(256), 'hex') for (let idx = 0; idx < 2**32; idx++) { tmp = encrypt(hint_pt, key1, iv) key1_table.push(tmp) key2_table.push(decrypt(hint, key2, iv)) var key1 = key2 = Buffer.from(intToHexStr(idx + 1), 'hex') } for (let i = 0; i < 2**32; i++) { for (let j = 0; j < 2**32; j++) { if (key1_table[i] == key2_table[j]) { console.log("key1 = ", i, "\nkey2 = ", j) break } } }
:::
:::spoiler Python Source Code
# from Crypto.Cipher import DES from tqdm import trange from pyDes import des, CBC, PAD_PKCS5 hint_pt = 'AIS3{??????????}' hint = '118cd68957ac93b269335416afda70e6d79ad65a09b0c0c6c50917e0cee18c93' iv = b'4149533320e4b889' key1_table = [] key2_table = [] def encrypt(m, key, iv): # des = DES.new(key, DES.MODE_CBC, iv) k = des("0" * 8, CBC, "0"*8, pad=None, padmode=PAD_PKCS5) k.setKey(key) k.setIV(iv) return k.encrypt(m, padmode=PAD_PKCS5) def decrypt(c, key, iv): # des = DES.new(key, DES.MODE_CBC, iv) k = des("0" * 8, CBC, "0"*8, pad=None, padmode=PAD_PKCS5) k.setKey(key) k.setIV(iv) return k.decrypt(c, padmode=PAD_PKCS5) key1 = key2 = '{0:0>16x}'.format(0).encode() for idx in range(2**32): key1_table.append(encrypt(hint_pt, key1, iv)) key2_table.append(decrypt(hint, key2, iv)) key1 = key2 = '{0:0>16x}'.format(idx + 1).encode() for i in range(len(key1)): for j in range(len(key2_table)): if key1_table[i] == key2_table[j]: print("key1 = {}\nkey2 = {}".format(i, j))
:::