Dreamhack-rev-basic-4 문제 풀이

Posted by : at

Category : reversing



0. 메타데이터 분석


/assets/img/posts/2024-12-01-rev-basic-4/Untitled.png


  1. PE64
  2. C언어로 작성
  3. 패킹은 안됐을 것 같아서 검사 패스


1. 동적 분석


큰일났다 사전에 문제 4개 풀기로 합의했는데 그거 쌩짜로 까먹고 2개라고 굳세게 주장하면서 나만 2개 풀었다

이제부터 엉덩이에 먼지나게 문제푼다 실시

사용자 인풋을 콘솔 통해서 stdin으로부터 받음


2. 정적 분석


/assets/img/posts/2024-12-01-rev-basic-4/Untitled_1.png


sub_140001220은 사용자 입력값을 scanf 계열 함수를 사용해 받을 것이다

확인해 보니 맞다

검증 루틴인 sub_140001000을 확인해 보자


2.1. sub_140001000


/assets/img/posts/2024-12-01-rev-basic-4/Untitled_2.png


이렇게 보니까 영 가독성이 떨어진다. 변수를 바꿔서 예쁘게 보이도록 해주자.

/assets/img/posts/2024-12-01-rev-basic-4/Untitled_3.png


검증 루틴의 루프가 총 0x1C회 돌기 때문에, byte_140003000 배열은 총 28 byte의 데이터를 담고 있을 것이다.

그렇다면 해당 배열에는 어떤 데이터가 들어있을까?

24 27 13 C6 C6 13 16 E6 47 F5 26 96 47 F5 46 27 13 26 26 C6 56 F5 C3 C3 F5 E3 E3 00


이제 검증 루프 조건문을 해석해 보자.

(24*x) (x»4) 는 (x«4) (x»4) 와 동치된다.

즉, 검증 루틴의 수식은 아래와 같이 변경 가능하다.

(usr_input[i]<<4) | (usr_input[i]>>4) != byte_140003000[i]

usr_input[i] 가 1byte짜리인 것을 감안하면, 앞뒤 4bit씩을 교환하는 의미를 가지고 있음을 알 수 있다.

그렇다면 동일하게, 무엇이 알맞은 usr_input[i] 인지를 알고 싶다면

usr_input[i] = (byte_140003000[i]<<4) | (byte_140003000[i]>>4)

가 될 것이다.

이를 프로그램으로 구현해 보자.

from pwn import *# 프로그램 내부에 저장되어 있던 데이터 덤프 파일을 리스트로 저장tmp=[]
with open('./data', 'rb') as file:
    while True:
        byte=int.from_bytes(file.read(1), byteorder='big')
        if not byte:
            break #EOF then end the loop        tmp.append((((byte) << 4)&0xFF)|((byte) >> 4))
tmp_to_string=[chr(i) for i in tmp]
output=[]
output.append(''.join(tmp_to_string))
print(output)


플래그 획득 완료!

/assets/img/posts/2024-12-01-rev-basic-4/Untitled_4.png


About TouBVA
TouBVA

A Security Researcher, now concentrating on Security Consulting.

Email : touBVa@gmail.com

Website : https://toubva.github.io