이제부터 또 열심히!
pwnable.xyz
pwnable.xyz
에서 문제를 풀어보려고 합니다...
사실 며칠 전부터 풀어보려고 했는데... FTZ도 어렵고 그래서 ㅎㅎ 미루다가 FTZ level19 20이 너무 짜증나서 이거먼저 해보려고 합니다.
Welcome문제부터... 시작해보죠!
challenge 파일을 IDA에 넣고 디스어셈블 한 결과입니다.
IDA를 처음 써봐서 이런 방식의 표기는 너무 어색한데요...
알법한 부분만 좀 해석해보자면...
__int64 __fastcall main(__int64 a1, char **a2, char **a3)
{
_QWORD *v3; // rbx
__int64 v4; // rdx
char *v5; // rbp
__int64 v6; // rdx
size_t v7; // rdx
size_t size; // [rsp+0h] [rbp-28h]
unsigned __int64 v10; // [rsp+8h] [rbp-20h]
v10 = __readfsqword(0x28u);
sub_B4E(a1, a2, a3);
puts("Welcome."); // Welcome 출력
v3 = malloc(0x40000uLL); // 0x40000만큼 동적 할당
*v3 = 1LL; // 첫 바이트에 1을 입력
_printf_chk(1LL, "Leak: %p\n", v3); // v3의 주소를 출력
_printf_chk(1LL, "Length of your message: ", v4);
size = 0LL; // size 변수를 0으로 설정
_isoc99_scanf("%lu", &size); // size 변수의 값을 입력받음
v5 = (char *)malloc(size); // size 만큼 동적 할당
_printf_chk(1LL, "Enter your message: ", v6);
read(0, v5, size); // size 만큼 v5에 입력받음
v7 = size;
v5[size - 1] = 0; // v5[size - 1]을 0으로 설정
write(1, v5, v7);
if ( !*v3 ) // v3이 0일 때 실행
system("cat /flag");
return 0LL;
}
이렇게 정리할 수 있을 것 같습니다.
그래도 모르겠으니 gdb를 통해 분석해봐야겠죠?
윽 symbol이 없다고 하네요...
이걸 어떻게 해결해야할 지 이리저리 찾아보다가!
1. 한번 r을 통해 실행해주고
2. b __libc_start_main을 통해 처음 시작하는 부분에 브레이크포인트를 잡아주고
3. 다시 r을 통해 실행해주면?
짜잔
이렇게 나오게 됩니다!
그리고 스샷의 맨 아래에 main=0x5555~~이렇게 있는 부분 있죠?
이곳이 바로 main 함수의 시작지점이라고 합니다.
그래서
x/70i 0x555555554920
이렇게 입력해주게 되면?
이런식으로 main 함수가 어떻게 구성되어있는지 확인할 수 있습니다.
그리고 일단 main 함수 첫부분에 브레이크 포인트를 잡아주도록 하죠.
이제 어떻게 풀어야할까요?
아까 위에 코드에서
v5[size - 1] = 0;
이게 있었고,
if 문에서는 v3가 0이어야 하므로... 이걸 잘 이용하면 될 것 같습니다.
v5를 0으로 바꿔주는 부분에 브레이크를 걸어주고 실행해볼게요.
그게 이 부분이겠죠? if문과의 거리로 보나 생김새로 보나 저부분입니다.
브레이크를 걸어주고? 임의로 길이는 10 문자열은 AAAAAAAA를 넣어줬습니다.
rbp+rdx*1-0x1의 주소에 0x0을 입력하라.. 라는 의미인데요.
저 위치는 일단 배열의 마지막 원소를 나타냅니다.
rdx*1은 char 형 배열이기 때문에 1바이트 크기라서 그런 것 같네요.
우리의 목표는 저 배열의 마지막 원소가 v3이 되게하면 될 것 같습니다!
이제 각각 저 값이 무엇인지 알아봅시다!
우선 rbp는 레지스터에서 AAAAAAAA가 들어있네요. 입력한 문자열의 주소(v5 주소)가 들어가는 부분입니다.
rdx는 레지스터에서 0xa가 들어있으며, 이는 10을 의미하기에 문자열의 길이(size)가 들어가는 부분입니다.
따라서 (v5의 주소 + size * 1 - 0x1)가 v3이 되면 됩니다.
이걸 어떻게 하냐? 라고 생각이 드시는 분들도 있을겁니다.
v5의 주소도 모르는데 어떻게 잘 조절해서 저렇게 하지?
malloc의 문제점을 이용하면 되는데요. malloc은 동적 할당이지만 엄청난 크기(메모리 크기를 넘어가는 양)를 할당받게 된다면 할당에 실패하게 됩니다. 이 경우 동적 할당을 받는 변수의 첫 주소는 null(0)이 되게 되는데요. 바로 이 점을 이용하는겁니다.
(0 + size * 1 - 0x1 = v3의 주소) 처럼 될 수 있다는 것이죠!
이를 이용해서 문제를 해결하는 코드를 작성하게 되면?
이렇게 됩니다.
중간중간 print는 제가 사용한 문법이 맞는지 확인한 것이므로 무시하셔도 좋습니다.
이렇게 풀 수 있습니다!
끄읕
'Hacking-기초 > [PWN] Pwnable.xyz' 카테고리의 다른 글
[PWN] xor (50pts) (0) | 2020.08.01 |
---|---|
[PWN] note (50pts) (0) | 2020.07.30 |
[PWN] misalignment (50pts) (0) | 2020.07.28 |
[PWN] add (50pts) (0) | 2020.07.28 |
[PWN] sub (50pts) (0) | 2020.07.28 |