攻防世界逆向高手题之dmd-50

99 篇文章 33 订阅

攻防世界逆向高手题之dmd-50

继续开启全栈梦想之逆向之旅~
这题是攻防世界逆向高手题的dmd-50
在这里插入图片描述

下载附件,照例扔入exeinfope中查看信息:
在这里插入图片描述

64位ELF文件,无壳,照例扔入IDA64位中查看伪代码,有main函数看main函数:
在这里插入图片描述

看到一堆变量,一堆系统函数,我知道系统函数通常不是考点,可这系统函数多到我都差点找不到主要代码:
在这里插入图片描述

突然看见字符串Enter the valid key!\n 猜测题型是与用户输入相关的判断型flag。
代码分析:

  v43 = __readfsqword(0x28u);			//一个内存段偏移,无用
  std::operator<<<std::char_traits<char>>(&std::cout, "Enter the valid key!\n", envp);
  std::operator>><char,std::char_traits<char>>(&edata, v42);
  std::allocator<char>::allocator(&v38);
  std::string::string(v39, v42, &v38);					// v42 输入复制给 v39。这里借鉴了别人的博客,这里犯下第一个错误,因为系统函数太多了,我也就只注意到了下面的md5,没去查这个函数用法,结果这个函数是赋值函数,也是关键
  md5((MD5 *)v40, (const std::string *)v39);			//一个md5加密函数, 把 v39 进行 MD5 后保存在 v40,我记得C语言没有md5函数的,这里可能是调用了外部的库函数
  v41 = std::string::c_str((std::string *)v40);
  std::string::~string((std::string *)v40);
  std::string::~string((std::string *)v39);
  std::allocator<char>::~allocator(&v38);

继续分析判断语句:

  if ( *(_WORD *)v41 == 0x3837		//这里犯下第二个错误,这里本来是14390的整数的,这里类型是16位WORD,后面都是8位的BYTE,也就是这里应该分出一个*(_BYTE *)v41和*(_BYTE *)(v41 + 1)的,可是我不会分,想起数在内存中是小端的十六进制数,就改为了十六进制,那么前面(_BYTE *)v41就是0x37,后面*(_BYTE *)(v41 + 1)就是0x38了。
    && *(_BYTE *)(v41 + 2) == 0x30
    && *(_BYTE *)(v41 + 3) == 0x34
    && *(_BYTE *)(v41 + 4) == 0x33
    && *(_BYTE *)(v41 + 5) == 0x38
    && *(_BYTE *)(v41 + 6) == 0x64
    && *(_BYTE *)(v41 + 7) == 0x35
    && *(_BYTE *)(v41 + 8) == 0x62
    && *(_BYTE *)(v41 + 9) == 0x36
    && *(_BYTE *)(v41 + 10) == 0x65
    && *(_BYTE *)(v41 + 11) == 0x32
    && *(_BYTE *)(v41 + 12) == 0x39
    && *(_BYTE *)(v41 + 13) == 0x64
    && *(_BYTE *)(v41 + 14) == 0x62
    && *(_BYTE *)(v41 + 15) == 0x30
    && *(_BYTE *)(v41 + 16) == 0x38
    && *(_BYTE *)(v41 + 17) == 0x39
    && *(_BYTE *)(v41 + 18) == 0x38
    && *(_BYTE *)(v41 + 19) == 0x62
    && *(_BYTE *)(v41 + 20) == 0x63
    && *(_BYTE *)(v41 + 21) == 0x34
    && *(_BYTE *)(v41 + 22) == 0x66
    && *(_BYTE *)(v41 + 23) == 0x30
    && *(_BYTE *)(v41 + 24) == 0x32
    && *(_BYTE *)(v41 + 25) == 0x32
    && *(_BYTE *)(v41 + 26) == 0x35
    && *(_BYTE *)(v41 + 27) == 0x39
    && *(_BYTE *)(v41 + 28) == 0x33
    && *(_BYTE *)(v41 + 29) == 0x35
    && *(_BYTE *)(v41 + 30) == 0x63
    && *(_BYTE *)(v41 + 31) == 0x30 )

后面判断后的结果按照以前经验转成ASCII字符,发现都是成功失败类的字符串,那这里的系统函数作用应该只是简单的赋值和输出吧,就不用深究了:
在这里插入图片描述
在这里插入图片描述

所以思路清晰了,对用户输入进行md5加密后一位一位比较,那么我们用md5后的值在在线工具中反向解密即可。
脚本:

key1=[0x37,0x38,0x30,0x34,0x33,0x38,0x64,0x35,0x62,0x36,0x65,0x32,0x39,0x64,0x62,0x30,0x38,0x39,0x38,0x62,0x63,0x34,0x66,0x30,0x32,0x32,0x35,0x39,0x33,0x35,0x63,0x30]
md=""
for i in key1:
	md+=chr(i)
print(len(md))
print(md)

md5结果:
在这里插入图片描述

在线解密网址:

https://www.cmd5.com/

在这里插入图片描述

额,我们不需要两次解密,一次就可以了,所以对grape再加密一次:
在这里插入图片描述

结果:b781cbb29054db12f88f08c6e161c199




PS:我在修改14390整数时突然发现我的IDA7.5有撤销功能!!(狂喜.jpg),快捷键一样是Ctrl+Z:
在这里插入图片描述

看见没,这里有个undo,是撤销!!太棒了!,不知道是那一版本IDA开始新增的功能!



总结:

1:
这里犯下第一个错误,因为系统函数太多了,我也就只注意到了下面的md5,没去查这个函数用法,结果这个函数是赋值函数,也是关键。

2:
这里犯下第二个错误,这里本来是14390的整数的,这里类型是16位WORD,后面都是8位的BYTE,也就是这里应该分出一个*(_BYTE
)v41和(_BYTE *)(v41 + 1)的,可是我不会分,想起数在内存中是小端的十六进制数,就改为了十六进制,那么前面(_BYTE )v41就是0x37,后面(_BYTE *)(v41 + 1)就是0x38了。

解毕!敬礼!

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沐一 · 林

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值