tmxklab
[Pwnable.xyz] welcome 본문
1. 문제
nc svc.pwnable.xyz 30000
1) 문제 확인
어떤 leak된 주소가 출력되고 입력 값을 받을 수 있는 부분이 존재
2) IDA(hex-lay) - 메인함수
- 14~15번째 줄 : v3포인터 변수를 malloc을 통해 메모리 할당과 1로 초기화
- 19~20번째 줄 : scanf를 통해 입력 값을 size변수에 저장, v5포인터 변수를 malloc을 통해 메모리 할당 시 size값의 크기만큼 할당
- 22~23번째 줄 : v5포인터 변수에 size크기만큼 표준 입력을 받고 v7변수에 size값 저장
- 26번째 줄 : v3가 널 값이면 flag값을 보여줌
3) 메모리 보호기법 및 파일 정보 확인
- 64bit elf파일이며 동적 라이브러리를 사용, stirpped된 파일이라 함수의 심볼 정보가 없음
2. 접근 방법
확인1)
main함수의 if문을 통과해야 플래그 값을 볼 수 있으며 if문을 통과하기 위해서는 v3포인터 변수가 널 값이어야 한다.
확인2)
v3포인터 변수가 널 값이어야 하지만 v3는 메모리 할당한 뒤 1로 초기화 시키므로 if문에 만족하지 못하여 main함수가 종료된다.
디버깅)
일단, stripped된 파일이라 disas main이 안먹힌다.
그래서 나는 다음과 같은 방법으로 main함수 디버깅을 했다.(사실 구글링하다가 알게 됨)
1)
- 먼저 run함
2)
- __libc_start_main에 bp를 걸어줌
- run하면 main함수의 주소 값이 보임
3)
- main함수 주소 값에 bp를 걸어줌
4)
- 다시 run하면 짜잔~ 메인함수에 들어옴
디버깅)
1) v5포인터 변수를 가지고 v3포인터 변수의 주소 값에 overflow가 가능하지 않을까 했다.
- v3는 rbx에 저장되고 v5는 rbp에 저장되는데 거리가 너무 멀다
2) v5의 사이즈
v3는 malloc시 사이즈 값이 코드 상에 존재하지만 v5는 사이즈 값을 사용자의 입력 값에 따라 변경될 수 있다.
- 위 인스트럭션은 v5[size-1]=0이며, rbp(v5포인터 변수 주소) + $rdx(size값) - 1을 뜻한다.
2-1) 적당한 크기의 사이즈를 잡은 경우
- 정상적으로 v5[size-1]에 0이 들어가는 것을 확인할 수 있다.
- 또한, v5[rbp]의 주소 값이 제대로 찍히는 것을 볼 수 있다.
rbp = v5, rdx = size(0x7b=123)
2-2) 엄청 큰 사이즈를 잡은 경우
- v5[rbp]의 주소 값이 0x0으로 되는 것을 볼 수 있다.
3) 결론
-
비정상적으로 v5의 사이즈를 크게 잡은 경우 malloc에서 실패하여 주소 값을 0으로 초기화되는 것을 확인할 수 있다.
-
[rbp + rdx - 1] = 0인 부분에서 "rbp + rdx - 1 = v3의 주소 값"을 만족시키려면 v3는 0으로 초기화될 것이다.
-
v3의 주소 값은 rbx에 담기며 십진수로 변환하는 경우 엄청 큰 값을 가지게 된다.
-
따라서, rbp는 0으로 초기화되며 "rdx - 1 = v3의 주소 값"이 된다.
3. 풀이
1) 디버깅을 통해 확인
- RBX는 v3의 주소 값이며 현재 1이 저장됨
- 0x7fffff790010 = 140,737,479,507,984
- 따라서, 위 십진수에 1을 더한 140,737,479,507,985를 입력한다.
- v3의 주소에 0으로 값이 바뀐 것을 확인할 수 있다.
조건문 통과
2) 공격 실행
- v3의 주소 값 : 0x7fc71bb98010
- 십진수로 변환하면 140,493,140,361,232이며 1을 더한 값을 입력해준다.
'War Game > Pwnable.xyz' 카테고리의 다른 글
[Pwnable.xyz] free spirit (0) | 2020.03.30 |
---|---|
[Pwnable.xyz] grownup (0) | 2020.03.30 |
[Pwnable.xyz] misalignment (0) | 2020.03.27 |
[Pwnable.xyz] add (0) | 2020.03.07 |
[Pwnable.xyz] sub (0) | 2020.03.07 |