WAR GAME/pwnable.xyz

[pwnable.xyz] xor 풀이 (64bit, OOB, call)

jir4vvit 2021. 5. 5. 13:45

문제 풀이 환경 : ubuntu 18.04
사용 툴 : IDA 7.5 pro

어제 롸업보고 다음날에 롸업 안보고 다시 풀었다. 


주어진 파일은 문제 파일 바이너리

 

접근해서 적을 수 있나여?

 

Analysis

mitigation

execution

code

main

이 전에 풀었던 addsub 문제랑 비슷해보인다. 

세 숫자를 입력해야하고 마지막 인풋은 index이다. 

 

이 문제도 역시 flag를 출력해주는 win 함수가 존재하는데, win 함수를 최종적으로 실행시키는 것이 목표이다.

 

저기 네모친 곳원하는 주소원하는 값을 쓰고 있다. 그리고 더 자세히 보면(?) OOB가 발생한다. idx는 9이상이 되면 프로그램이 while문을 빠져나가지만, 음수일 때는 체크하지 않아서 OOB가 발생한다. 

 

그리고 저기 if 조건이.. 첫번째와 두번째로 입력한 수가 0이 되면 안되는데, 이건 xor 연산할 때 A^0 = A 가 되는? 쉽게 연산하는 것을 막으려고 이렇게 한 것 같다.  그리고 역시나 문자를 입력하면 break...!

 

 

처음에 main의 RET를 win 함수로 덮을까?라는 생각을 했다. 하지만 이 프로그램은 while문을 빠져나오면 exit 함수를 실행시켜 종료하므로 main의 RET까지 가지 않는다 ㅠ 그럼 어떻게 풀어야 할까..

Exploit Scenario

Summary

  1. 1099511583976 1 -262887 입력
  2. 아무 문자 입력

무슨 값을 쓸까

main

그럼 우리는 exit를 실행할 때 win이 실행되었으면 좋겠다고 생각할 것이다. 하지만 이 문제는 풀렐로 이므로 함수의 got를 덮을 수는 없다.

디버깅하려고 pie base를 구하려고 했는데, 보니까 좀 수상하다. 모든 권한이 다 있다.. 수정이 가능하다고 한다.

이거에 유의해서 다시 main을 한번 보면...

 

 

call exit 대신 call win을 실행을 시킬 수 있지 않을까?

 

이 전에 hackctf ezshell 문제에서 이런 비슷한 것을 다뤄본 적이 있다.

call : E8 + 4byte

jmp : E9 + 4byte

뒤의 4byte는 상대적이라서 다 다르다. 뒤의 4byte를 구하려면 목적지 주소 - 현재 명령 주소 - 5 를 하면 된다.

call win

\xE8\x54\xff\xff\xff

0xffffff54E8 => 10진수로 하면 1099511583976

 

v4 ^ v5를 저 값으로 만들어야 한다. 1099511583976 ^ 1 = 1099511583977  -> 0xFF FFFF 54E9

 

0xFF FFFF 54E9\xE9\x54\xff\xff\xffjmp call

 

처음에 win call을 실행시킬까 했지만... 그냥 저렇게 1099511583976과 1을 주어 jmp win을 실행시켜도 된다.

 

난 죽어도 call win을 실행시키겠다..! 하면

xor을 자기 자신과 두 번 하면 자기 자신이 된다는 것을 이용하면 된다.

 

v5 = 0xFFFFFF54e8 ^ 1 한 값

v4 = 1

 

v4(1) ^ v5(0xffffff54e8^1) 

 

어디에 쓸까

당연히.. call exit 자리에 call win을 써야하니깐 call exit 자리에 써야 한다. 

이 자리는 어떻게 구할까?

 

어셈을 확인해 보자.

내가 인풋 세개를 1 1 1로 줬다. 어셈을 rax, rcx, rdx에 내가 적은 값을 넣는다. rbp에서 떨어진 위치를 보니까 rax가 idx이다.

그리고 rcx와 rdx를 xor한 값을 rcx에 넣는다.

rax가 내가 넣은 idx니깐..

idx*8 + 0x555555756200(result) = 0x555555554ac8(call exit위치)

 

이렇게 되는 것을 알겠는가?,,

이렇게 계산을 해주면 idx-262887이 된다.

Exploit Code