728x90
반응형
입력한 값의 해시 값과 코드에서 가지고 있는 값이 일치하면 풀리는 문제다.
int __fastcall main(int argc, const char **argv, const char **envp)
{
_BYTE v4[32]; // [rsp+0h] [rbp-60h] BYREF
char s2[16]; // [rsp+20h] [rbp-40h] BYREF
char s[32]; // [rsp+30h] [rbp-30h] BYREF
_QWORD s1[2]; // [rsp+50h] [rbp-10h] BYREF
s1[0] = 0xD2F969F60C4D9270LL;
s1[1] = 0x1F35021256BDCA3CLL;
printf("Enter input: ");
fgets(s, 17, _bss_start);
s[strcspn(s, "\n")] = 0;
md5String(s, s2);
if ( !memcmp(s1, s2, 0x10uLL) )
{
puts("Hash matched!");
reverse_string(s, v4);
decrypt_bytestring(s, v4);
}
else
{
puts("Hash mismatch :(");
}
return 0;
}
아이다의 hex ray로 확인한 값이다. 대충 내가 입력한 값과 s1의 값을 비교하여 일치하면 hash matched가 된다는 식으로 해석이 가능하다. 자세하게 이해하기 위해 어셈블리 코드를 보자.
.text:00000000000012EB mov rax, 0D2F969F60C4D9270h
.text:00000000000012F5 mov rdx, 1F35021256BDCA3Ch
.text:00000000000012FF mov [rbp+s1], rax
.text:0000000000001303 mov [rbp+var_8], rdx
변수를 초기화하고 있따.
.text:0000000000001307 lea rax, format ; "Enter input: "
.text:000000000000130E mov rdi, rax ; format
.text:0000000000001311 mov eax, 0
.text:0000000000001316 call _printf
input을 입력하라는 문자열을 print한다.
.text:000000000000131B mov rdx, cs:__bss_start ; stream
.text:0000000000001322 lea rax, [rbp+s]
.text:0000000000001326 mov esi, 11h ; n
.text:000000000000132B mov rdi, rax ; s
.text:000000000000132E call _fgets
null 문자를 포함한 총 17글자를 입력받는다.
.text:0000000000001333 lea rax, [rbp+s]
.text:0000000000001337 lea rdx, reject ; "\n"
.text:000000000000133E mov rsi, rdx ; reject
.text:0000000000001341 mov rdi, rax ; s
.text:0000000000001344 call _strcspn
.text:0000000000001349 mov [rbp+rax+s], 0
입력 받은 글자에서 `\n`을 찾아 0을 대입한다.
.text:000000000000134E lea rdx, [rbp+s2]
.text:0000000000001352 lea rax, [rbp+s]
.text:0000000000001356 mov rsi, rdx
.text:0000000000001359 mov rdi, rax
.text:000000000000135C call md5String
.text:0000000000001361 lea rcx, [rbp+s2]
.text:0000000000001365 lea rax, [rbp+s1]
.text:0000000000001369 mov edx, 10h ; n
.text:000000000000136E mov rsi, rcx ; s2
.text:0000000000001371 mov rdi, rax ; s1
.text:0000000000001374 call _memcmp
.text:0000000000001379 test eax, eax
.text:000000000000137B jnz short loc_13B4
.text:000000000000137D lea rax, s ; "Hash matched!"
.text:0000000000001384 mov rdi, rax ; s
.text:0000000000001387 call _puts
입력 값을 md5로 해싱하고 그 값을 앞서 변수에 담았던 값을 가져와 비교한다. 일치하면 `hash matched!`가 출력된다.
.text:00000000000012E3 s1 = qword ptr -10h
.text:00000000000012E3 var_8 = qword ptr -8
.text:00000000000012EB mov rax, 0D2F969F60C4D9270h
.text:00000000000012F5 mov rdx, 1F35021256BDCA3Ch
.text:00000000000012FF mov [rbp+s1], rax
.text:0000000000001303 mov [rbp+var_8], rdx
위와 같이 저장됐는데 어떻게 하나의 변수로 값이 나올 수 있었을까? s1은 var_8와 이어져있다. var_8와 s1을 세어보면 각각 8바이트씩인 것을 알 수 있다. 따라서 s1부터 위쪽으로 16바이트를 읽는다면 s1과 var_8을 합친 값이다.
s1[0] = 0xD2F969F60C4D9270
s1[1] = 0x1F35021256BDCA3C
다시 말하면 위와 같은 값을 얻을 수 있다.
70 92 4D 0C F6 69 F9 D2 3C CA BD 56 12 02 35 1F
70924d0cf669f9d23ccabd561202351f
이는 리틀 엔디언으로 저장되어 있으니 이를 연속된 배열로 보면 위와 같다.
`70924d0cf669f9d23ccabd561202351f`을 크랙해보면 원본 데이터 값을 알 수 있다.
crackstation에서 crack한 값이다.
emergencycall911
이걸 입력하면 flag를 구할 수 있다.
DUCTF{In_the_land_of_cubicles_lined_in_gray_Where_the_clock_ticks_loud_by_the_light_of_day}
짜잔
728x90
반응형
'분류 전 > CTF' 카테고리의 다른 글
[ShaktiCTF25] Hooman 풀이 (3) | 2025.07.30 |
---|---|
[ShaktiCTF25] FRIENDS 풀이 (2) | 2025.07.30 |
[DownUnderCTF 2025] mini-me 풀이 (0) | 2025.07.22 |
[L3ak CTF 2025] babyrev 풀이 (1) | 2025.07.16 |
[L3ak CTF 2025] BrainCalc 풀이 (0) | 2025.07.15 |