목록Write-up (52)
또 뭐하지
풀이#include #include #include #include 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);}void read_flag() { system("cat /flag");}int main(int argc, char *argv[]) { char buf[0x80]; initialize(); gets(buf); return 0;}소스코드를 살펴보면 buf 크..
풀이주어진 바이너리를 실행시켜 보면 어떤 값이 나오고 입력을 받는다. 소스코드를 확인해보자. #include #include #include #include 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[]) { char buf[0x80]; initialize(); printf("buf = (%p)\n", buf); s..
풀이// Name: rao.c// Compile: gcc -o rao rao.c -fno-stack-protector -no-pie#include #include void init() { setvbuf(stdin, 0, 2, 0); setvbuf(stdout, 0, 2, 0);}void get_shell() { char *cmd = "/bin/sh"; char *args[] = {cmd, NULL}; execve(cmd, args, NULL);}int main() { char buf[0x28]; init(); printf("Input: "); scanf("%s", buf); return 0;}제공된 코드를 살펴보자.buf 크기는 0x28인데 scanf를 통해 입력받는 buf 크기에 제한..
풀이제공된 html 파일에 들어가서 내 생일을 입력해보았다. 아쉽게도 정답이 아니다.6자리 정도면 brute force도 나쁘지 않을 것 같지만 일단 소스코드를 살펴보자. confrim 버튼을 누르면 어떤 일이 발생하는지 요소 버튼을 통해 확인해보니, 입력한 값이 _0x9a220 함수로 넘어가는 것을 확인할 수 있었다.sources 탭을 통해 _0x9a220 함수를 찾아봤는데 하나도 알아볼 수 없었다.그냥 brute force를 하기로 하자.일단 방해가 되는 return alert('Wrong') 부분을 return 0가 되도록 원본 파일을 수정해주었다.for (var y = 0; y 그리고 코드를 작성하여 console 창에 입력했다. 한참 기다린 뒤에야 값이 나왔다. 그리고 화면에 떠있는 flag를 ..
풀이main 함수이다. sub_140001000 함수를 살펴봐야할 것 같다.함수를 살펴보면 일단 문자열 a1의 길이는 8의 배수여야 한다. 그리고 이 문자열을 8바이트 단위로 sub_1400010A0 함수에 넘겨준다. 이제 sub_1400010A0 함수를 확인해보자.byte_140004020[(unsigned __int8)v5[j] ^ v2]는 v5[j]와 v2를 XOR 연산하고, 그 결과를 인덱스로 사용하여 byte_140004020에서 값을 가져온다. 그 가져온 값을 b라고 할 때 a1[(j+1)%8]과 더한 다음 그 값을 5만큼 right rotate 해준다. 그 값을 다시 a1[(j+1)%8]에 넣어준다ubk_140004000와 byte_140004020 값을 얻어오자. #ubk_140004000..
풀이main 함수이다. sub_140001000 함수를 살펴봐야할 것 같다.a1에 -5를 곱한 값이 byte_140003000의 값과 일치하면 된다. 그런데 여기서 unsigned 값을 사용하기 때문에 쉽게 구할 수 는 없을 것 같다. byte_140003000 값을 얻어오자.a = "AC F3 0C 25 A3 10 B7 25 16 C6 B7 BC 07 25 02 D5 C6 11 07 C5 00 00 00 00 00 00 00 00 00 00 00 00"a = a.split()[:21]a = [int(x, 16) for x in a]tmp = []for t in a: for x in range(256): if (x * 251) % 256 == t: tmp..
풀이main 함수이다. sub_140001000 함수를 살펴봐야할 것 같다.__ROL1__(*(_BYTE *)(a1 + i), i & 7)는 읽은 바이트를 왼쪽으로 (i & 7) 비트만큼 회전하는 코드이다. 여기서 & 7 연산은 i 값을 8로 나눈 나머지를 구하는 것과 같으므로, 회전 수는 항상 0에서 7 사이가 된다. __ROL1__은 "Rotate Left" 연산을 의미한다. 해당 연산을 한 후 i와 xor한 값이 byte_140003000 값과 일치하면 조건에 맞는 값이다. byte_140003000을 얻어오자. a = "52 DF B3 60 F1 8B 1C B5 57 D1 9F 38 4B 29 D9 26 7F C9 A3 E9 53 18 4F B8 6A CB 87 58 5B 39 1E"a = a.s..
풀이main 함수이다. 필요한 sub_140001000 함수를 살펴보자.sub_140001000를 살펴보면 byte_140003020 배열의 a1[i]번째의 값이 byte_140003000[i] 값과 동일하면 correct가 출력된다는 것을 알 수 있다. byte_140003020 값과 byte_140003000 값을 가져온다a = "63 7C 77 7B F2 6B 6F C5 30 01 67 2B FE D7 AB 76 CA 82 C9 7D FA 59 47 F0 AD D4 A2 AF 9C A4 72 C0 B7 FD 93 26 36 3F F7 CC 34 A5 E5 F1 71 D8 31 15 04 C7 23 C3 18 96 05 9A 07 12 80 E2 EB 27 B2 75 09 83 2C 1A 1B 6..