문제 이름에서 힌트를 얻어야 한다. 리틀엔디언 방식이나 빅 엔디언 방식이나 이걸 묻는거다.
주어진 코드를 보면
// Name: chall.c
// Compile Option: gcc chall.c -o chall -fno-stack-protector
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#define FLAG_SIZE 0x45
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
int main(int argc, char *argv[]) {
int fd;
char *flag;
initialize();
// read flag
flag = (char *)malloc(FLAG_SIZE);
fd = open("./flag", O_RDONLY);
read(fd, flag, FLAG_SIZE);
close(fd);
printf("Input: ");
unsigned char arr[9];
scanf("%8s", arr);
printf("arr | 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x |\n", arr[0], arr[1], arr[2], arr[3], arr[4], arr[5], arr[6], arr[7]);
unsigned int * int_arr = (unsigned int *)arr;
printf("arr | 0x%x 0x%x |\n", int_arr[0], int_arr[1]);
if(int_arr[0] == 0x64726d68 && int_arr[1] == 0x636b3a29){
puts("Nice!");
puts(flag);
}
else{
puts("No...");
}
return 0;
}
여기서 중요하게 볼곳은 당연
if(int_arr[0] == 0x64726d68 && int_arr[1] == 0x636b3a29)
이 부분이다.
이걸 0x64, 0x72, 0x6d, 0x68 한글자 아스키코드로 바꿔보면 drmh
0x63, 0x6b, 0x3a, 0x29 ck:) 가 나온다.
그래서 답으로 drmhck:)을 입력하면 오답이라고 나온다.
그래서 빅, 리틀엔디언 방식을 찾아보니까
인텔 x86 아키텍쳐는 리틀엔디언 이라고 한다.
뭔 말이면 0x64726d68 이게 메모리에 저장될 때
0x68, 0x6d, 0x72, 0x64 이렇게 저장되고 그럼 입력이 hmrd 이된다.
그럼 답은 hmrd):kc 이다.