본문 바로가기

분류 전체보기

(68)
Exploit Tech: Return to Shellcode 이번 게시글에서는 Canary를 우회하여 Return Address Overwrite를 통해 Shell을 획득하는 실습에 대해 다뤄볼 것이다. 소스코드 //소스코드명: r2s.c //파일명: r2s #include #include int main() { char buf[0x50]; printf("Address of the buf: %p\n", buf); printf("Distance between buf and $rbp: %ld\n", (char*)__builtin_frame_address(0) - buf); printf("[1] Leak the canary\n"); printf("Input: "); fflush(stdout); read(0, buf, 0x100); printf("Your input is..
Mitigation: Stack Canary Stack Canary란 1) 함수 프롤로그에서 스택 버퍼와 SFP 사이에 임의의 값음 삽임함 2) 함수의 에필로그에서 해당 값의 변조를 확인함 변조 확인(O) -> 프로세스 강제 종료 변조 확인(X) -> 프로세스 정상 종료 Canary가 적용돼있는 Canary.asm을 분석해보자 Canary.c #include int main() { char buf[8]; read(0, buf, 32); return 0; } Canary.asm 1 push rbp 2 mov rbp,rsp 3 sub rsp,0x10 4 mov rax,QWORD PTR fs:0x28 5 mov QWORD PTR [rbp-0x8],rax 6 xor eax,eax 7 lea rax,[rbp-0x10] 8 mov edx,0x20 9 mov ..
basic_exploitation_001 *풀이: 함수의 소스코드를 먼저 살표보자, 소스코드: #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; } read_flag라는 flag를..
basic_exploitation_000 전체적인 스케치: scanf 함수를 통해 buf에 쉘코드를 삽입하고, 스택 버퍼 오버플로우를 통해 메인 함수의 return address를 buf의 시작주소로 옮겨, buf에 들어가있는 쉘코드를 실행시킴으로서 쉘을 획득하면 되는 문제이다. 다만 주의해야할 점은, 1) 쉘코드 작성시 scanf 함수는 'x09, x0a, x0b, x0c, x0d, x20'와 이 이후의 값들을 읽어들이지 못 하기 때문에, 이를 우회한 쉘코드를 이용해야한다 2) x86 아키텍처에서 실행되는 execve syscall이므로, x86-64 아키텍처와 들어가게 되는 인자의 레지스터가 다르다. 이는 아래의 사진을 참고하자 사진을 통해 x86(32bit) 아키텍처에서의 execve의 인자 레지스터로는 eax, ebx, ecx, edx가..
Exploit Tech: Return Address Overwrite(리턴 주소 변경 및 실습) 이번 글에서는 ret 주소를 버퍼 오버플로우를 통해 변경하는 실습을 함께 해볼 것입니다. 소스 코드: #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; } 설명: 위의 소스 코드에는 shell을 실행시킬 수 있는 get_shell이라는 함수가 존재합니다. 이 취약점을 이용하여 메인함수의..
Memory Corruption: Stack Buffer Overflow(개념) 스택 버퍼 오버플로우 스택 버퍼 오버플로우는 스택의 버퍼에서 발생하는 오버플로우를 뜻한다. 이를 이해하기 위해 먼저 버퍼와 오버플로우의 개념을 살펴보자 버퍼 데이터가 목적지로 이동되기 전에 보관되는 임시 저장소이다. 수신 측과 송신 측 사이에 버퍼라는 임시 저장소를 두고, 이를 통해 간접적으로 데이터를 전달하게 합니다. 송신 측은 버퍼로 데이터를 전송하고, 수신 측은 버퍼에서 데이터를 꺼내 사용한다. 버퍼 오버플로우 버퍼 오버플로우(Buffer Overflow)는 문자 그대로 버퍼가 넘치는 것을 의미한다. 버퍼는 제각기 크기를 가지고 있다. 만약 10바이트 크기의 버퍼에 20바이트 크기의 데이터가 들어가려 하면 오버플로우가 발생하게 된다. 일반적으로 버퍼는 메모리상에 연속해서 할당되어 있으므로, 어떤 버..
Quiz: Calling Convention(퀴즈: 함수 호출 규약) *Quiz 1, 2, 3, 4 풀이: 위의 소스코드를 보면 cdecl 호출 규약을 사용한다는 걸 알 수 있다. cdecl에서 인자는 역순으로 push 되므로, (a)에는 push 0x3 (b)에는 push 0x2 (c)에는 push 0x1이 들어간다 (d)에서는 sum 함수의 반환값이 eax에 저장되고 push되어있던 세 인수를 정리해줘야 하므로, 12byte(int인수 세 개)만큼이 줄어들어야한다.(x86 아키텍처에서는 push될 때 0x4만큼씩의 공간이 할당된다) 따라서 (d)에는 add esp, 0xc가 들어간다. *Quiz 5, 6, 7 풀이: SYSV에서는 인자가 RDI, RSI, RDX, RCX, R8, R9 순으로 저장 된다. 또한 인자가 역순으로 저장된다. 따라서 (a)에는 mov rdx,..
Background: Calling Convention(함수 호출 규약) 함수 호출 규약 1. 함수 호출 규약은 함수의 호출 및 반환에 대한 약속이다. 2. 함수 호출 규약은 아키텍처 그리고 운영체제에 따라서 달라지며, 프로그래머가 코드에 어떤 함수 호출 규약을 사용할지 선택할 수도 있다. 3. 함수 호출 규약를 분류하는 방식은 다음과 같다. 즉, 함수 호출 규약에 따라 다음의 것들이 달라진다. 1) 인자 전달 순서 ( 왼쪽 인자 -> 오른쪽 인자 or 오른쪽 인자 -> 왼쪽 인자 ) 2) 인자 전달 방법 ( 스택 or 레지스터 ) 3) Stack Frame을 정리하는 방법 ( 함수 호출자[caller] or 함수 피호출자[callee] ) 함수 호출 규약의 종류 - x86(32bit) 아키텍처는 레지스터를 통해 피호출자의 인자를 전달하기에는 레지스터의 수가 적으므로, 스택으..