[Dreamhack CTF] simple-opertaion

Sungwuk·2024년 12월 5일
0

dreamhack

목록 보기
15/17

문제를 풀어보자

문제를 다운받아 보면 바이너리 파일이 존재한다.

이걸 디컴파일 할려면 IDA란 리버싱 툴이 필요한데 그건 알아서 구하길...

여튼 주어진 바이너리 파일을 IDA에서 열면

; Attributes: bp-based frame

; int __cdecl main(int argc, const char **argv, const char **envp)
public main
main proc near

s1= byte ptr -3Ah
s= byte ptr -31h
var_28= dword ptr -28h
var_24= dword ptr -24h
s2= qword ptr -20h
fd= dword ptr -14h
buf= qword ptr -10h
var_8= dword ptr -8
var_4= dword ptr -4

; __unwind {
endbr64
push    rbp
mov     rbp, rsp
sub     rsp, 40h
mov     [rbp+var_24], 0
mov     [rbp+var_28], 0
mov     [rbp+var_8], 0
mov     eax, 0
call    initialize
mov     edi, 45h ; 'E'  ; size
call    _malloc
mov     [rbp+buf], rax
mov     esi, 0          ; oflag
lea     rax, aFlag      ; "./flag"
mov     rdi, rax        ; file
mov     eax, 0
call    _open
mov     [rbp+fd], eax
mov     rcx, [rbp+buf]
mov     eax, [rbp+fd]
mov     edx, 45h ; 'E'  ; nbytes
mov     rsi, rcx        ; buf
mov     edi, eax        ; fd
call    _read
mov     eax, [rbp+fd]
mov     edi, eax        ; fd
call    _close
lea     rax, [rbp+var_28]
mov     rdi, rax
call    get_rand_num
mov     eax, [rbp+var_28]
mov     esi, eax
lea     rax, format     ; "Random number: %#x\n"
mov     rdi, rax        ; format
mov     eax, 0
call    _printf
lea     rax, aInput     ; "Input? "
mov     rdi, rax        ; format
mov     eax, 0
call    _printf
lea     rax, [rbp+var_24]
mov     rsi, rax
lea     rax, aD         ; "%d"
mov     rdi, rax
mov     eax, 0
call    ___isoc99_scanf
mov     edx, [rbp+var_28]
mov     eax, [rbp+var_24]
xor     eax, edx
mov     [rbp+var_8], eax
mov     edx, [rbp+var_8]
lea     rax, [rbp+s]
mov     ecx, edx
lea     rdx, a08x       ; "%08x"
mov     esi, 9          ; maxlen
mov     rdi, rax        ; s
mov     eax, 0
call    _snprintf
mov     [rbp+var_4], 0
jmp     short loc_145A
.
.
.

이런 어셈블리어가 나아고 이걸 디컴파일 하면

int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s1[9]; // [rsp+6h] [rbp-3Ah] BYREF
  char s[9]; // [rsp+Fh] [rbp-31h] BYREF
  unsigned int v6; // [rsp+18h] [rbp-28h] BYREF
  unsigned int v7; // [rsp+1Ch] [rbp-24h] BYREF
  char *s2; // [rsp+20h] [rbp-20h]
  int fd; // [rsp+2Ch] [rbp-14h]
  void *buf; // [rsp+30h] [rbp-10h]
  unsigned int v11; // [rsp+38h] [rbp-8h]
  int i; // [rsp+3Ch] [rbp-4h]

  v7 = 0;
  v6 = 0;
  v11 = 0;
  initialize(argc, argv, envp);
  buf = malloc(0x45uLL); //buf를 위해 0x45(69) 바이트 크기의 메모리를 동적으로 할당
  fd = open("./flag", 0); //open() 함수로 ./flag 파일을 열고 내용을 읽어 buf에 저장
  read(fd, buf, 0x45uLL);
  close(fd);
  get_rand_num(&v6);
  printf("Random number: %#x\n", v6);
  printf("Input? ");
  __isoc99_scanf("%d", &v7);
  v11 = v6 ^ v7; //사용자 입력 v7과 랜덤 숫자 v6의 XOR 연산 결과를 v11에 저장
  snprintf(s, 9uLL, "%08x", v6 ^ v7); //이 XOR 연산 결과를 문자열 형태로 변환하여 s에 저장한 뒤, 이를 뒤집어서 s1에 저장
  for ( i = 0; i <= 7; ++i ) //문자열 s1과 "a0b4c1d7"을 비교
    s1[i] = s[7 - i];
  printf("Result: %s\n", s1);
  s2 = "a0b4c1d7";
  if ( !strcmp(s1, "a0b4c1d7") )
  {
    puts("Congrats!"); //문자열이 같다면 플래그를 출력하며 "Congrats!"
    puts((const char *)buf);
  }
  else
  {
    puts("Try again");
  }

이런 c 언어가 나온다.

사용자로부터 입력을 받아 특정 조건(s1 == "a0b4c1d7")을 만족할 경우 플래그를 출력. 조건을 만족하기 위해서는 랜덤 숫자(입력값)와 고정된 XOR 결과(0x7d1c4b0a)를 이용해 적절한 입력값을 계산

난 여기서 0x6868015d XOR 0x7d1c4b0a한 결과의 십진수 359942743를 입력한것

정답

profile
보안전문가 꿈나무

0개의 댓글