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)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

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

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
e_yejun

Jun_ : Pwn

Reversing

[Dreamhack] rev-basic-7 write up

2023. 1. 24. 23:27

Index

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


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

문제

실행 파일(exe)이 주어지고, 실행하면 사용자 입력을 받고 프로그램이 종료된다.

문제풀이

문제의 main 함수이다. sub_140001000함수로 사용자가 입력한 값을 넘긴다.

for 문 안의 if 조건문을 false 반환을 받으면 된다. 먼저, byte_140003000 배열의 값을 확인하자.

F2로 브레이크 포인터를 걸고 F9로 실행시켰다. 프로그램이 실행되면서 0x7ff74a853000 배열에 문자가 저장된 걸 확인할 수 있다.

if ( (i ^ (unsigned __int8)__ROL1__(*(_BYTE *)(a1 + i), i & 7)) != byte_140003000[i] )

위에서 얻은 값을 if 조건문에 맞게 역연산해주면 된다. 지저분한 식을 깔끔하게 바꿔보자.

if ( (i ^ __ROL1__(a1[i], i & 7)) != byte_140003000[i] )

__ROL1__()이라는 함수가 사용된다. 어셈블리어를 함께 보자.

i & 7이 연산된 cl과 a1[i]값을 가진 al이 rol이라는 명령어로 처리된다.

rol은 Rotate Left로 왼쪽으로 시프트연산을 하는 shl과 비슷한 역할이지만, 크기를 넘어서는 비트를 다시 하위 1비트로 밀면서 들어가진다.

오른쪽 방향으로 Rotate Right를 하는 ror도 있다. 역시 shr과 비슷한 역할이지만, 최하위 비트 아래로 내려가는 비트를 상위 1비트로 밀면서 들어간다.

즉, 정해진 크기의 큐가 있다면, 기준점을 잡고 원형 큐 처럼 돌아가면서 시프트되는 연산이다.

문제 조건문에서는 마지막에 xor연산을 수행하니, 결과 값에서 다시 i값으로 xor연산을 수행한다. 이후 ROL이 되어서 결과를 만든 것이니, xor한 결과 값과 i & 7로 ROR연산을 수행한다.

파이썬 풀이 코드

str = [0x52, 0xdf, 0xb3, 0x60, 0xf1, 0x8b, 0x1c, 0xb5, 0x57, 0xd1, 0x9f, 0x38, 0x4b, 0x29, 0xd9, 0x26, 0x7f, 0xc9, 0xa3, 0xe9, 0x53, 0x18, 0x4f, 0xb8, 0x6a, 0xcb, 0x87, 0x58, 0x5b, 0x39, 0x1e]

def ror(x, y):  #1byte ror
    shr = x >> y
    under = x << (8-y)
    under &= 255
    return shr|under

for i in range(0, len(str)):
    xor_i = i^str[i]
    print(chr(ror(xor_i, (i & 7))), end='')

ror함수에서 먼저, 첫번째 인자 x를 두번째 인자 y로 shr 연산을 진행한다. 이후, x에서 8-y만큼 반대로 shl 연산을 진행한다. 두개의 값을 or 연산을 하면 로테이트 된 비트 값이 나오면서 ror연산이 마무리된다. 이때, shl 연산을 한 결과 값은 1byte만 사용될 수 있도록 255(0xff)와 and연산한다.

실행 결과


Uploaded by N2T

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

    티스토리툴바