盒子
盒子
文章目录
  1. Reverse
  2. 1.re4
  3. 2.xor
  4. 3.走后门
  5. 4.re06

Reverse-3

Reverse

1.re4

首先我们先点开运行试玩一下,大意就是让你输入正确的用户名和密码就能拿到flag,接下来进入正题。

tu1

丢进IDA中,先shift+F12查看一下字符串(我们所需要的correct name)

tu2

可以看见FindKey字样的字符串,以及别的一些看上去像flag的字样。我们进入主函数中查看

tu3

可以看见整个程序的大概的执行进程,加灰的那串字符串尤其得留意一下,可以先复制到剪贴板中留到以后使用,再进入findkey的函数中查看

tu4

粗略的看了一下,有相关的对比跳转函数,F5查看伪代码

tu5

是用c++写的程序,Str为输入的名字且长度为7,v5为输入的密码且长度为14,往后看,再将Str与FindKey做比较,如果正确的话就往well_done!的函数跳转,所以我们就可知道用户名就是FindKey,与密码相关联的函数存储在sub_401C00函数中,进入查看

tu6

函数很乱,大概的可以看到复制和字符连接函数以及比较函数,不过我们从前面主函数中他处于if函数中可以得知,只要返回值为1就可以,所以上面v5的值就应该为0,v10和v12的值就应该相等。分析到此就差不多了,我们直接进入程序来调试查看,F9调出进程,在比较函数处设置断点,输入的用户名为FindKey,且输入的密码应为14位

tu7

tu8

此时程序断在此处,F7单步运行var_D8就是我们输入的密码被转换过之后的值,而var_70则是我们输入的密码所要对比的值,当我们单步运行过后可以发现var_D8字符串中的字符被一个一个调用,调用一个就与var_70中相对应的字符作对比,我们可以点击var_D8进去看看他所赋的内存地址

tu9

我们可以看见我们原先打入的hellohelloworl这十四个字符串被转换成了上图中的二十个字符串,为什么给我们多加了6个?我们先不管,先看看var_70的内存地址

tu10

可以看到var_70也是二十个字符串,我们再看看之前的伪代码,那么就可以理解了,程序就是将你输入的十四位的密码先添上六个字符串,然后再和内存中的二十位密码作对比,如果一样,则正确,否则错误

tu11

上图就是所添加上六个字符串的地方的代码,sub_2012D0函数处Src给添上了v3,v2字符串。

所以我们将之前所记录下的内存中的二十长度字符串复制下来,在密码处输入前十四位,看看运行结果

tu12

运行成功,拿到flag!

2.xor

老步骤,打开程序看看,先运行一下,再查找字符串,看见key字样后点击进入主函数,查看伪代码,程序就是让你输入flag,输入正确就拿到key,错误则不行

tu14
tu13

随手加上注释,要拿到key,result的值要为0,则sub_40100A函数的值要为0,v4为输入的值,v3位输入的值得长度。进入sub_40100A函数查看一下

tu15

直接看汇编,要使返回值为0(即false),则strcmp对比函数的值为0,即var_10等于arg_0,var_10的值在上面,var_50先被赋值dword_42201C处的字符串,var_C,var_8,var_4也先后被写入422020,422024,422028处,而后又整体赋值给var_10,最后,var_10和arg_0做最终的对比然后返回,可以得知arg_0是我们所输入的值,所以只要我们所输入的值就是var_10,我们跳转到4220··的内存地址中去查看。

tu16

可以看到这就是var_10中所存储的字符串,根据大端存储原理(不懂得童鞋可以百度”大端,小端存储的区别”),我们把字符串一个个从后往前提取出来,写个转换ASCII码的转换小脚本,就可以拿到flag。(真有这么简单吗…)

tu17

tu18

用拿到的调试一下看看,结果并没有成功。。于是我又翻回去看,看看看看了很久,我才发现,原来上面的汇编中的strcmp是个函数!!!,call _strcmp。。是个自己写的函数!!!不是比较函数!!!!套路果然深。。然后再去看一看strcmp的函数怎么运行的

tu19

上面是strcmp的函数,有很多的跳转函数。。换成伪代码之后代码变得更长了。。算了,我们还是边运行边看看结果吧

随便输入几个字符

tu20

F7F8进行调试运行,得到var_88是我们所输入的值,调试过程中我们发现我们所输入的值变换了,变成了

tu21

这样我还是无法得出他是如何转换字符串的,那么我们就直接用上我们之前所解出来的那十二位字符串去运行,看看它会变成什么样的字符串

tu22

好了,这个必定是flag了,我们再把这个字符串输入进去试试看,能否得到成功的回应

tu23

getflag!!!(终于…)

3.走后门

这道题蛮简单的,打开运行之后就是让你输入正确的用户名和密码,密码就是flag。

tu24

再扔到IDA里面查看,直接查看各个主函数看看

tu25

可以直接看到用户名和密码…虽然密码被md5加密了,直接解码

