본문 바로가기
분류 전/CTF

[DownUnderCTF 2025] rocky 풀이

by jwcs 2025. 7. 22.
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

crackstation에서 crack한 값이다.

 

emergencycall911

이걸 입력하면 flag를 구할 수 있다.

 

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