728x90
반응형
목차
1. Easy ELF 실습
  - 실습을 위한 사전 단계(Linux 파일 실행)
2. 분기문 분석
3. byte 및 배열 정리
4. 소스코드 작성(어셈블리어 기반)

[Review] (4주차) 이론 - 총정리

2022.07.19 - [Security & Analysis/IDA Pro] - [IDA Pro] 악성코드 정적분석 툴 사용법&이론 - week.04(전 과정 Review)

 

[IDA Pro] 악성코드 정적분석 툴 사용법&이론 - week.04(전 과정 Review)

개요 * Easy_KeygenMe.exe 파일 실습 1. 레지스터 활용 분석 - 메모리 주소 및 스택 프레임의 이해 - ESP(스택 포인터), EBP(프레임 포인터), EIP 등 개념 정리 2. 어셈블리 명령어 이해 및 알고리즘 분석 - Pse

sarahee.tistory.com


1. Easy ELF 실습

ELF 파일은 리눅스의 실행파일이므로, 실행시킨 후 랜덤 문자를 입력

Wrong 출력

파일 확장자를 모든 파일(All Files (*))로 변경

2. 분기문 분석

실행 후 View > Open subviews > Strings (or Shift + F12)

문자열 검색

리눅스 실행 시 조회된 문자열(Reversing.Kr Easy ELF, Wrong) 및 정답 출력 예상(Correct) 조회

Wrong 해당 그래프 모드 확인

Wrong graph

cmp를 통해 분기문 이동

jump if not zero(not equal) → eax가 1이라면(빨간색 화살표), Correct 연결

레지스터나 메모리 값을 변경하지 않고, 플래그 레지스터에만 영향을 줌

* flag register: 상태 레지스터

Correct graph

분기문 지나기 전 call 링크 두개

sub_8048434

sub_8048451

eax가 1이 되기 위해서는, 모든 분기문에서 조건 점프(초록색 화살표 이동)하여, 우측 하단으로 차례 이동

3. byte 및 배열 정리

첫 번째 조건문

byte_804A021의 값과 31h 비교

 

두 번째 조건문

byte_804A020을 eax에 저장하여,

첫 번째 문자(eax 내)와 0x34 XOR 연산

 

세 번째 문자(byte_804A022)와 0x32 XOR 연산

네 번째 문자(byte_804A023)와 0x0FFFFFF88 XOR 연산

다섯 번째 문자(byte_804A024)와 0x58 값이 같은지 비교

 

네 번째 조건문

테스트

 

네 번째 조건문

세번째 문자(byte_804A022)와 0x7C 비교

 

다섯 번째 조건문

첫번째 문자(byte_804A020)와 0x78 비교

 

여섯 번째 조건문

네번째 문자(byte_804A023)와 0x0DD 비교

No. CODE XREF 어셈블리어 10진수 to 문자(ASCII) 순서
1 sub_804851B+2A↓p cmp     al, 31h 0x31 = 49, chr(49) = 1 byte_804A021
2 sub_8048451+C↑j
loc_8048469
xor     eax, 34h
xor     eax, 32h
xor     eax, 0FFFFFF88h
cmp     al, 58h
0x34 = 52, chr(52) = 4
0x32 = 50, chr(50) = 2
0x88 = 136, chr(136) = (enter)
0x58 = 88, chr(88) = X
byte_804A020
byte_804A022
byte_804A023
byte_804A024
3 sub_8048451+4E↑j
loc_80484A8
test     al, al    
4 sub_8048451+60↑j
loc_80484BA
cmp     al, 7Ch 0x7C = 124, chr(124) = | byte_804A022
5 sub_8048451+72↑j
loc_80484CC
cmp     al, 78h 0x78 = 120, chr(120) = x byte_804A020
6 sub_8048451+84↑j
loc_80484DE
cmp     al, 0DDh 0xDD = 221, chr(221) = Ý byte_804A023

 

정리해보면, input 문자열은 다음과 같이 구성 (^: XOR)

input[0] ^ 34h = 78h

input[1] = 31h

input[2] ^ 32h = 7Ch

input[3] ^ 88h = DDh (byte이므로 88 앞의 FFFFFF는 무시)

input[4] = 58h

input[5]는 test(세 번째 조건문)

4. 소스코드 작성(어셈블리어 기반)

// string
ans = ""

ans += chr(0x34 ^ 0x78)
ans += chr(0x31)
ans += chr(0x32 ^ 0x7C)
ans += chr(0x88 ^ 0xDD)
ans += chr(0x58)

print(ans)

 

출력: L1NUX

Correct! 정답 출력

 

 

728x90
728x90
728x90
반응형
개요
* Easy_CrackMe.exe 실습 리뷰 및 Easy_KeygenMe.exe 파일 실습
1. 디스어셈블리 상세 기능
- 스택 프레임 및 함수 호출 규약의 이해
- 동적 디버깅 사용 및 코드 실행
- 데이터 타입과 데이터 구조
- 기본 데이터/코드 변환
2. 스택/힙 할당 배열 및 구조체 접근

목차
0. Easy KeygenMe 실습
1. 어셈블리어: MOV, CMP, XOR, MOVZX, MOVSX
2. 알고리즘 분석
3. XOR(⊕) 연산의 결합법칙
4. 소스코드 작성(pseudo code 기반)

[Review] (3주차) 실습

2022.07.04 - [IDA Pro] - IDA Pro 악성코드 정적분석 툴 사용법&실습 - week.03(Easy_CrackMe) (2)

 

