일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- adb
- 자바스크립트 강의
- 리버싱 스터디
- 더오름
- 자바스크립트 강의 추천
- 안드로이드 adb
- 안드로이드 모바일 앱 모의해킹
- 자바스크립트강의 후기
- rev-basic 풀이
- 인프런 강의 추천
- 제주코딩베이스캠프
- 드림핵 리버싱 풀이
- 위니브
- 안드로이드 리버싱
- adb 옵션
- 리버싱
- 리버싱 플래그
- 티스토리챌린지
- 리버싱 핵심 원리
- 드림핵 플래그
- 강의 체험단 1기
- 안드로이드 adb start-server
- dreamhack reversing
- 오블완
- 드림핵 리버싱
- 자바스크립트
- 리버싱 초보
- 리버싱핵심원리
- 제주ICT
- 리버싱 입문
- Today
- Total
해보자고
[드림핵]rev-basic-3 본문
# 문제
문제 링크 | https://dreamhack.io/wargame/challenges/17
이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다.
해당 바이너리를 분석하여 correct를 출력하는 입력값을 찾으세요!
1. main 함수 찾기
(main 함수를 찾는 방법 생략. 이전 글들 참고)
2. 실행 흐름 파악하기
rev-basic 시리즈들과 마찬가지로 test eax eax로 eax값이 0인지 확인하고, 0이면 je 명령어로 cha113.7FF6177c1186 로 이동해 wrong이 출력되고, 0이 아닌 값이면 correct가 출력된다.
중요한 분기점이 되는 함수는 test 이전에 불려진 cha113.7FF6177c1000임으로 살펴본다.
3. 디버깅
해당 함수는 반복문임을 알 수 있는데 cmp rax, 18에서 rax와 0x18을 비교해서 같으면 jae가 실행되어 거진 함수가 종료된다. rax는 아마 반복문의 횟수를 카운트하는 변수임을 짐작할 수 있고, inc eax에서 eax의 값을 반복횟수마다 1씩 증가시켜주는 것을 확인할 수 있다.
또한, 한 줄 한 줄 실행하다보면 RAX에는 lea 명령어를 통해 7FF668D23000 주소값이 들어가게 된다. 해당 주소값에 어떤 값이 저장되어 있는지를 확인해보면,, I'gtcgB~ 문자열이 저장되어 있다. 또한 우리가 Input으로 입력한 값은 RDX에 저장되어 있는 것도 레지스터 뷰를 통해 확인할 수 있다.
그러나 EAX와 EDX를 비교하여 계속해서 반복문으로 비교하는 것이 아니라 EAX와 ECX값을 비교하여 이에 따라 분기문이 달라지는 것을 확인할 수 있다. EAX와 ECX의 값을 어셈블리어를 통해 찾아보자.
어셈블리어에서 rsp는 eax의 값을 임시저장하거나, 저장하는 등 반복의 횟수를 0부터 담고 있다.
차례대로 rcx에 반복문의 횟수를 저장하고, rdx에는 input값이 저장되고 있다.
그 후 ecx에 input[[i] 값을 저장하고 횟수와 xor 연산을 진행한다.
횟수를 다시 edx에 저장하고, ecx에는 input[i]^i+i*2 가 저장된다.
기존의 저장된 값과 연산된 ecx를 비교해서 같으면 반복문을 계속해서 돌아가며 비교하지만 다르다면 rsp=24(0x18)로 설정한 후 바로 return 된다.
원래 input값을 구하는 코드를 짜보면 아래와 같다.
#include <stdio.h>
int main() {
char flag[24] = {0x49, 0x60, 0x67, 0x74, 0x63, 0x67, 0x42, 0x66, 0x80, 0x78, 0x69, 0x69,
0x7B, 0x99, 0x6D, 0x88, 0x68, 0x94, 0x9F, 0x8D, 0x4D, 0xA5, 0x9D, 0x45};
char org_flag[24] ={0};
for(int i =0; i < 23; i++) {
org_flag[i] = (flag[i] - 2*i) ^ i;
}
printf("flag is ");
for(int i = 0; i<23; i++) {
printf("%c", org_flag[i] );
}
}
'리버싱' 카테고리의 다른 글
[드림핵] rev-basic-6 (0) | 2024.05.06 |
---|---|
[리버싱] rev-basic-4 (0) | 2024.04.28 |
[드림핵]rev-basic-2 (0) | 2024.04.27 |
[크랙미 ] crackme1 (1) | 2024.04.21 |
[드림핵]rev-basic-1 (0) | 2024.04.12 |