首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

逆向专题 Writeup分享一

快,关注这个公众号,一起涨姿势~

逆向WP分享一

0x01.re4

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

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

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

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

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

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

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

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

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

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

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

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

运行成功,拿到flag!

0x02.xor

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

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

直接看汇编,要使返回值为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··的内存地址中去查看。

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

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

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

随便输入几个字符

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

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

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

getflag!!!(终于...)

0x03.走后门

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

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

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

得到密码

0x04.re06

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

说明这个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

拿到flag!

下面是部分注释

完整注释

method public static void Main() cil managed

{

.custom instance void [mscorlib]System.STAThreadAttribute::.ctor()

.entrypoint

.maxstack 5

.locals init (

[0] class [mscorlib]System.Collections.ObjectModel.ReadOnlyCollection`1 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 [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::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::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::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

L_00ae: ldstr ""

L_00b3: ldloc.0

L_00b4: call string [mscorlib]System.String::Join(string, class [mscorlib]System.Collections.Generic.IEnumerable`1)

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

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)

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 }

下期

预告

一种 Au3 远控木马变种样本分析

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20171215G03JKV00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券