[Layer7] 리버싱 7차시 과제

2025. 6. 23. 00:24·과제

Custom2

Ghidra를 열어서 확인해보자.

 

 

먼저 Main 함수 들어가보자. 여기서 필요한 부분은 while문이다. 여기서 위 코드는 while 문에서 가공을 거친 변수인 flag (변수명은 내가 바꾼 것이다.)를 fgets로 입력 받은 inputed_value (또한 이것도 내가 변경한 것이다.) strcmp로 비교하여 일치하면 옳은 플래그임을 나타내는 코드이다.

 

여기에서 우리가 봐야할 부분은 while 문 위 변수들과 while 문 안에 있는 코드들이다. cVar4와 lVar5가 각각 76과 0으로 초기화 되어 있다. while 문 안에서는 lVar5가 카운터와 인덱스로 이용되고 있으며 각 인덱스에 있는 문자는 cVar4 - lVar5 * lVar5 식을 따라 결정된다. 그 후 cVar4는 lVar5 + 1 인덱스를 가진 enc2.0 배열의 요소가 저장된다. 

 

enc2.0 배열을 확인해보자.

 

이렇게 각 주소마다 16진수 바이트가 저장되어 있다. 이것을 뽑아내어 연산을 하면 플래그가 나온데 아무리 생각해도 저걸 손으로 일일히 타이핑 쳐서 바이트 값을 가져오는 것은 무리이므로 Ghidra에 내장되어 있는 파이썬 스크립트를 써보자.

 

파이썬 스크립트를 만들었다면 아래와 같은 코드를 작성해보자.

 

# -*- coding: utf-8 -*-

#TODO write a description for this script
#@author 
#@category _NEW_
#@keybinding 
#@menupath 
#@toolbar 
#@runtime Jython


#TODO Add User Code Here
program = getCurrentProgram()
memory = program.getMemory()

# 특정 주소의 데이터 읽기
address = toAddr(0x00102040)  # 원하는 주소
data = getDataAt(address)

# 바이트 배열로 읽기
buffer_size = 65  # 읽을 크기
byte_array = getBytes(address, buffer_size) # enc2.0

# unsigned로 변환
unsigned_byte_array = []

for i in byte_array:
    unsigned_byte_array.append(i & 0xFF)


cvar4 = 76
var5 = 0
flag = [0] * 65

while True:
    flag[var5] = cvar4 - (var5 * var5) & 0xFF
    var5 += 1

    if var5 == 64:
        break

    cvar4 = int(hex(unsigned_byte_array[var5]), 16)
    print hex(unsigned_byte_array[var5]), ' ',

print"\nflag: ", 
for i in flag:
    
    print chr(i),

 

코드를 하나씩 리뷰하면 다음과 같다.

 

program = getCurrentProgram()
memory = program.getMemory()

 

현재 프로그램과 메모리를 받아온다.

 

# 특정 주소의 데이터 읽기
address = toAddr(0x00102040)  # 원하는 주소
data = getDataAt(address)

# 바이트 배열로 읽기
buffer_size = 65  # 읽을 크기
byte_array = getBytes(address, buffer_size) # enc2.0

 

읽어오고 싶은 주소를 toAddr로 지정한 다음 버퍼 크기를 정하고 getBytes를 사용하여 버퍼만큼 읽는다.

 

이러면 버퍼에 저장된 바이트들이 byte_array에 저장된다. 

 

그러나 이렇게만 받아오면 문제가 생긴다. 바로 파이썬이 16진수 바이트를 signed 데이터로 확인하여 음수가 발생할 수 있다는 것이다. 그러므로 아래와 같은 코드를 작성해야한다.

for i in byte_array:
    unsigned_byte_array.append(i & 0xFF)

 

cvar4 = 76
var5 = 0
flag = [0] * 65

while True:
    flag[var5] = cvar4 - (var5 * var5) & 0xFF
    var5 += 1

    if var5 == 64:
        break

    cvar4 = int(hex(unsigned_byte_array[var5]), 16)
    print hex(unsigned_byte_array[var5]), ' ',

print"\nflag: ", 
for i in flag:
    
    print chr(i),

 

