728x90
반응형
- 문제 페이지를 보면키 리버싱이라고 적혀있고, 힌트 2가지가 적혀있다.
- correct 함수가 호출될 수 있는 input 중 가장 짧은 것을 구하시오
- 이 문제는 프로그램이 실행되는 어떠한 시스템에서도 동일하게 풀려야합니다
- 문제와 함께 파일을 다운받을 수 있는 링크가 있다.
- 그러나 리버싱 프로그램에 파일을 올려보면 잘못된 PE 파일이라고 한다.
- IDA 에 파일을 올려서 확인했다.
- 프로그램 좌측에는 Functions - Function name 이 있다.
- Correct 함수를 더블클릭해서 트리구조로 확인했다.
- 코드를 보면 어떤 값과 0DEADBEEFh 가 같은지 비교하여 "Congratulation! you are good!” 문자열을 출력하는 구조인 것 같다.
- Ghidra를 사용하여 가장 먼저 main 함수를 확인해보았다.
- main 함수의 코드는 다음과 같다.
undefined4 main(int param_1,char **param_2,int param_3)
{
uint uVar1;
int iVar2;
size_t sVar3;
void *local_40;
undefined local_3a [30];
uint local_1c;
uint local_18;
int local_14;
memset(local_3a,0,0x1e);
if ((param_1 < 2) && (iVar2 = strcmp(*param_2,"./suninatas"), iVar2 == 0)) { //파일명이 suninatas인지 확인
for (local_14 = 0; *(int *)(param_3 + local_14 * 4) != 0; local_14 = local_14 + 1) {
for (local_18 = 0; uVar1 = local_18, sVar3 = strlen(*(char **)(param_3 + local_14 * 4)),
uVar1 < sVar3; local_18 = local_18 + 1) {
*(undefined *)(local_18 + *(int *)(param_3 + local_14 * 4)) = 0;
}
}
printf("Authenticate : ");
__isoc99_scanf(&DAT_080d9dd9,local_3a);
memset(input,0,0xc);
local_40 = (void *)0x0;
local_1c = Base64Decode(local_3a,&local_40); //입력한 값이 Base64로 인코딩되어있어야 함
if (local_1c < 0xd) { //local_lc의 길이가 13보다 작아야 함
memcpy(input,local_40,local_1c);
iVar2 = auth(local_1c); //auth() 함수 호출
if (iVar2 == 1) { //결과가 1일때 correct() 함수 호출
correct();
}
}
}
return 0;
}
- main 함수의 코드를 보다보면 auth() 함수가 존재한다. 해당 함수의 코드 내용은 다음과 같다.
- auth 함수는 입력받은 값을 md5 해시 함수를 통해서 변환하고, 이 값이 f87cd601aa7fedca99018a8be88eda34 라면 1을 리턴한다.
bool auth(size_t param_1)
{
int iVar1;
undefined local_18 [8];
char *local_10;
undefined auStack12 [8];
memcpy(auStack12,input,param_1);
local_10 = (char *)calc_md5(local_18,0xc); //입력받은 값 해싱
printf("hash : %s\n",local_10);
iVar1 = strcmp("f87cd601aa7fedca99018a8be88eda34",local_10); //값 비교(같으면 1(Correct() 함수 호출), 다르면 0 리턴)
return iVar1 == 0;
}
- Correct 함수의 코드는 다음과 같다.
void correct(void)
{
if (input._0_4_ == -0x21524111) { //input._0_4_ == input의 첫 4바이트, input의 첫 4바이트 값이 0x21524111(0xdeadbeef)와 같아야 함
puts("Congratulation! you are good!");
}
/* WARNING: Subroutine does not return */
_exit(0);
}
- 코드를 보아 인증 키를 얻기 위한 과정은 아래와 같이 정리가 된다.
- 파일의 이름은 suninatas 이어야 한다.
- 입력한 값의 길이는 12바이트여야 한다.
- 입력한 값은 Base64 인코딩이 되어있어야 한다.
- 입력한 값의 첫 4바이트는 0x21524111(0xdeadbeef) ⇒ ef be ad de(Little Endian) 이어야 한다.
- 위의 조건에 맞는 페이로드를 작성 후 값을 찾아보았다.
(python -c 'import base64;print base64.encodestring("\xef\xbe\xad\xde"+"\x5f\x92\x04\x08"+"\xec\xc9\x11\x08")'; cat) | ./suninatas
- \x5f\x92\x04\x08
- \xec\xc9\x11\x08
- 다운받은 파일 reversme는 suninatas로 파일명을 변경 후 페이로드를 실행한다.
- 바로 실행하면 아래와 같이 에러들이 뜨는데, 이 상황은 suninatas 파일에 권한만 주면 된다.
- 값이 나왔다.
- Authenticate : hash : b566fd21b3c26707e680c6e32f1d0f99 Congratulation! you are good!
- Authenticate 값만 확인하면 다음과 같다.
- Authenticate : 776t3l+SBAjsyREI
- 알아낸 776t3l+SBAjsyREI 값을 인증페이지에 입력 후 문제풀이에 성공했다.
- Authkey : 776t3l+SBAjsyREI
728x90
반응형