crackme0x00
패스워드를 찾는 문제.
일단 포함된 문자열을 찾아봤다.
"Password: " 다음 누가봐도 비밀번호일 것 같은 숫자가 있었다.
crackme0x01
비슷한 문제다. 바로 전 문제처럼 문자열을 찾아봤지만 그렇다할 단서는 찾지 못했다.
심볼 트리 탭에서 _main 함수를 선택하니 디컴파일 탭에서 비밀번호를 찾았다.
13번째 라인에서 0x149a와 local_8 변수를 비교하는데 맞으면 OK!
어셈블 코드는 이랬다..
5274를 넣어보자ㅏ
crackme0x02
0x01과 같은 문제다.
0x52b24 = 338724
crackme0x03
디컴파일러는 참 좋은 도구이다..
0x52b24 = 338724
crackme0x04
?.. 의도치 않게 풀어버렸다
일단 디컴파일된 코드를 보자
디컴파일된 코드를 좀 더 알기 쉽게 변수 명을 임의로 바꾸어 봤다.
int __cdecl _main(int _Argc,char **_Argv,char **_Env){
size_t a0; //a0 = local_a0
char s[120]; //s = local_7c
__alloca(a0);
___main();
_printf("IOLI Crackme Level 0x04\n");
_printf("Password: ");
_scanf("%s",s);
_check(s);
return 0;
}
s를 패스워드 인자로 받아 check 함수를 실행한다. check()는 아래와 같다.
void __cdecl _check(char *s){ //s = param_1
size_t var; //var = sVar1
char str; //str = local_11
uint a; //a = local_10
int m; //m = local_c
int n; //n = local_8
m = 0;
a = 0;
while(1) {
var = _strlen(s); //var은 인자로 받은 s의 길이
if (var <= a) {
_printf("Password Incorrect!\n");
return;
}
str = s[a]; //str은 입력값의 첫 글자(첫 루프)
_sscanf(&str,"%d",&n);
m = m + n;
if (m == 15) break; /m과 15가 같으면 OK
a = a + 1; //a에 1 더함 = 입력값의 다음 글자를 str에 저장
}
_printf("Password OK!\n");
/* WARNING: Subroutine does not return */
_exit(0);
}
결국 check()는 인자로 받은 숫자의 각 자리수 합이 15면 되는 거다
12345의 각 자리 합이 15라서 ok가 떴던 것..
그럼 555도 되겠져?
crackme0x05
역시 디컴파일된 main 함수, check 함수를 보자.
변수명이 보기 어려우니까 쉽게~
int __cdecl _main(int _Argc,char **_Argv,char **_Env){
size_t a0; //a0 = local_a0
char 7c[120]; //7c = local_7c
__alloca(a0);
___main();
_printf("IOLI Crackme Level 0x05\n");
_printf("Password: ");
_scanf("%s",7c);
_check(7c);
return 0;
}
0x04처럼 7c를 인자로 받아 check() 함수를 실행한다.
void __cdecl _check(char 7c){ //7c = *param_1
size_t var; //var = sVar1
char s; //s = local_11
uint a; //a = local_10
int m; //m = local_c
int n; //n = local_8
m = 0;
a = 0;
while(1){
var = _strlen(7c);
if (var <= a)
break;
s = 7c[a];
_sscanf(&s,"%d",&n);
m = m + n;
if (m == 16) {
_parell(7c);
}
a = a + 1;
}
_printf("Password Incorrect!\n");
return;
}
앞선 0X04랑 같은 알고리즘인 것 같다. 그대신 각 자리 수 합이 15가 아니라 16이어야 한다.
잘 보면 OK 프린트 문이 없는데 _parell() 함수에서 실행되는 것 같다.
그럼 각 자리 수 합이 16이 되게 79를 입력해보자
이미 알다시피 비밀은 _parell()에 있다.
디컴파일된 코드를 보면 아주 간단하다.
if문을 봐야하는데 입력값과 1을 AND 연산하여 결과값이 0일 때 OK가 뜬다.
1과 AND 연산한다는 뜻은 마지막 비트가 1인지 판단하는 것, 간단히 말해서 짝수를 입력해야 한다는 뜻이다.
앞서 입력한 79는 각 자리 수 합이 16이지만 홀수였다.
따라서 790, 862, 952 등 짝수이면서 각 자리 수 합이 16인 수를 입력하면 될 듯 하다.
'Wargame > CTF' 카테고리의 다른 글
InCTF 2020 Forensics_Investigation (0) | 2020.08.02 |
---|---|
RACTF 2020: Dimensionless Loading, Disk Forensics Fun (0) | 2020.06.13 |
2020 AUCTF (2) | 2020.04.11 |
Codegate 2020 (1) | 2020.04.02 |
UTCTF 2020 Chatt with Bratt: Write-Up (0) | 2020.03.11 |