攻防世界逆向入门题之流浪者

99 篇文章 34 订阅

攻防世界逆向入门题之流浪者

继续开启全栈梦想之逆向之旅~
这题是攻防世界逆向入门题的流浪者

在这里插入图片描述

下载附件,照例扔入exeinfope中查看信息:
在这里插入图片描述
32位PE文件无壳,照例扔入ida32中查看伪代码:
在这里插入图片描述
是没有主函数的题型,那就运行程序提取有用信息:
在这里插入图片描述
信息提取完了,一个弹框,一个判断,根据字符串我们可以找到弹框所在函数,弹框是messagebox函数,而import中只有一个messagebox,双击跟踪即可:
在这里插入图片描述在这里插入图片描述

查看该函数被谁调用,用IDA权威指南学到的新技巧,function call窗口:
在这里插入图片描述
在这里插入图片描述

找到比较函数,但是没有找到输入函数,继续查看被谁调用,继续function call窗口:
在这里插入图片描述

在这里插入图片描述

找到函数了。

按照流程走,我们要判断是和输入有关的生成型flag还是简单的存储型flag,答案是前者,而且是明文密文对照类型,那就开始代码分析:

  v4 = (CWnd *)((char *)this + 100);
  v1 = CWnd::GetDlgItem(this, 1002);		//这些系统函数一开始吓到我了,虽然系统函数一直不是什么考点,但还是认为这里会有和输入相关的东西,后来下载了API的chm文档查了一下作用,的确,后面的GetBuffer应该就是获取用户输入了,但只是获取而已,相当于scanf,知道即可,还是没什么考点
  CWnd::GetWindowTextA(v1, v4);
  v2 = sub_401A30((char *)v8 + 100);
  Str = CString::GetBuffer((CWnd *)((char *)v8 + 100), v2);
  if ( !strlen(Str) )
    return CWnd::MessageBoxA(v8, &byte_4035DC, 0, 0);	//弹框函数,这里犯下第一个错误,IDA双击进去的数据都是db类型的,而我们一开始看到的弹框显示的是中文,所以我们要改类型为dd类型才可以,不然就显示不了中文,所以&byte_4035DC跟踪进去后要用热键D改为dd类型再转字符。
  for ( i = 0; Str[i]; ++i )	//把输入的字符串逐个判断条件并根据不同条件修改,
  {
    if ( Str[i] > 57 || Str[i] < 48 )  
    {
      if ( Str[i] > 122 || Str[i] < 97 )
      {
        if ( Str[i] > 90 || Str[i] < 65 )
          sub_4017B0();	//有一个不是弹框范围内就返回失败
        else
          v5[i] = Str[i] - 29;	//范围在65~90中,输出结果在36~61中
      }
      else
      {
        v5[i] = Str[i] - 87; //范围在97~122中,输出结果在10~35中
      }
    }
    else
    {
      v5[i] = Str[i] - 48;	//范围在48~57中,输出结果在0~9中
    }
  }
  return sub_4017F0((int)v5);		//把修改后的数组结果作为参数赋给后面密文对照函数。
int __cdecl sub_4017F0(int a1)
{
  int result; // eax
  char Str1[28]; // [esp+D8h] [ebp-24h] BYREF
  int v3; // [esp+F4h] [ebp-8h]
  int v4; // [esp+F8h] [ebp-4h]

  v4 = 0;
  v3 = 0;
  while ( *(int *)(a1 + 4 * v4) < 62 && *(int *)(a1 + 4 * v4) >= 0 )
  {
    Str1[v4] = aAbcdefghiabcde[*(_DWORD *)(a1 + 4 * v4)];    //aAbcdefghiabcde双击跟踪是abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ'的62位长度字符串,也就不难解释while判断条件的<62了,这里还犯下第二,第三个错误,第二个错误是一开始没看出来这是个数组,*(_DWORD *)(a1 + 4 * v4)是取索引而已,a1是数组头地址,现在要知道带方括号的[]基本都是数组取字符!  第三个错误是这里*(_DWORD *)(a1 + 4 * v4)型我是真的搞不懂,明明a1是int型,还是数组头地址,它前面的(_DWORD *)把它又变成了uint32型地址,先不说这多此一举,关键是int型地址+1就是加4个字节啊!这里直接+4*v4,那不是一下就跳过4个a1数组元素了吗!关键是我调试IDA既然没有问题!!!好吧,只能认为是IDA分析出错了,
    ++v4;
  }
  Str1[v4] = 0;
  if ( !strcmp(Str1, "KanXueCTF2019JustForhappy") )  //从字典中获取的字符与明文对比,符合就是flag
    result = sub_401770();
  else
    result = sub_4017B0();
  return result;
}

