LOB zombie_assassin (lv.17/20) Writeup

이번 문제는 함수를 체이닝 하는 간단한 문제입니다. /* The Lord of the BOF : The Fellowship of the BOF - succubus - calling functions continuously */ #include <stdio.h> #include <stdlib.h> #include <dumpcode.h> // the inspector int check = 0; void MO(char * cmd) { if (check != 4) exit(0); printf("welcome to the MO!\n"); // olleh! system(cmd); } void YUT(void) { if (check != 3) exit(0); printf("welcome to the YUT!\n"); check = 4; } void GUL(void) { if (check != 2) exit(0); printf("welcome to the GUL!\n"); check = 3; } void GYE(void) { if (check != 1) exit(0); printf("welcome to the GYE!\n"); check = 2; } void DO(void) { printf("welcome to the DO!\n"); check = 1; } main(int argc, char * argv[]) { char buffer[40]; char * addr; if (argc < 2) { printf("argv error\n"); exit(0); } // you cannot use library if (strchr(argv[1], '\x40')) { printf("You cannot use library\n"); exit(0); } // check address addr = (char * ) & DO; if (memcmp(argv[1] + 44, & addr, 4) != 0) { printf("You must fall in love with DO\n"); exit(0); } // overflow! strcpy(buffer, argv[1]); printf("%s\n", buffer); // stack destroyer // 100 : extra space for copied argv[1] memset(buffer, 0, 44); memset(buffer + 48 + 100, 0, 0xbfffffff - (int)(buffer + 48 + 100)); // LD_* eraser // 40 : extra space for memset function memset(buffer - 3000, 0, 3000 - 40); } 여러 제약 조건들로 인해 출제자의 의도대로 DO(), GYE(), GUL(), YUT(), MO() 함수를 체이닝 할수밖에 없습니다. ...

2019-04-18 · 3 min · 428 words · Byeongmin Bae

Reverse Engineering Windows XP Minesweeper

이번 글에서는 Windows XP 지뢰찾기를 동적 분석하여 타이머를 수정하고 지뢰 배치를 확인할 수 있는 코드를 작성하는 과정을 살펴보겠습니다. 윈도우 GUI 프로그램은 기본적으로 창 단위로 구성되고, 해당 창에서 일어나는 이벤트를 핸들링 하기 위한 프로시저가 존재합니다. 지뢰찾기의 핵심 로직은 결국 이 프로시저에 존재하게 되어있습니다. 그렇다면 프로시저의 주소는 어떻게 찾을까요? 윈도우 API 를 사용해 창을 생성하려면 무조건 RegisterClass() 를 호출하여 해당 창의 정보를 등록해야 합니다. ATOM RegisterClassA( [in] const WNDCLASSA *lpWndClass ); 이때 넘어가는 WNDCLASSA 구조체를 살펴보면 프로시저의 주소값을 담는 lpfnWndProc 필드가 보입니다. ...

2019-04-10 · 3 min · 452 words · Byeongmin Bae

root-me.org ELF-x86-Format-string-bug-basic-2 Writeup

이번 문제는 FSB 를 트리거하여 check 변수의 값을 0xdeadbeef 로 덮는것이 목표입니다. printf() 계열 함수는 포맷 스트링을 인자로 받는데, 여기에 사용자 입력값이 들어가게 되면 입력값에 포함된 포맷스트링이 해석되어 FSB 취약점이 발생합니다. #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <unistd.h> int main(int argc, char **argv) { int var; int check = 0x04030201; char fmt[128]; if (argc < 2) exit(0); memset(fmt, 0, sizeof(fmt)); printf("check at 0x%x\n", & check); printf("argv[1] = [%s]\n", argv[1]); snprintf(fmt, sizeof(fmt), argv[1]); if ((check != 0x04030201) && (check != 0xdeadbeef)) printf("\nYou are on the right way !\n"); printf("fmt=[%s]\n", fmt); printf("check=0x%x\n", check); if (check == 0xdeadbeef) { printf("Yeah dude ! You win !\n"); setreuid(geteuid(), geteuid()); system("/bin/bash"); } } snprintf() 의 함수 원형을 보면 세번째 인자는 포맷 스트링이 들어가야 하는 자리이지만 문제 코드를 보면 세번째 인자에 사용자 입력값이 들어가고 있습니다. ...

2019-03-09 · 2 min · 249 words · Byeongmin Bae