W4terCTF2024 writeup

W4terCTF2024 writeup

纯小白,做出的题很少

图片很糊但就先这样吧
队友:https://github.com/kuku172
放个友链Lst4r-max.github.io

Spam 2024

先找垃圾邮件,搜了很多东西后找到spammimic - encoded,然后第一步解码:

1
59,6f,75,20,6c,69,6b,65,20,65,6d,6f,6a,69,73,2c,20,64,6f,6e,27,74,20,79,6f,75,3f,0a,0a,01f643,01f4b5,01f33f,01f3a4,01f6aa,01f30f,01f40e,01f94b,01f6ab,01f606,2705,01f606,01f6b0,01f4c2,01f32a,263a,01f6e9,01f30f,01f4c2,01f579,01f993,01f405,01f375,01f388,01f600,01f504,01f6ab,01f3a4,01f993,2705,01f4ee,01f3a4,01f385,01f34e,01f643,01f309,01f383,01f34d,01f374,01f463,01f6b9,01f923,01f418,01f3f9,263a,01f463,01f4a7,01f463,01f993,01f33f,2328,01f32a,01f30f,01f643,01f375,2753,2602,01f309,01f606,01f3f9,01f375,01f4a7,01f385,01f449,01f30a,01f6b9,01f6aa,01f374,01f60e,01f383,01f32a,01f643,01f441,01f94b,01f451,01f4a7,01f418,01f3a4,01f94b,01f418,01f6e9,01f923,01f309,01f6e9,23e9,01f60d,2753,01f418,01f621,2600,01f60d,01f643,01f601,01f600,01f601,01f6ab,01f4c2,2705,2603,01f6ab,01f60e,01f52a,01f451,01f600,01f579,01f6ab,01f60d,01f32a,01f4c2,01f44c,01f34d,01f44c,01f993,01f590,01f923,01f60e,01f3ce,01f34d,01f3f9,01f34c,01f34d,01f3a4,2600,01f3f9,01f388,01f6b0,01f4a7,2600,2709,01f3f9,01f34d,01f993,01f385,01f374,2602,23e9,01f6aa,01f40d,263a,01f418,01f607,01f621,01f375,01f30f,01f993,01f375,01f6e9,01f4c2,01f44c,01f3f9,01f5d2,01f5d2,0a,0a,42,74,77,2c,20,74,68,65,20,6b,65,79,20,69,73,20,22,4b,45,59,22

前后是ACSII,中间是emoji的unicode。

1
2
3
4
5
6
7
8
9
10
11
12
def hex_to_ascii(hex_string):
bytes_object = bytes.fromhex(hex_string)
ascii_string = bytes_object.decode("ASCII")
return ascii_string

hex_string1 = "59,6f,75,20,6c,69,6b,65,20,65,6d,6f,6a,69,73,2c,20,64,6f,6e,27,74,20,79,6f,75,3f,0a,0a"
hex_string1 = hex_string1.replace(',', '')
print(hex_to_ascii(hex_string1))

hex_string2 = "0a,0a,42,74,77,2c,20,74,68,65,20,6b,65,79,20,69,73,20,22,4b,45,59,22"
hex_string2 = hex_string2.replace(',', '')
print(hex_to_ascii(hex_string2))
1
2
3
4
unicode_string ="01f643,01f4b5,01f33f,01f3a4,01f6aa,01f30f,01f40e,01f94b,01f6ab,01f606,2705,01f606,01f6b0,01f4c2,01f32a,263a,01f6e9,01f30f,01f4c2,01f579,01f993,01f405,01f375,01f388,01f600,01f504,01f6ab,01f3a4,01f993,2705,01f4ee,01f3a4,01f385,01f34e,01f643,01f309,01f383,01f34d,01f374,01f463,01f6b9,01f923,01f418,01f3f9,263a,01f463,01f4a7,01f463,01f993,01f33f,2328,01f32a,01f30f,01f643,01f375,2753,2602,01f309,01f606,01f3f9,01f375,01f4a7,01f385,01f449,01f30a,01f6b9,01f6aa,01f374,01f60e,01f383,01f32a,01f643,01f441,01f94b,01f451,01f4a7,01f418,01f3a4,01f94b,01f418,01f6e9,01f923,01f309,01f6e9,23e9,01f60d,2753,01f418,01f621,2600,01f60d,01f643,01f601,01f600,01f601,01f6ab,01f4c2,2705,2603,01f6ab,01f60e,01f52a,01f451,01f600,01f579,01f6ab,01f60d,01f32a,01f4c2,01f44c,01f34d,01f44c,01f993,01f590,01f923,01f60e,01f3ce,01f34d,01f3f9,01f34c,01f34d,01f3a4,2600,01f3f9,01f388,01f6b0,01f4a7,2600,2709,01f3f9,01f34d,01f993,01f385,01f374,2602,23e9,01f6aa,01f40d,263a,01f418,01f607,01f621,01f375,01f30f,01f993,01f375,01f6e9,01f4c2,01f44c,01f3f9,01f5d2,01f5d2"
unicode_list = unicode_string.split(',')
emoji_string = ''.join(chr(int('0x' + uni, 16)) for uni in unicode_list)
print(emoji_string)
1
2
You like emojis, don't you?
Btw, the key is "KEY"
1
🙃💵🌿🎤🚪🌏🐎🥋🚫😆✅😆🚰📂🌪☺🛩🌏📂🕹🦓🐅🍵🎈😀🔄🚫🎤🦓✅📮🎤🎅🍎🙃🌉🎃🍍🍴👣🚹🤣🐘🏹☺👣💧👣🦓🌿⌨🌪🌏🙃🍵❓☂🌉😆🏹🍵💧🎅👉🌊🚹🚪🍴😎🎃🌪🙃👁🥋👑💧🐘🎤🥋🐘🛩🤣🌉🛩⏩😍❓🐘😡☀😍🙃😁😀😁🚫📂✅☃🚫😎🔪👑😀🕹🚫😍🌪📂👌🍍👌🦓🖐🤣😎🏎🍍🏹🍌🍍🎤☀🏹🎈🚰💧☀✉🏹🍍🦓🎅🍴☂⏩🚪🐍☺🐘😇😡🍵🌏🦓🍵🛩📂👌🏹🗒🗒

