파일을 IDA로 열면 오류가 발생한다. syms2elf 플러그인을 다운로드 받아서 실행하면 symbol 오류가 사라지고 아래와 같이 디컴파일 가능하다.
__int64 __fastcall sub_87C(char *a1, const char *a2)
{
char v3; // dl
size_t v4; // rax
char *v5; // [rsp+8h] [rbp-68h]
char v6[32]; // [rsp+10h] [rbp-60h] BYREF
char v7[24]; // [rsp+30h] [rbp-40h] BYREF
int v8; // [rsp+48h] [rbp-28h]
int v9; // [rsp+50h] [rbp-20h]
int v10; // [rsp+54h] [rbp-1Ch]
int v11; // [rsp+58h] [rbp-18h]
int i; // [rsp+5Ch] [rbp-14h]
v5 = a1;
v11 = 0;
v10 = 0;
strcpy(v7, "1617181926381617919194");
if ( strlen(a2) != 22 )
return 0LL;
for ( i = 0; i < strlen(v5); ++i )
v11 += v5[i];
v8 = 0;
v11 /= 30;
while ( v10 != 22 )
{
if ( (v10 & 1) != 0 )
v3 = a2[v10] - 4;
else
v3 = a2[v10] + 4;
v6[v10] = v3;
v6[v10++] ^= v11;
}
v9 = 0;
for ( i = strlen(v6) - 1; i >= 0; --i )
{
v4 = strlen(v6);
if ( v6[v4 - i - 1] != v7[i] )
return 0LL;
}
return 1LL;
}
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *s1; // [rsp+20h] [rbp-10h]
s1 = getenv("team_name");
if ( s1 && !strncmp(s1, "bi0s", 4uLL) )
{
if ( argc == 2 )
{
if ( (unsigned int)sub_87C(s1, argv[1]) == 1 )
sub_830(argv[1]);
else
printf("Better luck next time!");
}
else
{
printf("usage: chall <input>");
}
}
else
{
printf("Nope.");
}
return 0;
}
코드를 살펴보면 (unsigned int)sub_87C(s1, argv[1]) == 1) 라는 조건이 참이면 플래그가 출력되는 것을 예상할 수 있다. sub_87C(s1, argv[1])의 결과가 1이면 된다. 해당 함수를 거꾸로 역연산하면 첫번째로 아래 코드를 역연산해야한다.
for ( i = strlen(v6) - 1; i >= 0; --i )
{
v4 = strlen(v6);
if ( v6[v4 - i - 1] != v7[i] )
return 0LL;
}
해당 연산은 간단하게 한번 더 하면 역연산 가능하다. 즉, 1617181926381617919194을 거꾸로 뒤집으면 원래 상태가 된다.
-> 4919197161836291817161
다음으로 역연산해야 할 코드는 아래와 같다.
while ( v10 != 22 )
{
if ( (v10 & 1) != 0 )
v3 = a2[v10] - 4;
else
v3 = a2[v10] + 4;
v6[v10] = v3;
v6[v10++] ^= v11;
}
v11은 계산하면 12인것을 알 수 있고 이진수로 111이다. 조금 더 보기 편하게 수정하겠다.
int i = 0
while ( i != 22 ){
if ( (i & 1) != 0 ) // 홀수면
result[i] = flag[i] - 4;
else // 짝수면
result[i] = flag[i] + 4;
result[i++] ^= 12; // 최종 result는 위에서 구한 4919197161836291817161
}
이제 역연산을 진행하면 xor을 한번 더 하면 원래 값이 되고 +4 -4를 해도 짝수 홀수는 변하지 않으므로 아래와 같이 파이썬 코드를 작성한다.
result='4919197161836291817161'
flag=''
for i in range(22):
if(i % 2==0):
flag+=chr((ord(result[i])^12) - 4)
else:
flag+=chr((ord(result[i])^12) + 4)
print(flag)
결과는 아래와 같다. 처음에 여기서 아스키코드 변환이랑 여러가지를 해보았지만 해결되지않았다. 찾아보니 그냥 아래 값이 플래그였다....
4999997A6A0C6B1A0A7A6A
'Reversing > CTF' 카테고리의 다른 글
[HackCTF] Keygen (0) | 2021.10.09 |
---|---|
[HackCTF] Strncmp (0) | 2021.09.12 |
[HackCTF] Handray (0) | 2021.09.11 |
[HackCTF] Reversing Me (0) | 2021.09.10 |
[HackCTF] Welcome_REV (0) | 2021.09.10 |
댓글