文章目录
- [[LitCTF 2023]世界上最棒的程序员](#[LitCTF 2023]世界上最棒的程序员)
- [[LitCTF 2023]ez_XOR](#[LitCTF 2023]ez_XOR)
- [[LitCTF 2023]enbase64](#[LitCTF 2023]enbase64)
- [[LitCTF 2023]snake](#[LitCTF 2023]snake)
- [[LitCTF 2023]程序和人有一个能跑就行了](#[LitCTF 2023]程序和人有一个能跑就行了)
- [[LitCTF 2023]debase64](#[LitCTF 2023]debase64)
- [[LitCTF 2023]For Aiur](#[LitCTF 2023]For Aiur)
- LitCTF{Pylon_OverCharge!!_We_Must_construc7_addition4l_pylons}
[LitCTF 2023]世界上最棒的程序员
入门题
[LitCTF 2023]ez_XOR
注意Str2 还有个XOR函数,点进去
3 作为参数 传给XOR,乘以3 所以是异或9 而不是异或3
EXP:
python
enc = b'E`}J]OrQF[V8zV:hzpV}fVF[t'
flag = []
for x in enc:
flag.append(chr(x^9))
print("".join(flag))
# LitCTF{XOR_1s_3asy_to_OR}
[LitCTF 2023]enbase64
好像对base64码表做了处理,但是不管,先尝试解码再说
解不了,嗯再回去看。
有个basechange
下个断点,用动态调试,Local Windows debugger
选中后Shift+E 复制下来就好,
python
import base64
str = 'GQTZlSqQXZ/ghxxwhju3hbuZ4wufWjujWrhYe7Rce7ju'
string1 = "gJ1BRjQie/FIWhEslq7GxbnL26M4+HXUtcpmVTKaydOP38of5v90ZSwrkYzCAuND" # 替换的表
string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
print(base64.b64decode(str.translate(str.maketrans(string1, string2))))
# LitCTF{B@5E64_l5_tooo0_E3sy!!!!!}
[LitCTF 2023]snake
pyc文件,反编译一下就好,可以使用在线网站,pyc反编译
也可以使用uncompyle6,安装就是pip install uncompyle6 ,对py版本有要求,自行查询。
命令如上。
反编译后发现出错,unknown magic number,说明pyc的文件头出错了。
用winhex看一看
对比一下正常的magic number
实际上,pyc文件的magic number是根据编译的python版本而变化的,
文末附上 magic number 的对照表。
这一题题目是37,应该是py3.7编译的,所以我们根据3.7的magic number修改
再次反编译,
找到flag部分
EXP:
python
flag = [
30, 196,
52, 252, 49, 220, 7, 243,
3, 241, 24, 224, 40, 230,
25, 251, 28, 233, 40, 237,
4, 225, 4, 215, 40, 231,
22, 237, 14, 251, 10, 169]
for i in range(0, len(flag), 2):
flag[i], flag[i + 1] = flag[i + 1] ^ 136, flag[i] ^ 119
for i in range(len(flag)):
flag[i] = chr(flag[i])
print("".join(flag))
# LitCTF{python_snake_is_so_easy!}
[LitCTF 2023]程序和人有一个能跑就行了
打开来,一个litctf,一串数据,一个memcmp比较。
sub_4015A0估计是个加密函数,点进去看看
是个RC4加密,不了解RC4的去学习。
提取出密文,解密
EXP:
python
def rc4_decrypt(ciphertext, key):
# 初始化 S-box
S = list(range(256))
j = 0
for i in range(256):
j = (j + S[i] + key[i % len(key)]) % 256
S[i], S[j] = S[j], S[i]
# 初始化变量
i = j = 0
plaintext = []
# 解密过程
for byte in ciphertext:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i]
k = S[(S[i] + S[j]) % 256]
plaintext.append(byte ^ k)
return bytes(plaintext)
# 示例用法
encrypted_data = [
0x8D, 0x6C, 0x85, 0x76, 0x32, 0x72, 0xB7, 0x40, 0x88, 0x7E, 0x95, 0xEE, 0xC5, 0xED, 0x2E, 0x71, 0x37, 0xF1, 0x4A,
0x99, 0x35, 0x18, 0xA7, 0xB0, 0, 0x96, 0xB7] # 替换成你的密文
encryption_key = b'litctf' # 替换成你的密钥
decrypted_data = rc4_decrypt(encrypted_data, encryption_key)
print("Decrypted Data:", decrypted_data.decode('utf-8'))
# Decrypted Data: LitCTF{this_is_a_fake_flag}
[LitCTF 2023]debase64
我这里为了方便修改了v5,用快捷键Y。
可以看到sub_401520 对 v7进行了处理,大概是放到v4里面,点进去
一个base64编码。因为base64编码每三个字节为一组,所以这里只取到0x70,共12个字节。
如果是没有改变数组大小的话,
需要先转换成十六进制,又因为数据在内存中是小端序存储,所以需要将十六进制前后颠倒一下,
python
import base64
str_encoded = [0x46, 0xed, 0x18, 0x96, 0x56, 0x9E, 0xd2, 0x72, 0xb2, 0xb3, 0x80, 0x70]
bytes_encoded = bytes(str_encoded)
decoded_bytes = base64.b64encode(bytes_encoded).decode('utf-8')
print(decoded_bytes)
数据取出来解一下base64.得到Ru0Yllae0nKys4Bw
- 这里其实有点卡壳,也给我打开了点思路,一直逆向都卡死了,按照原本的思路将我们输入的明文经过base64编码得到密文,那么逆向就是用密文base64解码得到明文flag。但是这里是用 "密文" 来进行编码。导致我一直卡着。斯
Ru0Yllae0nKys4Bw有点怪,每四个字节逆序一下,
python
enc = b'Ru0Yllae0nKys4Bw'
# 将字节对象按四个字节一组进行切片,然后逆序
enc_reversed = b''.join(enc[i:i+4][::-1] for i in range(0, len(enc), 4))
print(enc_reversed)
得到 Y0uReallyKn0wB4s
再根据题目描述,后面有三个等号,那么 len(flag)+3 = 19。flag长度为20,故根据md5爆破
python
import hashlib
import string
en_flag = 'Y0uReallyKn0wB4s'
for i in string.printable:
end = en_flag + i + '==='
if hashlib.md5(end.encode()).hexdigest() == '5a3ebb487ad0046e52db00570339aace':
print(end)
exit()
# Y0uReallyKn0wB4s3===
- 做完了。其实做的过程中,我有使用 12345678900987654321的输入验证,发现经过base64编码后的数据和自己编码后的截然不同,说明题目的base64编码是经过魔改的,但为何 可以通过 密文 用普通的base64编码得到部分的明文数据?感觉有点费解,还是我钻了牛角尖,不过也算是为我打开了点思路,有时候,不要想太多,不要想太死,思维打开点。呼-->
[LitCTF 2023]For Aiur
pyinstaller编译的,可以使用pyinstxtractor反编译出文件
具体使用自行查阅。
找到主要的pyc文件,先拖入winhex中和struct对比一下,看一看magic number有没有缺失。
这一题中是完好的。
在线网站反编译一下。
下面都是对于游戏操作的一些设定,看from处有个check,可以,接下来去找ch
找到后反编译ch.pyc
解一下就可以了。
EXP:
python
enc = [
98, 77, 94, 91, 92, 107, 125, 66, 87, 70, 113, 92, 83, 70, 85, 81, 19, 21, 109, 99, 87, 107, 127, 65, 65, 64, 109,
87, 93, 90, 65, 64, 64, 65, 81, 3, 109, 85, 86, 80, 91, 64, 91, 91, 92, 0, 94, 107, 66, 77, 94, 91, 92, 71]
lis = []
num = 0
while True:
flag = 'LitCTF{'
if num % 2 == 0 and num % 4 == 0 and num % 6 == 0 and num % 8 == 0 and num % 12 == 0 and num % 13 == 11:
k = str(num)
for i in range(len(enc)):
flag += chr(ord(k[(i % len(k))]) ^ enc[i])
lis.append(ord(k[(i % len(k))]) ^ enc[i])
flag += '}'
print(flag)
break
num += 1
# LitCTF{Pylon_OverCharge!!_We_Must_construc7_addition4l_pylons}
k = str(num)
for i in range(len(enc)):
flag += chr(ord(k[(i % len(k))]) ^ enc[i])
lis.append(ord(k[(i % len(k))]) ^ enc[i])
flag += '}'
print(flag)
break
num += 1
LitCTF{Pylon_OverCharge!!_We_Must_construc7_addition4l_pylons}
``enum PycMagic { MAGIC_1_0 = 0x00999902, MAGIC_1_1 = 0x00999903, /* Also covers 1.2 */ MAGIC_1_3 = 0x0A0D2E89, MAGIC_1_4 = 0x0A0D1704, MAGIC_1_5 = 0x0A0D4E99, MAGIC_1_6 = 0x0A0DC4FC, MAGIC_2_0 = 0x0A0DC687, MAGIC_2_1 = 0x0A0DEB2A, MAGIC_2_2 = 0x0A0DED2D, MAGIC_2_3 = 0x0A0DF23B, MAGIC_2_4 = 0x0A0DF26D, MAGIC_2_5 = 0x0A0DF2B3, MAGIC_2_6 = 0x0A0DF2D1, MAGIC_2_7 = 0x0A0DF303, MAGIC_3_0 = 0x0A0D0C3A, MAGIC_3_1 = 0x0A0D0C4E, MAGIC_3_2 = 0x0A0D0C6C, MAGIC_3_3 = 0x0A0D0C9E, MAGIC_3_4 = 0x0A0D0CEE, MAGIC_3_5 = 0x0A0D0D16, MAGIC_3_5_3 = 0x0A0D0D17, MAGIC_3_6 = 0x0A0D0D33, MAGIC_3_7 = 0x0A0D0D42, MAGIC_3_8 = 0x0A0D0D55, MAGIC_3_9 = 0x0A0D0D61, };``