tu26

得到密码

4.re06

老规矩,直接运行试试看,可是这次开头就没那么简单了,运行不了,会闪退,那么我们用cmd模式运行看看,结果提示参数错误…

tu27

说明这个PE文件有参数检查,我们file查看文件类型,得知是.NET编写的程序,那么我们就先在IDA上加上注释,再用Reflector反编译,两者结合起来用

Reflector分析:

f=”不正确” —-loc.2

i=”参数错误”—-loc.3

p=”?#? ?## ?#??#?##? ?# ?#?#?#? #?# ?#??# ?#?# “

L_0005 …….

L_000a stloc.0

L_0046 ldloc.0

L_0047 …….

L_004c ldc.i4.8

L_004d beq.s L_0056

检查参数个数是否是8个,相等则跳过输出“参数错误”

str6存放数字字符,逆序转为数字型时==0x145d526db9faad8,顺序十进制转换==00011110303731719

str6=”00011110303731719 “

由if(srt3!= str5.reverse()) jmp L_015a

str5为str3的逆序

str5=”nTTDffcttRcVrhRghFa “

p=”?#? ?## ?#??#?##? ?# ?#?#?#? #?# ?#??# ?#?# “

?处为字符,#处为数字

根据下面我在IDA中的注释,再得出?和#处的字母和数字,输入程序所缺少的参数,即可得到flag

tu30

拿到flag!

下面是部分注释:

tu28

tu29

