문제를 풀어보자
문제를 다운받아 보면 바이너리 파일이 존재한다.
이걸 디컴파일 할려면 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를 입력한것