所以现在就是字典和明文的加密关系逆向题了,这里犯下第四个错误,这类明文字典密文题目逆向要从密文出发,找到对应的字典下标,再用下标数组反逻辑逆向出明文:

第一步从密文出发,找到对应的字典下标:

key1="abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ"
key2="KanXueCTF2019JustForhappy"
suoyin=[]
suoyin2=[]
v4=0
for i in range(len(key2)):
	for a in range(len(key1)):
		if key2[i] == key1[a]:
			suoyin.append(a)
print(suoyin)
#print(len(suoyin))

这是我的做法,逐个对比,找出下标,当然后面还学到更好的.index(str)方法,后面会讲。

输出:

[19, 0, 27, 59, 44, 4, 11, 55, 14, 30, 28, 29, 37, 18, 44, 42, 43, 14, 38, 41, 7, 0, 39, 39, 48]

这就是字典索引了,然后后面逆向出明文时就犯错了,逆向,是从底部出发向上走,也是是我们一开始掌握的是结果,要从条件中有关结果的判断往上走,而不是从0~1000这样从上往下加密然后提取出对应条件的下标,虽然结果一样,但是流程就差太多了:
脚本:

suoyin2=[19, 0, 27, 59, 44, 4, 11, 55, 14, 30, 28, 29, 37, 18, 44, 42, 43, 14, 38, 41, 7, 0, 39, 39, 48]
v5=0
flag=""

for i in suoyin2:	//这里的判断条件是从从条件中有关结果的判断往上走,因为前面写出了结果的范围,所以我们应该用结果的范围向上走。
	if i >= 0 and i <= 9:
		v5=i+48
	elif i >= 10 and i <= 35:
		v5=i+87
	elif i >= 36:
		v5=i+29
	flag+=chr(v5)
print(flag)

输出:

j0rXI4bTeustBiIGHeCF70DDM

别人更好的利用.index获取索引下标的脚本:

table = "abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ"
s = "KanXueCTF2019JustForhappy"
ff = []
for i in s:
    ff.append(table.index(i))	//这里我不得不说真的秒,我是一时想不到,用字符串内置函数.index(str)完美输出索引,比我快多了。
 
flag = ""
for i in ff:
    if 0 <= i <= 9:
        flag += chr(i + 48)
    elif 9 < i <= 35:
        flag += chr(i + 87)
    elif i > 36:
        flag += chr(i + 29)
 
print (flag)

总结:

1:弹框函数,这里犯下第一个错误,IDA双击进去的数据都是db类型的,而我们一开始看到的弹框显示的是中文,所以我们要改类型为dd类型才可以,不然就显示不了中文,所以&byte_4035DC跟踪进去后要用热键D改为dd类型再转字符。

2:3:
aAbcdefghiabcde双击跟踪是abcdefghiABCDEFGHIJKLMNjklmn0123456789opqrstuvwxyzOPQRSTUVWXYZ’的62位长度字符串,也就不难解释while判断条件的<62了,这里还犯下第二,第三个错误。
第二个错误是一开始没看出来这是个数组,*(_DWORD )(a1 + 4 * v4)是取索引而已,a1是数组头地址,现在要知道带方括号的[]基本都是数组取字符!
第三个错误是这里
(_DWORD *)(a1 + 4 * v4)型我是真的搞不懂,明明a1是int型,还是数组头地址,它前面的(_DWORD )把它又变成了uint32型地址,先不说这多此一举,关键是int型地址+1就是加4个字节啊!这里直接+4v4,那不是一下就跳过4个a1数组元素了吗!关键是我调试IDA既然没有问题!!!好吧,只能认为是IDA分析出错了。

4:所以现在就是字典和明文的加密关系逆向题了,这里犯下第四个错误,这类明文字典密文题目逆向要从密文出发,找到对应的字典下标,再用下标数组反逻辑逆向出明文:

解毕!敬礼!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

沐一 · 林

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

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

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

打赏作者

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

抵扣说明:

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

余额充值