所有注释 :

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
{

.custom instance void [mscorlib]System.STAThreadAttribute::.ctor()
.entrypoint
.maxstack 5
.locals init (
[0] class [mscorlib]System.Collections.ObjectModel.ReadOnlyCollection`1<string> onlys,
[1] uint64 num,
[2] string str,
[3] string str2,
[4] string str3,
[5] string[] strArray,
[6] string str4,
[7] string str5,
[8] string str6,
[9] int32 num2,
[10] int32 num3,
[11] int32 num4,
[12] int32 num5,
[13] char ch)
L_0000: call class chkflag.My.MyApplication chkflag.My.MyProject::get_Application()
L_0005: callvirt instance class [mscorlib]System.Collections.ObjectModel.ReadOnlyCollection`1<string> [Microsoft.VisualBasic]Microsoft.VisualBasic.ApplicationServices.ConsoleApplicationBase::get_CommandLineArgs()
L_000a: stloc.0 //onlys存储参数
L_000b: ldc.i8 0x145d526db9faad8
L_0014: stloc.1 //num=0x145d526db9faad8
L_0015: call class [mscorlib]System.Resources.ResourceManager chkflag.My.Resources.Resources::get_ResourceManager()
L_001a: ldstr "f"
L_001f: callvirt instance string [mscorlib]System.Resources.ResourceManager::GetString(string)
L_0024: stloc.2 //str="不正确"
L_0025: call class [mscorlib]System.Resources.ResourceManager chkflag.My.Resources.Resources::get_ResourceManager()
L_002a: ldstr "i"
L_002f: callvirt instance string [mscorlib]System.Resources.ResourceManager::GetString(string)
L_0034: stloc.3 //str2=“参数错误”
L_0035: call class chkflag.My.MyApplication chkflag.My.MyProject::get_Application()
L_003a: callvirt instance class [Microsoft.VisualBasic]Microsoft.VisualBasic.ApplicationServices.AssemblyInfo [Microsoft.VisualBasic]Microsoft.VisualBasic.ApplicationServices.ApplicationBase::get_Info()
L_003f: callvirt instance string [Microsoft.VisualBasic]Microsoft.VisualBasic.ApplicationServices.AssemblyInfo::get_Description()
L_0044: stloc.s str3 //str3存放Description信息

//.custom instance void [mscorlib]

System.Reflection.AssemblyDescriptionAttribute::.ctor(string) = { string('aFhgRhrVcRttcffDTTn') }

//str3="aFhgRhrVcRttcffDTTn"
L_0046: ldloc.0
L_0047: callvirt instance int32 [mscorlib]System.Collections.ObjectModel.ReadOnlyCollection`1<string>::get_Count()
L_004c: ldc.i4.8
L_004d: beq.s L_0056 //if(count==8) jmp L_0056
L_004f: ldloc.3
L_0050: call void [mscorlib]System.Console::WriteLine(string) //print "参数错误"
L_0055: ret
L_0056: call class [mscorlib]System.Resources.ResourceManager chkflag.My.Resources.Resources::get_ResourceManager()
L_005b: ldstr "p"
L_0060: callvirt instance string [mscorlib]System.Resources.ResourceManager::GetString(string)
L_0065: ldc.i4.1
L_0066: newarr char
L_006b: dup
L_006c: ldc.i4.0
L_006d: ldc.i4.s 0x20
L_006f: stelem.i2
L_0070: callvirt instance string[] [mscorlib]System.String::Split(char[])
L_0075: stloc.s strArray //char strArray[]=p
L_0077: ldloc.0
L_0078: callvirt instance int32 [mscorlib]System.Collections.ObjectModel.ReadOnlyCollection`1<string>::get_Count()
L_007d: ldc.i4.1
L_007e: sub.ovf
L_007f: stloc.s num2 //num2=len((onlys)-1
L_0081: ldc.i4.0
L_0082: stloc.s num3 //num3=0
L_0084: br.s L_00a8 //jmp L_00a8
L_0086: ldloc.0
L_0087: ldloc.s num3
L_0089: callvirt instance !0 [mscorlib]System.Collections.ObjectModel.ReadOnlyCollection`1<string>::get_Item(int32) //onlys[num3]
L_008e: ldloc.s strArray
L_0090: ldloc.s num3
L_0092: ldelem.ref
L_0093: ldc.i4.0
L_0094: call bool [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.LikeOperator::LikeString(string, string, valuetype [Microsoft.VisualBasic]Microsoft.VisualBasic.CompareMethod) //比较类型
L_0099: brtrue.s L_00a2
L_009b: ldloc.2
L_009c: call void [mscorlib]System.Console::WriteLine(string) //print "不正确"
L_00a1: ret
L_00a2: ldloc.s num3
L_00a4: ldc.i4.1
L_00a5: add.ovf
L_00a6: stloc.s num3 //num3+=1

L_00a8: ldloc.s num3
L_00aa: ldloc.s num2
L_00ac: ble.s L_0086 if(num3<=num2) jmp L_0086
L_00ae: ldstr ""
L_00b3: ldloc.0
L_00b4: call string [mscorlib]System.String::Join(string, class [mscorlib]System.Collections.Generic.IEnumerable`1<string>)
L_00b9: stloc.s str4
L_00bb: ldstr ""
L_00c0: stloc.s str5
L_00c2: ldstr ""
L_00c7: stloc.s str6
L_00c9: ldloc.s str4
L_00cb: callvirt instance int32 [mscorlib]System.String::get_Length()
L_00d0: ldc.i4.1
L_00d1: sub.ovf
L_00d2: stloc.s num4 //num4=len(str4)
L_00d4: ldc.i4.0
L_00d5: stloc.s num5 //num5=0
L_00d7: br.s L_0115 //jmp L_0115
L_00d9: ldloc.s str4
L_00db: ldloc.s num5
L_00dd: callvirt instance char [mscorlib]System.String::get_Chars(int32)
L_00e2: stloc.s ch //ch=str4[num5]
L_00e4: ldloc.s ch
L_00e6: call bool [mscorlib]System.Char::IsDigit(char)
L_00eb: brfalse.s L_00ff //if ch不是十进制数字 jmp L_00ff
L_00ed: ldloc.s str6
L_00ef: ldloc.s ch
L_00f1: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Conversions::ToString(char)
L_00f6: call string [mscorlib]System.String::Concat(string, string)
L_00fb: stloc.s str6 //str6存放数字元素
L_00fd: br.s L_010f
L_00ff: ldloc.s str5
L_0101: ldloc.s ch
L_0103: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Conversions::ToString(char)
L_0108: call string [mscorlib]System.String::Concat(string, string)
L_010d: stloc.s str5 //str5存放字符元素
L_010f: ldloc.s num5
L_0111: ldc.i4.1
L_0112: add.ovf
L_0113: stloc.s num5
L_0115: ldloc.s num5
L_0117: ldloc.s num4
L_0119: ble.s L_00d9 //if(num5<=num4) jmp L_00d9
L_011b: ldloc.s str6
L_011d: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::StrReverse(string)
L_0122: call uint64 [mscorlib]System.UInt64::Parse(string) //将字符型数据串转化为数字型
L_0127: ldloc.1
L_0128: bne.un.s L_015a //if(num!=int(str6)) num=91713730301111000
L_012a: ldloc.s str5
L_012c: call string [Microsoft.VisualBasic]Microsoft.VisualBasic.Strings::StrReverse(string) str5.reverse()
L_0131: ldloc.s str3
L_0133: callvirt instance bool [mscorlib]System.String::Equals(string)
L_0138: brfalse.s L_015a //if(srt3!= str5.reverse()) jmp L_015a
L_013a: ldstr "EIS{"
L_013f: ldstr "_"
L_0144: ldloc.0
L_0145: call string [mscorlib]System.String::Join(string, class [mscorlib]System.Collections.Generic.IEnumerable`1<string>)
L_014a: ldstr "}"
L_014f: call string [mscorlib]System.String::Concat(string, string, string)
L_0154: call void [mscorlib]System.Console::WriteLine(string)
L_0159: ret
L_015a: ldloc.2
L_015b: call void [mscorlib]System.Console::WriteLine(string)
L_0160: ret }
支持一下
扫一扫,支持v1nke
  • 微信扫一扫
  • 支付宝扫一扫