WAR GAME/pwnable.xyz

[pwnable.xyz] 133t-ness 풀이 (integer overflow, 계산놀이)

jir4vvit 2021. 5. 19. 16:32
문제 풀이 환경 : ubuntu 18.04
사용 툴 : IDA 7.5 pro

정수로 하는 계산놀이다.


Analysis

mitiagtion

사실 문제 풀 때 코드부터 확인했다.

보호기법 확인안해도 될 것 같아서 문제풀 때는 하지 않았었다.

execution

매정하게 종료된다..

code

IDA 켜자마자 함수 목록이 쫘라락 나온다.

main

round_1, round_2, round_3 반환값이 0이 아니면 win 함수를 실행시킨다.

round_1

x와 y에 read함수로 입력 받는다.

 

빨간색 네모

strchr 함수를 이용하여 해당 문자열에 '-' 문자가 포함되어있는 지 확인한다.

포함되어 있으면 포함된 곳의 포인터를 반환하고 없으면 Null 포인터를 반환한다. (false)

if문이 flase(0)이어야 한다.(if문을 타면 안된다.)

결론은 x와 y 문자열에 '-' 문자가 없어야 한다.

 

v1와 v2는 각각 x와 y를 정수타입(int)로 바꾼 값이다.

 

주황색 네모

v1와 v2는 1336보다 작아야 한다.

result 값을 어셈을 통해 확인하면 아래와 같다.

v1에서 v2를 뺀 값을 0x539(1337)과 비교하는데, 우리는 최종적으로 0이 아닌 값을 반환해야 하므로(main에서 win가 호출되는 조건) 오른쪽으로 가야한다. (jump해야 한다.)

jz 어셈블리는 cmp한 값이 같으면 점프를 한다.

 

이 경우, v1과 v2의 값을 아래와 같이 예상해볼 수 있다.

v1 = 1336

v2 = -1

하지만 이렇게 입력을 하면 첫번째 if문(빨간색 네모)에서 -1의 '-'가 걸려 0을 리턴하게 된다.

 

그래서 우리는 v2 타입이 int라는 것을 이용해야 한다.

integer overflow를 일으켜서 0xffffffff를 입력하면 -1로 값을 넣을 수 있다.

 

결론적으로 v1과 v2에 넣어야할 값은 아래와 같다.

v1 = 1336

v2 = 4294967295 (0xffffffff)

 

round_2

scanf로 v1과 v2를 입력을 받는다.

v1은 1보다 커야하고, v2는 1337보다 커야한다.

v1과 v2를 곱한 값은 1337이어야 한다.

지금 롸업 작성하면서 생각든건데... 함수가 bool 타입이라 eax에 1아니면 0을 넣어서 리턴시킨다 ㅋㅋ

 

아무튼.. v1이 rbp-0x10, v2이 rbp-0xC 인 것에 집중하여 보면 아까 코드상으로 분석한 거랑 똑같다.(당연한 소리겠지만 ㅎ)

 

v1 * v2 = 1337

마음 같아선 1 * 1337을 하고 싶다;;

 

x * (a+1337)/x = 1337 (이때 x는 a+1337에 나누어 떨어지는 값)

a+1337은 1337이어야 한다.

v1과 v2가 int이기 때문에 integer overflow를 생각해볼 수 있다. 

그러면 a는 0이 되어야 하니깐 4294967296

 

결론적으로

v1 = 3

v2 = 1431656211     //  (4294967296+1337)/3

 

round_3

scanf의 포맷스트링이 %d가 5개이므로 정수를 5개 입력을 받는다.

 

빨간색 네모는 왼쪽 라인, 주황색 네모는 오른쪽라인...

최종적으로 누가봐도 두꺼운 녹색 네모칸으로 가야한다.

 

디버깅할 때 편의상 1 2 3 4 5를 입력하였다. (난 보통 IDA 어셈보다 gdb로 한줄한줄 실행하면서 코드 흐름을 본다. ㅎ)

1 : rbp-0x20

2 : rbp-0x1C

3 : rbp-0x18

4 : rbp-0x14

5 : rbp-0x10

 

for문 빠져나온 곳을 보면...

입력한 모든 수 의 합과 곱이 같아야 한다.

 

하지만 입력한 모든 수는 왼쪽의 for문 루프에서 나중의 적은 수가 먼저 적은 수보다 같거나 커야 한다.

1 2 3 4 5

1 1 1 1 1 

이런식으로 되어야 한다.

 

이 경우.. 합과 곱이 같은 수를 만족하는 건 0 0 0 0 0 이다!

 

Exploit code