본문 바로가기

Writeups

[insomnihack 2024] writeups

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

작성중.

'Writeups' 카테고리의 다른 글

[bi0sctf 2024] writeups  (0) 2024.03.04
[dicectf 2024] writeups  (0) 2024.02.06
[securinetsCTF 2023] tomojiksi  (0) 2024.01.16
[dreamhack.io] multipoint2  (0) 2024.01.11