IDA Pro 악성코드 정적분석 툴 사용법&실습 - week.03(Easy_CrackMe) (2)

개요 * Easy_CrackMe.exe 실습 리뷰 및 Easy_KeygenMe.exe 파일 실습 1. 디스어셈블리 상세 기능 - 스택 프레임 및 함수 호출 규약의 이해 - 동적 디버깅 사용 및 코드 실행 - 데이터 타입과 데이터 구조 - 기

sarahee.tistory.com


0. Easy KeygenMe 실습

Intro

Find the Name when the Serial is 5B134977135E7D13

Name을 사용해서 시리얼 값 생성, 역으로 시리얼 값을 통해 해당 Name을 찾아내는 문제

초기 디스어셈블리 창
debug Running page
Input Name, Input Serial

시리얼 생성 알고리즘과 관련된 문제 풀이

1) 어셈블리어로 전체적인 구조 파악

2) Hex-rays로 세부 알고리즘 파악

rep stosd: 저장소 문자열 명령

stosb: AL로부터 byte를 읽어 들임, stosw: AX로부터 word를 읽어 들임 - 정수값을 메모리에 복사


1. 어셈블리어: MOV, CMP, XOR, MOVZX, MOVSX

MOV

데이터 복사 명령어

0x10: [esp+140h+var_130]

0x20: [esp+140h+var_12F]

0x30: [esp+140h+var_12E]

Byte 단위로 각각 스택에 넣어줌, 사용자가 입력한 문자열을 첫번째 글자부터 순서대로 Byte 단위로 레지스터에 넣음

CMP

esi가 3 이상이면 0으로 초기화

XOR

두 입력 신호가 서로 같으면 0, 다르면 1, 동일한 두 값초기화

MOVZX

소스의 내용을 목적지로 복사, 목적지의 나머지 부분을 0 padding

(목적지에 32bit register 소스에 16bit register) 

MOVSX

소스의 내용을 목적지로 복사, 목적지의 나머지 부분을 소스의 맨 처음 bit로 채움

(목적지에 32bit register → 소스에 16bit register)

loc_40107E: pseudocode


2. 알고리즘 분석

1) v3이 v8의 strlen이 클 때 까지 반복하고, i가 3 이상이면 0으로 초기화

2) sprintf를 통해 Buffer에 생성된 serial 저장

3) "%s%02X"를 통해 기존 Buffer 내용과 v8 포인터 입력값을 한글자씩 가져옴

4) xor 연산을 한 값을 sprintf 함수를 통해 serial이 저장되는 Buffer에 저장

5) serial을 계산하여 scanf로 입력받은 후, strcmp 함수로 동일한지 비교

- if 0일 때 거짓, 0이 아닐 때 참으로 동작하므로, strcmp 내 0일 경우(문자열이 같을 경우) Correct 출력

 

v6에는 16 16 = 0x10

v7[i - 1]가 될 수 있는 값은, v7[0], v7[1], v7[2]의 반복

qmemcpy: sizeof(v7)만큼 " 0" 영역의 값을 v7로 복사

첫번째 인자(v7): 복사받을 메모리를 가리킴

두번째 인자(" 0"): 복사할 메모리를 가리킴

세번째 인자(sizeof(v7)): 복사할 데이터(값)의 길이(바이트 단위)

 

16진수이므로 두자리씩 끊어서 총 8자리


3. XOR(⊕) 연산의 결합법칙

^: XOR 연산자

p q p ⊕ q (p ⊕ q) ⊕ q
T T F T
T F T T
F T T F
F F F F

(p ⊕ q) ⊕ q ≡ p ⊕ (q ⊕ q) ≡ p ⊕ F ≡ p

 

0x5b^0x10

0x13^0x20

0x49^0x30

0x77^0x10

0x13^0x20

0x5E^0x30

0x7D^0x10

0x13^0x20


4. 소스코드 작성(pseudo code 기반)

# sol1

serial = [0x5B, 0x13, 0x49, 0x77, 0x13, 0x5E, 0x7D, 0x13]
xor = [0x10, 0x20, 0x30]
ans = []

i_xor = 0
for i_ser in range(len(serial)):
    if i_xor >= 3:
        i_xor = 0
    ans.append(serial[i_ser]^xor[i_xor])
    i_xor += 1
    print(chr(ans[i_ser]), end='')

# sol2

serial = [0x5B, 0x13, 0x49, 0x77, 0x13, 0x5E, 0x7D, 0x13]
xor = [0x10, 0x20, 0x30]
ans = []

for i in range(len(serial)):
    ans.append(serial[i]^xor[i%3])
    print(chr(ans[i]), end='')

출력: K3yg3nm3

75 51 121 103 51 110 109 51

Name: K3yg3nm3 / Serial: 5B134977135E7D13

결과값 출력도 전에 창이 닫혀서, cmd로 다시..

Correct!


[Next] (4주차) 이론

2022.07.19 - [Security & Analysis/IDA Pro] - IDA Pro 악성코드 정적분석 툴 사용법&이론 - week.04(전 과정 Review)

 

IDA Pro 악성코드 정적분석 툴 사용법&이론 - week.04(전 과정 Review)

개요 * Easy_KeygenMe.exe 파일 실습 1. 레지스터 활용 분석 - 메모리 주소 및 스택 프레임의 이해 - ESP(스택 포인터), EBP(프레임 포인터), EIP 등 개념 정리 2. 어셈블리 명령어 이해 및 알고리즘 분석 - Pse

sarahee.tistory.com

 

728x90
728x90

+ Recent posts