[pwnable.xyz] xor 풀이
analysis
canary 없음.
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();
while ( 1 )
{
v6 = 0LL;
printf(format, argv);
v3 = _isoc99_scanf("%ld %ld %ld", &v4, &v5, &v6);
if ( !v4 || !v5 || !v6 || v6 > 9 || v3 != 3 )
break;
result[v6] = v5 ^ v4;
argv = (const char **)result[v6];
printf("Result: %ld\n", argv);
}
exit(1);
}
main에서는 숫자 3개를 입력받아서
숫자 중 0이 있거나 마지막 숫자가 9보다 크면 break한다.
result의 v6 인덱스에는 v5와 v4를 xor한 값이 들어간다.
result는 bss에 존재한다.
relro에 의해 result의 oob를 이용해서 got overwrite는 불가능하다.
argv를 사용한다는 점에서 이상하다.
printf에 argv를 그대로 넣는 점에서 fsb가 가능하지 않을까
안 되는 것 같더라.
또 특이한 점은 code 영역이 rwx 권한을 모두 가진다는 것이다.
oob를 이용하여 코드 수정이 가능하다.
종료 조건 이후 실행하는 call exit 부분을 partial overwrite를 통해 win으로 우회가 가능할까
pie에서 exit 함수는 0x830으로 끝나고 win 함수는 0xa21로 끝난다.
exploit
그러면
main에서 main+148이 call exit이고
main+153이 다른 instruction인걸로 보아
148부터 152까지가 call exit 관련인듯 한데
어딜 바꿔야할까
https://aidencom.tistory.com/190
0xe8이 call 이라는 뜻이고
뒤에 4byte가 상대주소로 쓰인다.
oob를 통해서 뒤 4byte를 바꿔주면 된다. 뭘로 바꾸지
상대 주소 = 목적지 주소 - rip - 5라고 한다.
목적지 주소는 win 주소..
0xff ff ff 54이다.
그러면 main+149에 54, main+150에 ff 넣으면 된다.
음. 위치를 계산하는건
(main+149 - result)/8을 했더니 -262887이 나온다.
주소가 잘 안들어간다.
맨 뒤가 무시된다. 왜징
대충 뒤에 00을 주고
0xffffff5401 1 -262887
정확히는
1099511583745 1 -262887 하니까 win이 들어간다.
gdb에서는 되든거 같더니 안된다.
그러면 다른 풀이처럼 0xffffff54e9 1 -262887로 해본다.
1099511583977 1 -262887
이건 또 된다.
왜지..
gdb랑 실제랑 다른갑다. 어떻게 보면 뒷자리가 들어가지 않는게 이상하니까