dreamhack.io/wargame/challenges/17/
rev-basic-3
Reversing Basic Challenge #3 이 문제는 사용자에게 문자열 입력을 받아 정해진 방법으로 입력값을 검증하여 correct 또는 wrong을 출력하는 프로그램이 주어집니다. 해당 바이너리를 분석하여 correct를 출
dreamhack.io
참이면 "Correct"를 반대면 "Wrong"을 반환한다고 한다.
◾ 일단 실행부터 해보자
키값 인증 문제다, 여기서 알 수 있는 것은 비교문이 쓰일 것!
◾ 프로그램 정보 확인
컴파일러 종류가 어셈블러이고 코드가 직관적일 것으로 보임
◾ 문자열 검색을 통해 메인 함수를 찾아보자
◾ Correct로 가기 위해 점프 문(노란색)에서 wrong으로 분기되지 않게 한다.
그 말은 즉슨 바로 위의 함수의 반환 값이 1이 되어야 함을 뜻한다(0일 때, ZF=1 따라서 wrong으로 분기됨)
함수로 들어가 보자!
◾ 네, 24번 반복하는데 조건이 있겠죠? 살펴보죠
◾ 저는 "pingu"라고 입력했고, 3000 주소(노란색)에는 I`gtcgBf..... 값이 들어있네요.
두 값을 비교할 텐데 한 바이트씩 가져와서 비교할 예정입니다. 자세히 보면 그냥 비교하지 않죠?
xor와 +연산을 수행한 결과를 비교합니다.
◾ 첫 번째 반복문에서 i=0, rsp에 저장됨
1) ecx = "p"
2) p xor 0
3) edx = 0
3) ecx = ("p"+0)
최종 ecx값을 기존 문자열에 첫 문자 I와 비교합니다
다른 문자다 그럼 for문을 빠져나가고 동일 문자이면 다음 반복문을 수행합니다~
◾ 두 번째 반복문에서 i=1
1) ecx = "i"
2) p xor 1
3) edx = 1
3) ecx = ("i"+2)
총 24번 반복합니다
◾ input을 I라고 입력해보니 동일한 문자라고 하네요 반복문 수행~
나머지 값들도 xor, +연산 조건을 충족하게 만들어봅시다.
#include "stdio.h"
int main(int argc, char* argv[])
{
//I`gtcgBf.xii{.m.h...M¥.E의 아스키코드값
int arry[24] = { 73, 96, 103, 116, 99, 103, 66, 102, 128, 120, 105, 105, 123, 153, 109, 136, 104, 148, 159, 141, 77, 165, 157, 69 };
for (int i = 0; i < 24; i++) { //24번 반복
for (int n = 0; n < 128; n++) { //아스키코드 0~127 중 조건에 맞는 값 찾기
if ( (n xor i) + 2*i == arry[i]) {
printf("Hex : %x\tDex : %d\tAski : %c\n", n, n, n);
//printf("%c",n); //한줄로
break;
}
}
}
return 0;
}
◾ 결괏값을 넣어보니 최초의 목적이었던 함수 반환 값이 1이 되었고 따라서 ZF에 0이 세팅되었습니다.
Correct로 진입 성공!
마무리
이번 예제를 통해 xor연산 방식과 for문에서 i가 어셈블리어에서 어떻게 구현되는지 알 수 있었습니다 :)