Dreamhack

리버싱 09 - 혼자 실습

kchabin 2022. 7. 12. 21:59

주어진 chall3.exe 파일을 윈도우 파워쉘에서 실행함. 맞는 문자열을 입력해야 Correct가 뜨고, 그 정답이 뭔지를 알아내야 함. 

IDA가 찾은 main 함수가 바로 나옴. 

일단 Strings에서 Correct 문자열을 찾아보고 해당 문자열이 어디서 참조되고 있는지 확인해보겠음.

역시 main함수에서 참조되고있음.

지난 실습을 하면서 정말 많이 본 코드가 바로 등장함. 생겨먹은 걸 보면 sub_1400011B0은 printf 함수, sub_140001210은 scanf 함수로 보임. 그리고 sub_140001000 함수가 v4를 인자로 받아서 입력값을 검증하는 함수겠지 싶음. 

 

sub_1400011B0 디컴파일. _acrt_iob_func()이 1이 인자이므로 이게 stdout 스트림을 사용하는 printf 함수인 것을 알 수 있음.

함수 내부에 있는 sub_140001080을 디컴파일하면 vfprintf가 나옴. 이를 통해 sub_1400011B0은 printf 함수라는 걸 확실히 알 수 있음. 

_acrt_iob_func()의 인자가 0임 -> stdin 스트림 사용.

내부에 있는 함수 sub_1400010D0을 디컴파일해보면 vfscanf가 나오는 것을 통해 sub_140001210은 scanf 함수라는 걸 알 수 있음. 

입력값을 검증하는 것으로 보이는 sub_140001000 함수를 디컴파일 해봤더니 반복문이 나온다. 아무래도 입력받은 값에 i를 더하고 곱하고 어쩌고를 해서 다른 0을 리턴하고 아니면 1을 리턴하는 식인 것 같다. i는 0부터 0x18까지인데 0x18은 십진수로 24이다. 따라서 이게 24번 반복된다는 것을 알 수 있다. 

그리고 ^ 이건 C언어에서 xor 연산 기호라고 한다. 

byte_140003000을 더블클릭하니까 이런게 튀어나왔다. 

혹시 16진수인건가 해서 변환시켜봤는데 말도 안되는 게 나온다. 아무래도 저 값들과 문자열 인덱스를 각각 비교하는것같다.

일단 C로 결과값을 얻어야 하는 것 같아서 적혀있는 코드를 보고 작성했다. 

if 조건문을 어떻게 써야할 지 찾아보니까 XOR 역연산을 해야 했다.

일단 *(unsigned __int8 *)*(a1 + i) 이 부분이 이제 우리가 입력한 값.그냥 ans[i] 

byte_140003000은 저 16진수들이 저장된 배열인데 저 16진수들이 곧 답 인거다. 

역연산을 하려면 우변에 있는 식들을 좌변으로 옮겨 줘야 한다. 

 

(byte_140003000[i] - 2*i) != i XOR [입력값] 

(byte_140003000[i] - 2*i) XOR i != [입력값] 

 

근데 이제 굳이 입력값과 비교할 필요 없이 그냥 플래그를 출력하는 게 목적이니까 

(byte_140003000[i] - 2*i) XOR i 

for문 안에 이걸 입력해서 출력하도록 하는 코드를 짠다.

플래그 = I_am_X0_xo_Xor_eXcit1ng

 

실제로 코드를 짜서 프로그램을 돌려서 플래그를 얻어낸다는 것을 생각도 못했다. 코딩 공부도 소홀히 하면 안될듯하다.

'Dreamhack' 카테고리의 다른 글

시스템 해킹 Stage 2  (0) 2022.07.18
시스템 해킹 Stage 1  (0) 2022.07.18
리버싱 08 - Patch  (0) 2022.07.12
리버싱 07 - rev-basic-1  (0) 2022.07.12
리버싱 06 - rev-basic-0  (0) 2022.07.12