flare-on2023
# PREFACE: 很有含金量的题,有点小难,而且和平时做的差别很大,稍稍有点不对感觉,但是做起来能学到很多东西.
# ps. 边记边写吧… 挺大强度的后面怕忘了… 另外这国庆怎么快没了…
# X
dotpeek 打开直接秒: glorified_captcha@flare-on.com
(这 flag 格式和平时都不一样…)
# ItsOnFire
最好是新版 jeb 打开,会自动解析 res 资源,这里的字符串基本上都是从 res 里面提的,自己翻会很痛苦
和一般的题确实差别不小,这里的 flag 逻辑和游戏本身关系并不大,翻翻可以找到这个 MessageWorker
有可疑的地方
一步步翻:
这里的类名混淆其实很有效,不仔细就容易看漏 555
往下翻
找到 AES 逻辑,对图片进行解密
秘钥生成的逻辑:
iv 上面有了
import binascii | |
from Crypto.Cipher import AES | |
from Crypto.Util.Padding import unpad | |
def compute_key(base_string): | |
crc_val = binascii.crc32(base_string.encode()) | |
key = (str(crc_val) * 2)[:16] | |
return key | |
a = 'https://flare-on.com/evilc2server/report_token/report_token.php?token=' | |
b = 'wednesday' | |
key_ori = a[4:10] + b[2:5] | |
def decrypt_aes_cbc(input_filename, output_filename): | |
key = compute_key("s://fldne") | |
iv = "abcdefghijklmnop".encode() | |
with open(input_filename, 'rb') as file: | |
encrypted_hex_data = file.read().hex() | |
encrypted_data = bytes.fromhex(encrypted_hex_data) | |
cipher = AES.new(key.encode(), AES.MODE_CBC, iv) | |
decrypted_data = unpad(cipher.decrypt(encrypted_data), AES.block_size) | |
with open(output_filename, 'wb') as file: | |
file.write(decrypted_data) | |
if __name__ == "__main__": | |
input_filename = "iv.png" | |
output_filename = "outputiv.png" | |
decrypt_aes_cbc(input_filename, output_filename) | |
# YOUr3_ON_F1r3_K33P_6O1N6@flare-on.com |
# mypassion
# 上强度了… 10.4: 基本上做了一半… 慢慢看…
相当长的 check 逻辑,前面的并不是 flag,也就是前面的部分需要保证成功运行过了即可(虽然听着简单,实际上很不简单)
main函数
框定了大体的框架,可以看出来输入方式以及部分输入位(这里的 check 就不是很严格,某种意义上在按暗示你前面不是 flag 了,不过确实没啥经验,前面还做了挺久)
这里有一位 shellcode 汇编的爆破,可以用 capstone 枚举猜一下,还算比较容易
然后注册了一张表,后续都会从这张表里面调用函数
下来这一层,给出了 input 的整体框架: ***/***/***/***/***/
类似这样,每层会用 /
切割检查其中的内容
然后很多 trick,直接放我目前的结论(估计不完全准确,但是能过就行)
里面有个 tick 的函数会计时,如果运行程序太快也会触发退出…(它的 check 不仅有 exitProcess, 还有前面的重启电脑、sleep、tick 等等,也是需要注意看)
继续往下,到第二个斜杠了,目前就到这样: 0;;**R@brUc3E/1337aaa/0/*pizza
中间那个数会复制,放到后面文件名里的文件去,再往后是四进制 = 长度,0 或 1a 均可,然后 pizza 是固定的,第 0 位随机即可
然后来了个难点,这里需要往里面填 shellcode,这里是不能硬过的,会影响下文,必须把所有 shellcode 缺失位全部填上…
可以观察我们需要填出来的函数:(高手学长师傅看出来这里是 InMemoryOrderModuleList
,v4 大概是个这个函数 GetExportedFunctionAddress64
)
进到 v4,第一个汇编就是 0x65,即组成: mov rax, gs:60h
# 这一段晚点补,有点复杂的
下一段
目前的 input:
0;;**R@brUc3E/1337pr.ost/0/*pizza/AMu$E`0R.?AZe/YPXEKCZXYIGMNOXNMXPYCXGXN/ob5cUr3/111
后面小 nop 一下,就有了(虽然不知道为什么最后没 com)
b0rn_t0_5truc7_b4by@flare-on.com