IDA 로드
주언진 심볼 파일(.pdb) 가 없기 때문에 아래 메시지 No 선택
다음과 같은 화면에서 F5키를 눌러 디컴파일 진행,
main 함수 부터 분석 시작
main 함수
main 함수 분석
- char형 배열 v4에 256개의 원소가 들어갈 수 있는 공간을 "스택"에 할당
=> malloc과 같은 할당이 아니기 때문에 힙이 아닌 스택에 공각 생성됨
- memset (v4, 0, sizeof(v4));
=> v4를 0으로 채움
- "Input : " 출력 후, v4에 256바이트의 문자열을 사용자에게 입력 받음
- sub_140001000 함수에 v4 인자를 주고, 반환값이 True 일 경우 "Correct" 출력
sub_140001000 함수
for문을 0x18 = 24회 반복하며, if 문 체크, if문 성립 시 0i64를 반환, 성립하지 않고 24회 for문 전부 순환 시 1i64반환.
여기서 0i64는 64비트의 정수 자료형에서 0을 의미 (32비트 정수 자료형의 경우 0으로 표기),
1i64는 64비트의 정수자료형에서 1을 의미
돌아가서 main 함수의 if 문을 살펴보면 unsigned int로 형변환해준 후, if문에 들어가 있는 것을 확인 할 수 있습니다.
그러나 True/False 여부에 영향을 미치지 않습니다.
해당 함수가 참이 되기 위해, if ( byte_140003000[i] != (i ^ *(unsigned __int8 *)(a1 + i)) + 2 * i ) 문은 24회의 for문 순환 할 동안 byte_140003000[i] = (i ^ *(unsigned __int8 *)(a1 + i)) + 2 * i ) 이 되어야 합니다.
byte_140003000 배열
49h, 60h, 67h, ... dup(0) 의 정보가 해당 배열이 가지고 있는 배열임
Hex view 사용 시 정렬된 값으로 확인 가능하며,
byte_140003000 이 선택된 상태에서 Shift+E 단축키 클릭 시 해당 데이터를 해석하기 간편한 형태로 익스포트 가능
hex string(spaced) 옵션으로 익스포트 한 후 bytes.fromhex 함수를 사용하여 bytes 형태로 다시 불러옴
역연산 수행
24바이트의 사용자 입력값이 a1일때, (i ^ *(unsigned __int8 *)(a1 + i)) + 2 * i ) 의 결과가 익스포트한 24바이트의 데이터와 일치하여 함
>> (unsigned __int8 *)(a1 + i)) 는 a1배열에서 i번째 위치에 있는 값을 가져오는 것 압니다.
1. a1은 배열의 시작 주소를 나타냅니다. 즉, 배열의 첫 번째 원소가 어디에 있는지 알려주는 기준점이죠.
2. i는 원하는 원소의 위치입니다. 배열의 첫 번째 원소에서부터 몇 번째 떨어져 있는지를 나타냅니다.
3. (unsigned __int8 *)는 이 주소를 가리키는 포인터의 타입을 unsigned __int8로 바꿉니다. unsigned __int8은 8비트 크기의 부호 없는 정수를 말하며, 여기서는 한 바이트를 의미합니다.
4. *(a1 + i)는 계산된 주소에서 실제 값을 읽어오라는 의미입니다. 즉, a1에서 i만큼 떨어진 곳에 있는 바이트 값을
가져옵니다.
이 모든 과정은 즉 a1[i] 이 됩니다.
(i^ a[i]) +2*i = data[i]
=> 이때 양변의 데이터 모두 8비트 정수 이기 때문에 오버플로우를 고려하여 256(2^8)으로 나눈 나머지를 저장하여야 함
i^a[i] = data[i] - 2*i
여기서 양쪽을 i로 XOR 연산해주면 a1[i] 값을 구할 수 있다.
data = bytes.fromhex("49 60 67 74 63 67 42 66 80 78 69 69 7B 99 6D 88 68 94 9F 8D 4D A5 9D 45 00 00 00 00 00 00 00 00")
#data = data[:24]
result = []
for i in range(24):
# i ^ a1[i] + 2 * i == data[i]
tmp = data[i] - 2 * i
tmp = tmp % 256
# i ^ a1[i] = tmp
a1_i = tmp ^ i
result.append(a1_i)
result = bytes(result)
print(result)
'Hacking > DreamHack' 카테고리의 다른 글
no mov (1) | 2024.04.24 |
---|---|
uaf_overwrite (1) | 2024.04.09 |
What-is-my-ip(5Round CTF) (0) | 2024.03.30 |
02/24 CTF (0) | 2024.02.24 |
Dreamhack CTF Season 5 Round #3 (Self-deception) (0) | 2024.02.15 |