# NotOsint (Reverse)
## Challenge

- Thử thách cho ta file `ELF 64`.
## Bước 1:
- Xem source code hàm `main` file bằng IDA.
```
__int64 __fastcall main(int a1, char **a2, char **a3)
{
int i; // [rsp+Ch] [rbp-134h]
_DWORD v5[24]; // [rsp+10h] [rbp-130h] BYREF
char s[200]; // [rsp+70h] [rbp-D0h] BYREF
unsigned __int64 v7; // [rsp+138h] [rbp-8h]
v7 = __readfsqword(0x28u);
sleep(1u);
puts("Alice: Hey Bob, I just found something cool");
sleep(1u);
puts("Bob: Huh?");
sleep(1u);
puts("Alice: PIS Club is inviting me to join. But I don't know what it is?");
sleep(1u);
puts("Bob: Hmm!!! Let me see.");
sleep(1u);
printf("Bob: PIS stands for: ");
sleep(1u);
fgets(s1, 100, stdin);
s1[strcspn(s1, "\n")] = 0;
sub_12A9(s1);
if ( !strcmp(s1, "PTITInformationSecurity") )
{
puts("Alice: Oh. I found it. I will contact them.");
sleep(1u);
puts("PIS bot: How can I help you?");
sleep(1u);
printf("PIS bot: Please enter the captcha code to verify you are human: ");
sleep(1u);
for ( i = 0; i <= 22; ++i )
__isoc99_scanf("%d", &v5[i]);
if ( sub_1649(v5) )
{
puts("The application for joining has been submitted. Please wait for the results from admin!!!");
sleep(1u);
sub_16F8(&unk_4020, s);
puts(s);
}
else
{
puts("Verification failed. Please try again later!!!");
sleep(1u);
}
}
else
{
puts(
"It seems that something is not right. Admin gives me information that its template is 'XXXX Xxxxxxxxxxx Xxxxxxxx'");
sleep(1u);
puts("Let's check again!!!");
}
return 0LL;
}
```
## Bước 2:
```
fgets(s1, 100, stdin);
s1[strcspn(s1, "\n")] = 0;
sub_12A9(s1);
if ( !strcmp(s1, "PTITInformationSecurity") )
```
- Tại đoạn này chương trình yêu cầu chúng ta nhập vào `s1` một chuỗi ký tự và so sánh chuỗi `s1` có giống với chuỗi ký tự `PTITInformationSecurity` hay không nếu khác chương trình sẽ thoát.
## Bước 3:
```
for ( i = 0; i <= 22; ++i )
__isoc99_scanf("%d", &v5[i]);
if ( sub_1649(v5) )
{
puts("The application for joining has been submitted. Please wait for the results from admin!!!");
sleep(1u);
sub_16F8(&unk_4020, s);
puts(s);
}
else
{
puts("Verification failed. Please try again later!!!");
sleep(1u);
}
}
else
{
puts(
"It seems that something is not right. Admin gives me information that its template is 'XXXX Xxxxxxxxxxx Xxxxxxxx'");
sleep(1u);
puts("Let's check again!!!");
}
```
- Phân tích đoạn code này ta thấy chương trình sẽ kiểm tra 23 số nhập từ bàn phím tại hàm `sub_1649(v5)` nếu 23 số này phù hợp thì chương trình sẽ trả Flag cho chúng ta.
## Phương pháp:
### Cách 1:
- Chúng ta sẽ sửa lại điều kiện tại hàm `sub_1649(v5)` `!=` sang `==`.
```
__int64 __fastcall sub_1649(__int64 a1)
{
int i; // [rsp+14h] [rbp-1Ch]
char v3[9]; // [rsp+1Fh] [rbp-11h] BYREF
unsigned __int64 v4; // [rsp+28h] [rbp-8h]
v4 = __readfsqword(0x28u);
for ( i = 0; i <= 22; ++i )
{
sub_1387(*(4LL * i + a1), v3);
sub_152F(v3);
if ( sub_14CB(v3) != dword_4020[i] )
return 0LL;
}
return 1LL;
}
```

- Chọn vào hàm bool và chuyển sang ngôn ngữ Assembly.

- Chuyển `jz` sang `jnz` sau đó lưu lại.
- 
- Bây giờ điều kiện đã thành `==` ta có thể nhập bất kỳ 23 chữ số để ra flag.
### Cách 2:
- Chúng ta vào hàm `sub_1649(v5)` .
- 
```
sub_1387(*(4LL * i + a1), v3);
```
- Vào hàm này để xem tác dụng của nó.
```
size_t __fastcall sub_1387(int a1, char *a2)
{
int v2; // eax
size_t result; // rax
char v5; // [rsp+1Fh] [rbp-11h]
int v6; // [rsp+20h] [rbp-10h]
int i; // [rsp+24h] [rbp-Ch]
int j; // [rsp+28h] [rbp-8h]
int v9; // [rsp+2Ch] [rbp-4h]
v6 = 0;
while ( a1 > 0 )
{
v2 = v6++;
a2[v2] = a1 % 2 + 48;
a1 /= 2;
}
a2[v6] = 0;
v9 = strlen(a2);
for ( i = 0; i < v9 / 2; ++i )
{
v5 = a2[i];
a2[i] = a2[v9 - i - 1];
a2[v9 - i - 1] = v5;
}
while ( 1 )
{
result = strlen(a2);
if ( result > 7 )
break;
for ( j = strlen(a2); j >= 0; --j )
a2[j + 1] = a2[j];
*a2 = 48;
}
return result;
}
```
- Hàm này có chức năng chuyển số nhập từ bàn sang hệ nhị phân, nếu chưa đủ 8bit thì đoạn mã sau sẽ bổ sung bit 0 để đủ 8 bit.
```
while ( 1 )
{
result = strlen(a2);
if ( result > 7 )
break;
for ( j = strlen(a2); j >= 0; --j )
a2[j + 1] = a2[j];
*a2 = '0';
}
return result;
```
- Tiếp tục xem source của hàm `sub_152F(v3)`.
```
__int64 __fastcall sub_152F(const char *a1)
{
__int64 result; // rax
char v2; // [rsp+17h] [rbp-9h]
int i; // [rsp+18h] [rbp-8h]
int v4; // [rsp+1Ch] [rbp-4h]
v4 = strlen(a1);
for ( i = 0; ; ++i )
{
result = (v4 / 2);
if ( i >= result )
break;
v2 = a1[i];
a1[i] = a1[v4 - i - 1];
a1[v4 - i - 1] = v2;
}
return result;
}
```
- Hàm này có chức năng lật ngược bit của các số.
- Trở lại hàm `if ( sub_14CB(v3) != dword_4020[i] )
return 0LL;
}
return 1LL;`
- Vào hàm `sub_14CB(v3)`.
```
__int64 __fastcall sub_14CB(const char *a1)
{
unsigned int v2; // [rsp+10h] [rbp-10h]
int v3; // [rsp+14h] [rbp-Ch]
int i; // [rsp+18h] [rbp-8h]
v2 = 0;
v3 = 1;
for ( i = strlen(a1) - 1; i >= 0; --i )
{
if ( a1[i] == 49 )
v2 += v3;
v3 *= 2;
}
return v2;
}
```
- Hàm này có chức năng trả các giá trị nhị phân sau khi đổi về giá trị DEC.
- Để chương trình trả về true. Thì ta phải nhập 23 số hệ DEC sao cho khi thực hiện các hàm trên bằng với giá trị cho trước trong hàm `dword_4020[i]`.
- 