攻防世界Reverse解题(一)
介绍:记录解题过程
1.insanity(winhex打开,搜索字符串flag)
题目描述:菜鸡觉得前面的题目太难了,来个简单的缓一下
题目场景: 暂无
题目附件: 附件1
- 下载附件1 得到一个无后缀文件
- 用winhex打开,搜索字符串flag
- 得到flag
9447{This_is_a_flag}
2.python-trade(反编译pyc文件,逆向加密算法)
题目描述:菜鸡和菜猫进行了一场Py交易
题目场景: 暂无
题目附件: 附件1
- 下载附件1 得到一个pyc文件
pyc文件反编译
Easy Python Decompiler反编译工具,pyc文件反编译得到:
# Embedded file name: 1.py
import base64
def encode(message):
s = ''
for i in message:
x = ord(i) ^ 32
x = x + 16
s += chr(x)
return base64.b64encode(s)
correct = 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt'
flag = ''
print('Input flag:')
flag = input()
if encode(flag) == correct:
print('correct')
else:
print('wrong')
- 逆向算法得到flag:
import base64
def uncode(message):
s = base64.b64decode(message)
b = ''
for x in s:
x = x - 16
x = x ^ 32
b += chr(x)
return b
correct = 'XlNkVmtUI1MgXWBZXCFeKY+AaXNt'
print('flag:', uncode(correct))
flag: nctf{d3c0mpil1n9_PyC}
3.re1(开始学习逆向工程)
题目描述:菜鸡开始学习逆向工程,首先是最简单的题目
题目场景: 暂无
题目附件: 附件1
下载附件1 得到一个exe文件
方法一:直接搜flag
- Notepad打开直接搜flag
DUTCTF{We1c0met0DUTCTF}
方法二:
- 参考:
攻防世界reverse:re1
<1>.查壳 - 无壳,32位程序
<2>拖入IDA
找到main函数
F5反编译
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
__m128i v5; // [esp+0h] [ebp-44h] BYREF
__int64 v6; // [esp+10h] [ebp-34h]
int v7; // [esp+18h] [ebp-2Ch]
__int16 v8; // [esp+1Ch] [ebp-28h]
char v9[32]; // [esp+20h] [ebp-24h] BYREF
v5 = _mm_loadu_si128((const __m128i *)&xmmword_413E34);
v7 = 0;
v6 = 0x7D465443545544i64;
v8 = 0;
printf("欢迎来到DUTCTF呦\n");
printf("这是一道很可爱很简单的逆向题呦\n");
printf("输入flag吧:");
scanf("%s", v9);
v3 = strcmp(v5.m128i_i8, v9);
if ( v3 )
v3 = v3 < 0 ? -1 : 1;
if ( v3 )
printf(aFlag_0);
else
printf(aFlagGet);
system("pause");
return 0;
}
由逻辑可知:
用户输入v9与v5比较,同则输出flag,所以flag在v5,跟踪v5
- 发现一串十六进制字符串,按R将其转化成字符串:
0tem0c1eW{FTCTUD
}FTCTUD
- flag出现,但要注意在x86处理器中字符是按照小端序储存的,即低位字节存入低地址,高位字节存入高地址
- 所以正确的flag应为
DUTCTF{We1c0met0DUTCTF}
4.game
题目描述:菜鸡最近迷上了玩游戏,但它总是赢不了,你可以帮他获胜吗
题目场景: 暂无
题目附件: 附件1
- 下载附件1 得到一个exe文件,是一个小游戏
|------------/ --------△--------|
|------------/ --------○--------|
|------------/ --------◇--------|
|------------/ --------□--------|
|--------------------|------------/ --------☆--------|
| |------------/ --------▽--------|
| |------------/ -----( ̄▽ ̄)/---|
| |------------/ -----(;°Д°)----|
二 |
| by 0x61 |
| |
|------------------------------------------------------|
Play a game
The n is the serial number of the lamp,and m is the state of the lamp
If m of the Nth lamp is 1,it's on ,if not it's off
At first all the lights were closed
Now you can input n to change its state
But you should pay attention to one thing,if you change the state of the Nth lamp,the state of (N-1)th and (N+1)th will be changed too
When all lamps are on,flag will appear
Now,input n
input n,n(1-8)
1.△ 2.○ 3.◇ 4.□ 5.☆ 6.▽ 7.( ̄▽ ̄)/ 8.(;°Д°) 0.restart
n=
方法一:直接通关
- 12345678
done!!! the flag is zsctf{T9is_tOpic_1s_v5ry_int7resting_b6t_others_are_n0t}
input n,n(1-8)
1.△ 2.○ 3.◇ 4.□ 5.☆ 6.▽ 7.( ̄▽ ̄)/ 8.(;°Д°) 0.restart
n=
方法二:逆向算法
<1>.PEiD查壳:
<2>.放入IDA
- main_0:
int __cdecl main_0(int argc, const char **argv, const char **envp)
{
char v4; // [esp+0h] [ebp-FCh]
char v5; // [esp+0h] [ebp-FCh]
char v6; // [esp+0h] [ebp-FCh]
char v7; // [esp+0h] [ebp-FCh]
char v8; // [esp+0h] [ebp-FCh]
char v9; // [esp+0h] [ebp-FCh]
char v10; // [esp+0h] [ebp-FCh]
char v11; // [esp+0h] [ebp-FCh]
char v12; // [esp+0h] [ebp-FCh]
char v13; // [esp+0h] [ebp-FCh]
char v14; // [esp+0h] [ebp-FCh]
char v15; // [esp+0h] [ebp-FCh]
char v16; // [esp+0h] [ebp-FCh]
char v17; // [esp+0h] [ebp-FCh]
char v18; // [esp+0h] [ebp-FCh]
char v19; // [esp+0h] [ebp-FCh]
char v20; // [esp+0h] [ebp-FCh]
char v21; // [esp+0h] [ebp-FCh]
char v22; // [esp+0h] [ebp-FCh]
char v23; // [esp+0h] [ebp-FCh]
int i; // [esp+DCh] [ebp-20h]
int v25; // [esp+F4h] [ebp-8h] BYREF
sub_45A7BE((int)&unk_50B110, v4);
sub_45A7BE((int)&unk_50B158, v5);
sub_45A7BE((int)&unk_50B1A0, v6);
sub_45A7BE((int)&unk_50B1E8, v7);
sub_45A7BE((int)&unk_50B230, v8);
sub_45A7BE((int)&unk_50B278, v9);
sub_45A7BE((int)&unk_50B2C0, v10);
sub_45A7BE((int)&unk_50B308, v11);
sub_45A7BE((int)"二 |\n", v12);
sub_45A7BE((int)"| by 0x61 |\n", v13);
sub_45A7BE((int)"| |\n", v14);
sub_45A7BE((int)"|------------------------------------------------------|\n", v15);
sub_45A7BE(
(int)"Play a game\n"
"The n is the serial number of the lamp,and m is the state of the lamp\n"
"If m of the Nth lamp is 1,it's on ,if not it's off\n"
"At first all the lights were closed\n",
v16);
sub_45A7BE((int)"Now you can input n to change its state\n", v17);
sub_45A7BE(
(int)"But you should pay attention to one thing,if you change the state of the Nth lamp,the state of (N-1)th and (N+1"
")th will be changed too\n",
v18);
sub_45A7BE((int)"When all lamps are on,flag will appear\n", v19);
sub_45A7BE((int)"Now,input n \n", v20);
while ( 1 )
{
while ( 1 )
{
sub_45A7BE((int)"input n,n(1-8)\n", v21);
sub_459418();
sub_45A7BE((int)"n=", v22);
sub_4596D4("%d", &v25);
sub_45A7BE((int)"\n", v23);
if ( v25 >= 0 && v25 <= 8 )
break;
sub_45A7BE((int)"sorry,n error,try again\n", v21);
}
if ( v25 )
{
sub_4576D6(v25 - 1);
}
else
{
for ( i = 0; i < 8; ++i )
{
if ( (unsigned int)i >= 9 )
j____report_rangecheckfailure();
byte_532E28[i] = 0;
}
}
j__system("CLS");
sub_458054();
if ( byte_532E28[0] == 1
&& byte_532E28[1] == 1
&& byte_532E28[2] == 1
&& byte_532E28[3] == 1
&& byte_532E28[4] == 1
&& byte_532E28[5] == 1
&& byte_532E28[6] == 1
&& byte_532E28[7] == 1 )
{
sub_457AB4();
}
}
}
- 成功后会执行
sub_457AB4();
- 跟踪:
int sub_45E940()
{
int i; // [esp+D0h] [ebp-94h]
char v2[22]; // [esp+DCh] [ebp-88h]
char v3[32]; // [esp+F2h] [ebp-72h] BYREF
char v4[4]; // [esp+112h] [ebp-52h] BYREF
char v5[64]; // [esp+120h] [ebp-44h]
sub_45A7BE("done!!! the flag is ");
v5[0] = 18;
v5[1] = 64;
v5[2] = 98;
v5[3] = 5;
v5[4] = 2;
v5[5] = 4;
v5[6] = 6;
v5[7] = 3;
v5[8] = 6;
v5[9] = 48;
v5[10] = 49;
v5[11] = 65;
v5[12] = 32;
v5[13] = 12;
v5[14] = 48;
v5[15] = 65;
v5[16] = 31;
v5[17] = 78;
v5[18] = 62;
v5[19] = 32;
v5[20] = 49;
v5[21] = 32;
v5[22] = 1;
v5[23] = 57;
v5[24] = 96;
v5[25] = 3;
v5[26] = 21;
v5[27] = 9;
v5[28] = 4;
v5[29] = 62;
v5[30] = 3;
v5[31] = 5;
v5[32] = 4;
v5[33] = 1;
v5[34] = 2;
v5[35] = 3;
v5[36] = 44;
v5[37] = 65;
v5[38] = 78;
v5[39] = 32;
v5[40] = 16;
v5[41] = 97;
v5[42] = 54;
v5[43] = 16;
v5[44] = 44;
v5[45] = 52;
v5[46] = 32;
v5[47] = 64;
v5[48] = 89;
v5[49] = 45;
v5[50] = 32;
v5[51] = 65;
v5[52] = 15;
v5[53] = 34;
v5[54] = 18;
v5[55] = 16;
v5[56] = 0;
v2[0] = 123;
v2[1] = 32;
v2[2] = 18;
v2[3] = 98;
v2[4] = 119;
v2[5] = 108;
v2[6] = 65;
v2[7] = 41;
v2[8] = 124;
v2[9] = 80;
v2[10] = 125;
v2[11] = 38;
v2[12] = 124;
v2[13] = 111;
v2[14] = 74;
v2[15] = 49;
v2[16] = 83;
v2[17] = 108;
v2[18] = 94;
v2[19] = 108;
v2[20] = 84;
v2[21] = 6;
qmemcpy(v3, "`S,yhn _uec{", 12);
v3[12] = 127;
v3[13] = 119;
v3[14] = 96;
v3[15] = 48;
v3[16] = 107;
v3[17] = 71;
v3[18] = 92;
v3[19] = 29;
v3[20] = 81;
v3[21] = 107;
v3[22] = 90;
v3[23] = 85;
v3[24] = 64;
v3[25] = 12;
v3[26] = 43;
v3[27] = 76;
v3[28] = 86;
v3[29] = 13;
v3[30] = 114;
v3[31] = 1;
strcpy(v4, "u~");
for ( i = 0; i < 56; ++i )
{
v2[i] ^= v5[i];
v2[i] ^= 0x13u;
}
return sub_45A7BE("%s\n");
}
- 修改代码输出flag:
zsctf{T9is_tOpic_1s_v5ry_int7resting_b6t_others_are_n0t}
方法三:修改程序逻辑:
- 修改前:
if ( byte_532E28[0] == 1
&& byte_532E28[1] == 1
&& byte_532E28[2] == 1
&& byte_532E28[3] == 1
&& byte_532E28[4] == 1
&& byte_532E28[5] == 1
&& byte_532E28[6] == 1
&& byte_532E28[7] == 1 )
-
jnz的机器码为75,只需将其改为jz的机器码74。修改方法:Edit/Patch program/Change byte(jnz->jz)
-
修改后:
if ( byte_532E28[0] == 1
&& byte_532E28[1] == 1
&& byte_532E28[2] == 1
&& byte_532E28[3] != 1
&& byte_532E28[4] != 1
&& byte_532E28[5] != 1
&& byte_532E28[6] != 1
&& byte_532E28[7] != 1 )
- 修改完后Edit/Patch program/Apply patches to input file保存修改后的文件,运行输个2得到flag:
done!!! the flag is zsctf{T9is_tOpic_1s_v5ry_int7resting_b6t_others_are_n0t}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/92716.html