e_yejun
Jun_ : Pwn
e_yejun
전체 방문자
오늘
어제
  • 분류 전체보기 (240)
    • Profile (1)
    • Pwnable (54)
    • Reversing (14)
    • Network (8)
    • Forensic (10)
    • Embedded (4)
    • Android (2)
    • Web (18)
    • 알고리즘 (42)
    • 프로그래밍 (24)
    • 프로젝트 (6)
    • 1-day (7)
    • CTF (15)
    • 기타 (33)
    • 일기장 (0)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • wargame
  • x64
  • 1-day
  • dvwa
  • Heap
  • BOF
  • how2heap
  • dreamhack.io
  • rev-basic
  • X86

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
e_yejun

Jun_ : Pwn

Reversing

[Dreamhack] rev-basic-3 write up

2023. 1. 22. 15:44

Index

문제
문제풀이
파이썬 풀이 코드
실행 결과


rev-basic-3
Reversing Basic Challenge #3 이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다. 해당 바이너리를 분석하여 correct를 출력하는 입력값을 찾으세요! 획득한 입력값은 DH{} 포맷에 넣어서 인증해주세요. 예시) 입력 값이 AppleBanana일 경우 flag는 DH{AppleBanana} Reference Reverse Engineering Fundamental Roadmap
https://dreamhack.io/wargame/challenges/17/

문제

실행 파일(exe)이 주어진다. 실행시키면 Input : 이라는 문자열을 출력하고, 사용자가 입력을 하면 프로그램이 종료된다. IDA 도구를 이용해서 이 파일을 분석해보자.

문제풀이

IDA 도구로 디컴파일한 main 함수이다. 프로그램을 실행시켰을 때와 같이 6번째 라인에서 Input : 문자열이 보인다. sub_1400011b0으로 더블클릭을 하여 들어가보면, printf 함수인 것을 알 수 있다. 이후 7번째 라인에서 사용자 입력을 받는다. 따라서 sub_140001210은 scanf 함수이다.

8번째 라인에서 sub_140001000 함수의 리턴 값에 따라 Correct 또는 Wrong 를 출력한다.

입력받은 v4 배열 변수 시작 주소를 넘기기 때문에, 무엇인가 비교하는 구문이라고 예상할 수 있다. 이 함수로 더블클릭으로 들어가서 분석해보자.

인자로 넘긴 v4의 배열 변수 시작 주소를 함수 안에서는 a1으로 사용한다. 이때 __int64 자료형으로 디컴파일 됐지만, 포인터 변수로 예상할 수 있다.

5번째 라인에서 for문으로 i가 0부터 23까지 24번 반복하고, 배열 인덱스로 i를 사용하여 byte_140003000 의 값을 1바이트씩 불러온다.

byte_140003000은 1바이트씩 32개인 배열로 선언되어 있고, 값들로 추정되는 값들이 나열되어 있다. 직접 메모리에 적재된 값을 확인하기 위해 비교하는 구문에 F2로 브레이크 포인터를 걸고, F9로 실행시켜보자.

메모리에 올라가면서 주소가 바뀌었다. 아까 위에서 byte_140003000가 프로그램이 실행되면서 byte_7ff75f213000이 되었다. 이 값을 Hex View에서 g키를 통해 7ff75f213000을 검색하면 아까 보았던 값들이 실제로 메모리에 적재된 것을 확인할 수 있다. 총 32byte 길이 중, 24byte가 입력되어 있다. 이 값을 1byte씩 가져와서 비교를 하는 것임을 우리는 이해했다.

다시 코드로 돌아가서 문제를 풀어보자.

이 함수의 리턴 값에 따라 Correct 또는 Wrong 이 출력된다고 했다. Correct를 위해서는 for문이 도는 동안 if 구문이 참(true)이 되면 안된다.

byte_14003000[i]의 값과 오른쪽 항의 값이 같지 않다면 참이 된다. 즉, 오른쪽 항의 연산 결과 값이 왼쪽과 같아야 한다.

오른쪽 항에서는 우리가 입력받은 값을 1byte씩 참조하고, 이 값을 2*i만큼 더하고, 마지막으로 i의 값과 XOR연산을 한다. 이 값이 아까 우리가 확인했던 byte_140003000 인덱스 값마다 일치하면 된다.

정리하면, 미리 연산해논 결과 값이 프로그램 안에 배열로 존재한다. 이 값을 주어진 식으로 역연산하는 문제가 되겠다. 간단한 파이썬 코드로 역연산된 값을 출력하면 플래그로 추정되는 값을 얻을 수 있다.

파이썬 풀이 코드

str = [0x49, 0x60, 0x67, 0x74, 0x63, 0x67, 0x42, 0x66, 0x80, 0x78, 0x69, 0x69, 0x7b, 0x99, 0x6d, 0x88, 0x68, 0x94, 0x9f, 0x8d, 0x4d, 0xa5, 0x9d, 0x45]
for i in range(0,24):
    print(chr((str[i]-(2*i))^i),end="")

실행 결과


Uploaded by N2T

    'Reversing' 카테고리의 다른 글
    • [Dreamhack] rev-basic-7 write up
    • [Dreamhack] rev-basic-6 write up
    • [Dreamhack] rev-basic-5 write up
    • [Dreamhack] rev-basic-4 write up
    e_yejun
    e_yejun
    정리노트 •_•

    티스토리툴바