일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- reversing
- 해킹캠프
- 2021
- PYTHON
- vsCode
- 코드엔진
- 히공
- 워 게임
- reversing.kr
- 풀이
- c언어
- probgame
- 변수
- Basic
- write-up
- 리버싱
- 강의
- ctf
- 뭉뭉
- ShaktiCTF
- 파이썬
- write up
- 시탭
- hackingcamp
- 라업
- 드림핵
- 라이트업
- 라이트 업
- 리버스 엔지니어링
- web
히공
hackingcamp22CTF - Opps Enc! 본문
문제
please_analysis_me 파일의 main 함수다.
cypher_code가 굉장히 중요해 보였다.
여기서 get_key가 굉장히 중요해 보였다.
get_key의 리턴 값이 v7에 들어가는데 v7은 char형이다.
그러면 cypher_code에서는 어떠한 부분을 0x1C로 xor 한다고 볼 수 있다.
get_key 함수다.
어차피 char형이 들어가므로 1바이트만 들어간다.
0x1C가 v7에 들어간다. (리틀엔디안)
please_analysis_me는 elf 섹션 중 어느 곳을 암호화하는 것 같았다.
opps_I_cannot_execute파일을 ida로 열어준다.
코드가 이상하다. shift+f7을 눌러 섹션을 본다.
text를 0x1C로 xor 해줄꺼다.
0x1140~0x1AE5 부분 까지 해주면 된다.
shift + f2를 누르면 이 창이 나오는데
scripting language를 idc에서 python으로 바꿔주고
from idc_bc695 import *
xorkey = 0x1c
for i in range(0x1140, 0x1ae6):
PatchByte(i, Byte(i) ^ xorkey)
이 코드를 입력한 후 Run을 눌러준다.
뭔가 제대로 바뀌었다.
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbp
unsigned int v5; // [rsp-44h] [rbp-44h]
signed int i; // [rsp-40h] [rbp-40h]
signed int v7; // [rsp-3Ch] [rbp-3Ch]
signed int v8; // [rsp-38h] [rbp-38h]
signed int v9; // [rsp-34h] [rbp-34h]
signed int v10; // [rsp-30h] [rbp-30h]
signed int v11; // [rsp-2Ch] [rbp-2Ch]
signed int v12; // [rsp-28h] [rbp-28h]
char v13; // [rsp-24h] [rbp-24h]
signed int j; // [rsp-20h] [rbp-20h]
__int64 v15; // [rsp-10h] [rbp-10h]
__int64 v16; // [rsp-8h] [rbp-8h]
__asm { endbr64 }
v16 = v3;
sub_1120(stdin, 0LL, 2LL, 0LL);
sub_1120(stderr, 0LL, 2LL, 0LL);
sub_1120(stdout, 0LL, 2LL, 0LL);
v15 = sub_1110(36LL);
sub_10F0(v15, 0LL, 36LL);
sub_1100(1LL, 1LL, "Thank you unpack me !\\n", 22LL);
sub_1100(1LL, 1LL, "What is password?\\n", 18LL);
sub_1100(0LL, 0LL, v15, 36LL);
if ( (unsigned __int64)sub_10D0(v15) > 0x24 )
sub_1100(1LL, 1LL, "ERR!", 7LL);
v5 = 15;
for ( i = 0; i <= 4; ++i )
{
if ( (unsigned int)((__int64 (__fastcall *)(_QWORD, _QWORD, _QWORD))round1)(
byte_2008[i],
*(unsigned __int8 *)(i + v15),
v5) != 1 )
sub_1130(0xFFFFFFFFLL);
++v5;
}
if ( *(_BYTE *)(v15 + 5) != 123 )
sub_1130(0xFFFFFFFFLL);
v7 = 10;
v8 = 6;
while ( v8 <= 11 )
{
if ( (unsigned int)((__int64 (__fastcall *)(_QWORD, _QWORD, _QWORD))round2)(
byte_2008[v8],
*(unsigned __int8 *)(v8 + v15),
(unsigned int)(v7 + 3)) != 1 )
{
sub_10C0("WRONG");
sub_1130(0xFFFFFFFFLL);
}
++v8;
++v7;
}
v9 = 30;
v10 = 12;
while ( v10 <= 18 )
{
if ( (unsigned int)((__int64 (__fastcall *)(_QWORD, _QWORD, _QWORD))round3)(
byte_2008[v10],
*(unsigned __int8 *)(v10 + v15),
(unsigned int)(v9 - 8)) != 1 )
{
sub_10C0("WRONG");
sub_1130(0xFFFFFFFFLL);
}
++v10;
--v9;
}
v11 = -10;
v12 = 19;
while ( v12 <= 26 )
{
if ( (unsigned int)((__int64 (__fastcall *)(_QWORD, _QWORD, _QWORD))round4)(
byte_2008[v12],
*(unsigned __int8 *)(v12 + v15),
(unsigned int)(v11 + 2)) != 1 )
{
sub_10C0("WRONG");
sub_1130(0xFFFFFFFFLL);
}
++v12;
++v11;
}
v13 = 50;
for ( j = 27; j <= 33; ++j )
{
if ( (unsigned int)round5(v13 + 1, (__int64)&v16, byte_2008[j], *(_BYTE *)(j + v15)) != 1 )
{
sub_10C0("WRONG");
sub_1130(0xFFFFFFFFLL);
}
--v13;
}
if ( *(_BYTE *)(v15 + 34) == 125 )
sub_1100(1LL, 1LL, "GREAT!\\n", 8LL);
return 0;
}
메인 함수 코드다.
round1 함수에 들어가면 이상하게 뜬다.
함수 우클릭 후 create function을 누르면 헥스레이 사용이 가능해진다.
round1~5까지 전부 해주자.
int __cdecl main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbp
unsigned int v5; // [rsp-44h] [rbp-44h]
signed int i; // [rsp-40h] [rbp-40h]
signed int v7; // [rsp-3Ch] [rbp-3Ch]
signed int v8; // [rsp-38h] [rbp-38h]
signed int v9; // [rsp-34h] [rbp-34h]
signed int v10; // [rsp-30h] [rbp-30h]
signed int v11; // [rsp-2Ch] [rbp-2Ch]
signed int v12; // [rsp-28h] [rbp-28h]
char v13; // [rsp-24h] [rbp-24h]
signed int j; // [rsp-20h] [rbp-20h]
__int64 scanf_value; // [rsp-10h] [rbp-10h]
__int64 v16; // [rsp-8h] [rbp-8h]
__asm { endbr64 }
v16 = v3;
sub_1120(stdin, 0LL, 2LL, 0LL);
sub_1120(stderr, 0LL, 2LL, 0LL);
sub_1120(stdout, 0LL, 2LL, 0LL);
scanf_value = sub_1110(36LL);
sub_10F0();
printf_or_scanf(1LL, 1LL, "Thank you unpack me !\\n", 22LL);
printf_or_scanf(1LL, 1LL, "What is password?\\n", 18LL);
printf_or_scanf(0LL, 0LL, scanf_value, 36LL);
if ( (unsigned __int64)sub_10D0(scanf_value) > 0x24 )
printf_or_scanf(1LL, 1LL, "ERR!", 7LL);
v5 = 15;
for ( i = 0; i <= 4; ++i )
{
if ( (unsigned int)round1(byte_2008[i], *(unsigned __int8 *)(i + scanf_value), v5) != 1 )
sub_1130(0xFFFFFFFFLL);
++v5;
}
if ( *(_BYTE *)(scanf_value + 5) != 123 )
sub_1130(0xFFFFFFFFLL);
v7 = 10;
v8 = 6;
while ( v8 <= 11 )
{
if ( (unsigned int)round2(byte_2008[v8], *(unsigned __int8 *)(v8 + scanf_value), (unsigned int)(v7 + 3)) != 1 )
{
sub_10C0("WRONG");
sub_1130(0xFFFFFFFFLL);
}
++v8;
++v7;
}
v9 = 30;
v10 = 12;
while ( v10 <= 18 )
{
if ( (unsigned int)round3(byte_2008[v10], *(unsigned __int8 *)(v10 + scanf_value), (unsigned int)(v9 - 8)) != 1 )
{
sub_10C0("WRONG");
sub_1130(0xFFFFFFFFLL);
}
++v10;
--v9;
}
v11 = -10;
v12 = 19;
while ( v12 <= 26 )
{
if ( (unsigned int)round4(byte_2008[v12], *(unsigned __int8 *)(v12 + scanf_value), (unsigned int)(v11 + 2)) != 1 )
{
sub_10C0("WRONG");
sub_1130(0xFFFFFFFFLL);
}
++v12;
++v11;
}
v13 = 50;
for ( j = 27; j <= 33; ++j )
{
if ( (unsigned int)round5(v13 + 1, (__int64)&v16, byte_2008[j], *(_BYTE *)(j + scanf_value)) != 1 )
{
sub_10C0("WRONG");
sub_1130(0xFFFFFFFFLL);
}
--v13;
}
if ( *(_BYTE *)(scanf_value + 34) == 125 )
printf_or_scanf(1LL, 1LL, "GREAT!\\n", 8LL);
return 0;
}
코드를 예쁘게 정리했다.
round1부터 round5까진 비슷하다.
&v15-64+n_3977을 해준다.
&v15는 rbp-0x8이고
&v15-64 = rbp-0x48이다.
한 마디로
(BYTE *)&v7
로 사용한다는 것이다.
byte_2008 = [6, 0x11, 0x13, 0x1B, 2, 0x7B, 0x7E, 0x42, 0x38, 0x6E, 0x6B, 0x15, 0x31, 0x23, \\
0xA, 0x3F, 0x30, 0xF, 0x18, 0xD3, 0x98, 0xDE, 0xC8, 0xC6, 0xCC, 0xCE, 0xF4, 0x10, 5, 0x17, 0x15, 0x1E, 0x19, 0x26, 0
]
flag = ''
#HCAMP
v5 = [0x41,0x42,0x43,0x44,0x41]
v4 = 15
for i in range(5):
flag+=chr(v5[i]^byte_2008[i]^v4)
v4+=1
flag+='{'
#Wow__Y
v5 = [0x24,0x23, 0x40,0x21,0x25, 0x5e]
v6 = 10
for v7 in range(6,0xc):
flag += chr(v5[v7-6]^byte_2008[v7]^(v6+3))
v6+=1
#ou_are_
v8 = 30
v9 = 12
v5 = [0x48, 0x43, 0x41, 0x4d, 0x50, 0x7b, 0x57]
for v9 in range(12,18+1):
flag += chr(v5[v9-12]^byte_2008[v9]^(v8-8))
v8-=1
#l3arned_
v10 = 0xf6
v5 = [0x47,0x52,0x45,0x41,0x54,0x54,0x54,0x54]
for v11 in range(19,27):
flag += chr(v5[v11-19]^byte_2008[v11]^(v10+2))
v10 = (v10+1) & 0xff
#decdec_
v12 = 50
v5 = [0x47,0x52,0x45,0x41,0x54,0x54,0x54]
for j in range(27,34):
flag += chr(v5[j-27]^byte_2008[j]^(v12+1))
v12-=1
flag+='}'
print(flag)
# HCAMP{Wow__You_are_l3arned_decdec_}
파이썬으로 복호화 할 수 있다.
플래그 : HCAMP{Wow__You_are_l3arned_decdec_}
'write up > hackingcamp22CTF' 카테고리의 다른 글
hackingcamp22CTF - dvm-rev (0) | 2021.03.20 |
---|---|
hackingcamp22CTF - revtine (0) | 2021.03.20 |
hackingcamp22CTF - Demon Notepad (0) | 2021.03.20 |
hackingcamp22CTF - Do u know it? (0) | 2021.03.20 |