-
two targets - pwnable.xyzWrite-ups/pwnable.xyz 2020. 2. 12. 00:10
Prob Info Checksec 두가지 방법으로 풀 수 있게 만든 문제이다.
int __cdecl __noreturn main(int argc, const char **argv, const char **envp) { char *v3; // rsi const char *v4; // rdi int v5; // eax char s; // [rsp+10h] [rbp-40h] __int64 v7; // [rsp+30h] [rbp-20h] char *v8; // [rsp+40h] [rbp-10h] unsigned __int64 v9; // [rsp+48h] [rbp-8h] v9 = __readfsqword(0x28u); setup(*(_QWORD *)&argc, argv, envp); v3 = 0LL; v4 = &s; memset(&s, 0, 0x38uLL); while ( 1 ) { while ( 1 ) { print_menu(v4, v3); v5 = read_int32(); if ( v5 != 2 ) break; printf("nationality: "); v3 = (char *)&v7; v4 = "%24s"; __isoc99_scanf("%24s", &v7); } if ( v5 > 2 ) { if ( v5 == 3 ) { printf("age: "); v3 = v8; v4 = "%d"; __isoc99_scanf("%d", v8); } else if ( v5 == 4 ) { v4 = &s; if ( (unsigned __int8)auth((__int64)&s) ) win(); } else { LABEL_14: v4 = "Invalid"; puts("Invalid"); } } else { if ( v5 != 1 ) goto LABEL_14; printf("name: "); v3 = &s; v4 = "%32s"; __isoc99_scanf("%32s", &s); } } }
_BOOL8 __fastcall auth(__int64 a1) { signed int i; // [rsp+18h] [rbp-38h] char s1[8]; // [rsp+20h] [rbp-30h] __int64 v4; // [rsp+28h] [rbp-28h] __int64 v5; // [rsp+30h] [rbp-20h] __int64 v6; // [rsp+38h] [rbp-18h] unsigned __int64 v7; // [rsp+48h] [rbp-8h] v7 = __readfsqword(0x28u); *(_QWORD *)s1 = 0LL; v4 = 0LL; v5 = 0LL; v6 = 0LL; for ( i = 0; (unsigned int)i <= 0x1F; ++i ) s1[i] = ((*(_BYTE *)(a1 + i) >> 4) | 16 * *(_BYTE *)(a1 + i)) ^ *((_BYTE *)main + i); return strncmp(s1, &s2, 0x20uLL) == 0; }
이 함수에서 main함수의 바이트 값을 하나씩 연산하여 일치하면 통과할 수 있다.
Exploit 1
첫번째 방법은 간단하게 생각해 auth함수를 그대로 역산하는 것이다. 메인 함수의 바이트값들과 auth 값을 이용해 그대로 연산을 해줘 값을 입력하면 플래그를 받을 수 있다.
Exploit 2
두번째 방법은 취약점을 이용하는 것이다.
printf("nationality: "); v3 = (char *)&v7; v4 = "%24s"; __isoc99_scanf("%24s", &v7);
이 부분에서 bof가 일어나는데, v7 다음의 v8을 덮을 수 있다.
printf("age: "); v3 = v8; v4 = "%d"; __isoc99_scanf("%d", v8);
v8은 이곳에서 쓰이는데, 숫자를 입력할 수 있다. 이를 이용해 v8을 GOT로 덮고 win 함수의 주소로 GOT Overwrite해주면 된다.
Exploit 3
두번째 풀이를 하고나서 잘 생각해보니 쉘을 딸 수 있을것 같았다. 같은 방법으로 atoi의 GOT를 system@plt로 덮고 "/bin/sh"을 넣어줬다. 하지만 scanf()에서 %d로 받기 때문에 4바이트만 덮을 수 있어 이미 한 번 호출된 atoi는 상위 4바이트에 값이 남아있어 strcmp의 GOT를 덮었다.
Shell 'Write-ups > pwnable.xyz' 카테고리의 다른 글
TLSv00 - pwnable.xyz (0) 2020.02.12 Free Spirit - pwnable.xyz (0) 2020.02.12 xor - pwnable.xyz (0) 2020.02.11 note - pwnable.xyz (0) 2020.02.11 GrownUp - pwnable.xyz (0) 2020.02.11