다음으로 Ghidra에서 봤던 연산식 작성하고 그것을 문자로 프린트하여 Flag를 확인해보자.

 

 

 

 

Custom3

 

마찬가지로 디컴파일링해서 코드를 확인해보자. flag와 여러 local 변수들이 있는 것을 볼 수 있다. memset으로 flag 변수를 152 바이트 할당한다. 이러는 이유는 뒤에 있는 local 변수와 합치기 위해서다. 그러므로 flag에는 DH_00104020 ~ DH_00104090 값이 저장된다. DH 값을 확인해보자.

 

 

이 값들을 저장하고 나면 아래와 같은 코드가 실행될 것이다.

 

(*(code *)(&PTR_FUN_001040a0)[sVar4 % 11])(&flag);

 

위 코드는  sVar4 % 11 인덱스를 이용한 특정 포인터를 사용하여 함수를 정해 플래그 값을 포인터로 넣는 것을 보여준다.

 

저 포인터로 이동해보자.

 

 

여러 함수가 있다. 전 코드에서 봤듯이 sVar4 % 11를 이용하여 위치를 알아내야 하지만 여기 프로그램에서는 그럴 필요가 없다. 왜냐하면 여러 함수 중 파라미터가 존재하는 함수가 하나 뿐이기 때문이다. 

 

 

처음에 있던 FUN_001014fd 함수는 파라미터가 없는 것을 알 수 있다. 그러면 한 번 FUN_00101ac5 함수를 확인해보자.

 

 

헉 이 함수에는 파라미터가 존재한다. 다른 함수는 파라미터가 존재하지 않는 것을 또한 확인할 수 있다. 이 코드를 집중적으로 봐보자.

 

위 코드에서 for 문을 보면 포인터를 이용해 값이 변경되는 것을 확인할 수 있다. 위 식을 사용하여 아래와 같은 파이썬 코드를 작성할 수 있다.

 

#TODO write a description for this script
#@author 
#@category _NEW_
#@keybinding 
#@menupath 
#@toolbar 
#@runtime Jython


#TODO Add User Code Here
program = getCurrentProgram()
memory = program.getMemory()

address = toAddr(0x00104020)

byte_count = 8 * 14 + 4
raw_bytes = getBytes(address, byte_count)
unsigned_bytes = [] * 116

for i in raw_bytes:
    unsigned_bytes.append(i & 0xFF)



dat_address = toAddr(0x00102010)
dat_byte_count = 16
dat_bytes = getBytes(dat_address, dat_byte_count)
unsigned_dat = []

for i in dat_bytes:
    unsigned_dat.append(i & 0xFF)
    # print hex(i & 0xFF),

sVar4 = len(unsigned_bytes)



for local_8c in range(116):
    unsigned_bytes[local_8c] = (unsigned_dat[local_8c % 16] ^ (unsigned_bytes[local_8c] & 0xFF)) & 0xFF



for i in unsigned_bytes:
    print chr(i),

print "sVar4:", sVar4

 

위 코드를 실행하면 플래그가 나올 것이다.

 

'과제' 카테고리의 다른 글

[Layer7] Web CTF Write-up  (0) 2025.08.05
[Layer7] 리버싱 8차시 문제 풀이  (0) 2025.07.12
[Layer7] 리버싱 6차시 CTFd 문제 풀이  (0) 2025.06.18
[Layer7] 리버싱 5차시 CTFD 풀이  (0) 2025.06.16
[Layer7] rev-basic-1 ~ 6 풀이  (0) 2025.06.15
'과제' 카테고리의 다른 글
  • [Layer7] Web CTF Write-up
  • [Layer7] 리버싱 8차시 문제 풀이
  • [Layer7] 리버싱 6차시 CTFd 문제 풀이
  • [Layer7] 리버싱 5차시 CTFD 풀이
Lambda
Lambda
집 가고 싶다.
  • Lambda
    Lambda's Notebook
    Lambda
  • 전체
    오늘
    어제
    • 분류 전체보기 (40)
      • 포너블 (2)
      • 과제 (17)
      • 정리 (16)
      • 리버싱 (1)
      • 리눅스 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Lambda
[Layer7] 리버싱 7차시 과제
상단으로

티스토리툴바