[insomnihack 2024] writeups
NOTE: This is imported from my old blog. The original post was written on Jan 26, 2024.
2024년 들어 처음 뛴 CTF이다. 혼자서 응애맛 리버싱 1개를 슥삭했고, 다른 2개의 문제를 같이 고민하여 총 3문제 풀이에 기여를 했다. 대회 끝나고 1주일동안 아무것도 안하다가 주말에 서울갈 일정이랑 Real World CTF 뛸 생각에 미리 슥 백업해놓는다.
unstringify
최신의 opcode와 ymm 레지스터를 사용한다. SIMD의 기술력은 세계제일
SIMD 특: 이름이 너무 길다
밖에 있어서 집컴에 ssh걸고 r2로 그래프를 봤을 때, 뭐가 없어서 바로 풀 수 있었다.
외부에 급하게 볼 일이 있을땐 radare2도 나쁘지 않은듯. 심지어 Apple silicon에서도 amd64 바이너리를 볼수 있음.
Analysis & AES
분석해보면 0x20byte 입력 이후 generate_key
의 결과로 setting된 ymm0
register의 값을 key로, 입력한 0x20byte의 input이 Permutate된(vpermq
) AES 한 단계를 수행하며, 그 결과가 vpcmpeqq
에서 참조하는 0x22c0
으로부터 0x20byte의 값과 동일해야 한다.
Key
vmovdqa
(main+132
)에 Breakpoint 걸고 ymm0
을 확인해 Key를 긁어올 수 있다.
v32_int8
을 확인해서 (Endian을 잘 지켜서) key 0003195a5b005902000315015c09015e42530d164d06420d2752423a630b540f
를 얻어냈다.
Encrypted
vpcmpeqq
에서 참조하는 encrypted flag는 51cc0fbea0262a146d758930ecfd461c0fa3b4798b62C90668ea03be2ac7f2c4
이다.
Restore
vaesenc
의 동작은 AES의 SubBytes, ShiftRow, MixColumn 을 순서대로 실행한 뒤 기존의 Key와 Blockwise하게 XOR한다. 역산하여 알아낸 키와 XOR, InvMixColumn, InvShiftRow, InvSubBytes 를 하면 (vpermq
를 거친 이후의) Flag가 나온다.
사실 해당 vpermq
는 ymm 레지스터를 permutate할 때 8byte 단위로 permutate하기에, 덩어리 4개를 잘 조합하면 Flag를 볼 수 있다. (눈썰미로 가능)
from aes import AES_implemented
enc = bytes.fromhex("51CC0FBEA0262A146D758930ECFD461C0FA3B4798B62C90668EA03BE2AC7F2C4")
# ymm0 = bytes.fromhex("3030303030303030303030303030303030303030303030303030303030303030") # Temp input
ymm1 = bytes.fromhex("0003195a5b005902000315015c09015e42530d164d06420d2752423a630b540f")
enc = bytes([en ^ y1 for en, y1 in zip(enc, ymm1)])
dec = AES_implemented(ymm1[:16]).decrypt_step(enc)
flg = dec[24:32] + dec[16:24] + dec[8:16] + dec[0:8]
print(flg)
# INS{T45k_Sp0n$0r3d_By_G4l4h4d<3}
FLAG: INS{T45k_Sp0n$0r3d_By_G4l4h4d<3}
풀면서 큰 어려움은 없었지만 솔직히 xmm ymm도 예쁘게 gdb에서 뽑아주는 플러그인이 있었으면 좋겠다.
만들어볼까
frown
작성중.
frown-revenge
작성중.