找到下面的工具:
emoji-aes

alt text
发现密钥的问题,试了KEY的unicode, ascii,等等,🔑的unicode,用KEY生成垃圾邮件,都失败了。
找到正确的密钥🔑。
解密结果是:

1
0x???? ⊕ dxBUQVJndGJbbGByE3tGUW57VxV0bH9db3FSe2YFUndUexVUYWl/QW1FAW1/bW57EhQSEF0=

这个字符串应该是被异或操作过的结果,找到正确的16进制数与其进行异或就能得到原始信息。下面是暴力破解来找出可能的结果。
异或运算的一个特点是自反的,就是用同一个键进行两次异或操作就可以恢复原始信息。

1
2
3
4
5
6
7
import base64

cipher_text = base64.b64decode('dxBUQVJndGJbbGByE3tGUW57VxV0bH9db3FSe2YFUndUexVUYWl/QW1FAW1/bW57EhQSEF0=')

for xor_key in range(0x10000): # 试验所有 0x0000 到 0xffff 的可能key
plain_text = ''.join(chr(b ^ (xor_key & 0xff)) for b in cipher_text)
print(f'0x{xor_key:04x}: {plain_text}')

第一次的代码有点问题,遍历输出只发现了一个很像的数据。
alt text
分析了下奇数位和偶数位异或的值是不一样的,0x????看得出来是个四位十六进制,这个奇数位看起来基本是对的。
改一下代码,然后一样遍历枚举,就找到flag了。

1
2
3
4
5
6
7
8
import base64

cipher_text = base64.b64decode('dxBUQVJndGJbbGByE3tGUW57VxV0bH9db3FSe2YFUndUexVUYWl/QW1FAW1/bW57EhQSEF0=')
xor_key_even = 0xfe20

for xor_key_odd in range(0x10000):
plain_text = "".join(chr(cipher_text[i] ^ ((xor_key_odd if i % 2 else xor_key_even) & 0xff)) for i in range(len(cipher_text)))
print(f'key_odd: 0x{xor_key_odd:04x}, deciphered message: {plain_text}')

alt text

GZ GPT

nc:
alt text
乱码解决方案:乱码恢复
alt text
alt text

手动改乱码比较慢,就使用python的pwn库,并导入codecs模块(基础编解码功能)进行无限交互直至远程服务器终止。

1
2
3
4
5
6
7
8
9
10
11
from pwn import *
import codecs

conn = remote('127.0.0.1', 50338)

while True:
data = conn.recv().decode('utf-8')
gbk_data = data.encode('gbk')
print(f"接收到的数据:{data}")
conn.interactive()
conn.close()

alt text

看提示,应该是每次返回的有隐藏数据(想到去年的shadow,感觉这次输出光标也有奇怪的闪动)。
确定了下每次输出后都有隐藏信息,这题是考隐写的。
把终端输出复制过来看到vscode的提示:
alt text

然后去查一下锁定类型:零宽度字符隐写,并找到工具Unicode Steganography with Zero-Width Characters
用笨蛋方法一句句复制粘贴上去解码的,把每次的Hidden Text粘贴上去就得到完整的flag了。

broken.mp4

解压后一个视频是完好的,打开看看,很明显的提示了,明显是在微信打开的嘛,去微信上搜搜标题,很好找到这篇文章链接
然后去下载公众号上说的那个软件恢复一下就OK了
alt text

Sign In

四道签到题的最后一个(晚上公选课无聊乱翻榜单看到的)
alt text

Remember It 0

第一次做pwn题,随便试试,签到题的话一般跟着做就行(主要是懒得想其他方法了)
看源码,笨蛋方法没问题,就一步步敲的
alt text
然后cat flag
alt text

Shuffle Puts

签到题,嗯,打开IDA直接看strings
alt text

总结

小白第一次玩CTF还是挺开心的,感觉算是入了门。(一周前容器实例还不会开netcat还不会用的)。
如果这周事情不那么多就好了,这周太忙了有效做题时间不多,很多方向都没学,基本上就是在做Misc了。

作者

zyh

发布于

2024-05-03

更新于

2024-09-25

许可协议

评论