셸(Shell)은 운영체제에 명령을 내리기 위한 사용자 인터페이스로, 운영체제의 핵심 기능을 담당하는 커널(Kernel)과 대비된다. 셸을 획득하면 시스템을 제어할 수 있어, 해킹에서 셸 획득은 성공을 의미한다.
execve 셸코드는 임의의 프로그램을 실행할 수 있는 셸코드로, 이를 통해 서버의 셸을 획득할 수 있다. 보통 셸코드라고 하면 이 execve 셸코드를 가리킨다.
리눅스에서 기본 셸로는 sh, bash가 많이 사용되며, 사용자가 zsh, tsh 등의 다른 셸도 설치할 수 있다.
어셈블리 코드
execve 셸코드의 syscall은 다음과 같다.
syscall | rax | arg0 (rdi) | arg1 (rsi) | arg2 (rdx) |
execve | 0x3b | const char *filename | const char *const *argv | const char *const *envp |
여기서 argv는 실행파일에 넘겨줄 인자이고, envp는 환경변수다.
리눅스에서 기본 실행 프로그램들은 /bin 디렉토리에 저장되어 있으며, 여기서 실행해야 할 sh도 해당 디렉토리에 저자오디어 있다.
따라서 execve("/bin/sh", null, null) 을 실행하는 것을 목표로 쉘 코드를 작성한다.
mov rax, 0x68732f6e69622f
push rax
mov rdi, rsp ; rdi = "/bin/sh\x00"
xor rsi, rsi ; rsi = NULL
xor rdx, rdx ; rdx = NULL
mov rax, 0x3b ; rax = sys_execve
syscall ; execve("/bin/sh", null, null)
한줄씩 살펴보면
mov rax, 0x68732f6e69622f
push rax
rax 레지스터에 0x68732f6e69622f 값을 이동(저장)한다. ASCII 문자열 /bin/sh에 해당하는 값이다.
rax 레지스터에 저장된 값을 스택에 push한다. 스택에 문자열 /bin/sh이 저장된다.
mov rdi, rsp
rdi 레지스터에 현재 스택 포인터(rsp) 값을 저장한다. 이로써 rdi는 "/bin/sh" 문자열을 가리키게 된다.
이는 execve 시스템 호출에서 실행할 프로그램의 경로를 나타낸다.
xor rsi, rsi
xor rdx, rdx
xor 연산을 통해 rsi와 rdx가 0으로 초기화되며, 0은 포인터로 사용되면 NULL을 나타낸다.
mov rax, 0x3b
syscall
rax 레지스터에 0x3b를 저장한다.이는 execve 시스템호출의 번호이다.
syscall 명령어로 rax에 저장된 시스템 호출 번호(0x3b, 즉 execve)와, 앞서 설정된 rdi(파일 경로), rsi(인자), rdx(환경 변수) 값을 사용하여 /bin/sh 셸을 실행하게 된다.
컴파일 및 실행
위 어셈블리 코드를 컴파일하기 위해, 스켈레톤 코드안에 쉘코드를 채운 파일을 만든다.
__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(); }
위 파일을 컴파일하고 실행한다. sh가 성공적으로 실행된 것을 확인할 수 있다.
디버깅
run_sh에 브레이크 포인트를 걸고 실행한 결과다.
다음은 execve 시스템 호출(run_sh+27)에 브레이크 포인트를 걸고 실행했다.
경로, 인자, 환경변수가 설정된 것을 확인할 수 있다.
ni(next instruction)명령어를 사용해서 다음 코드인 syscall을 실행하면 sh이 실행된다.
참고 - 드림핵( System Hacking )
'시스템 해킹 > 학습' 카테고리의 다른 글
[시스템] (스택) 버퍼 오버플로우 (0) | 2024.08.26 |
---|---|
[시스템] 함수 호출 규약 (SYSV) (0) | 2024.08.22 |
[시스템] 바이트 코드 쉘 코드 만들기 (objdump) (0) | 2024.08.20 |
[시스템] orw 셸코드 (Shellcode) (0) | 2024.08.20 |