IDA动态调试解RC4

IDA动态调试解RC4

本篇博客所有内容,均学习于无名侠大佬在bilibili的视频:https://www.bilibili.com/video/BV1WQ4y1X7TY

LazyIDA熊猫版:https://github.com/P4nda0s/LazyIDA

实验文件下载:https://github.com/P4nda0s/SycRevLearn


原理分析:

有一些算法的加密与解密是相同的算法过程,例如 RC4、部分简单的异或算法等。

测试方法:

1.设置算法输入数据A

2.获取算法输出数据B

3.设置算法输入数据为B (上一步结果代入)

4.获取算法输出数据 B',对比 B' 与 A 的值,若相等则该算法加密解密是同一段代码。

通俗来讲,就是输入A输出B,输入B输出A。

拿视频中的题目来分析:

  sub_85F057(v14);//反调试
  puts("Welcome!! give me your flag:\n");
  do
  {
    v8 = j_j_j___fgetchar();
    if ( v8 == 10 )
      break;
    input[index++] = v8;
  }
  while ( (int)index < 44 );
  if ( index >= 0x200 )
    j____report_rangecheckfailure();
  input[index] = 0;
  len = j__strlen(input);
  sub_85CEFB((int)v13, (int)v14, len);
  for ( i = 0; i < 256; ++i )
    v12[i] = v13[i];
  fun1((int)v13, (int)input, len);//加密函数
  for ( j = 0; j < 44; ++j )
  {
    if ( v7[j] == input[j] )
      ++v10;
  }
  if ( v10 == 44 )
    puts("Yes, u right!\n");
  else
    puts("no no no\n");
  system("pause");
  return 0;
}

啥也不要分析,主要看fun1((int)v13, (int)input, len);

input是我们输入的,这个函数会将我们的input进行加密。

  for ( j = 0; j < 44; ++j )
  {
    if ( v7[j] == input[j] )
      ++v10;
  }

然后在通过这里进行比较。

根据for语句可以得知,flag的长度可能是44,这里为什么说是可能呢,如果是逐字节加密,就是我们输入的每一个字符加密后都是一个字符,那么flag的长度肯定是44,如果我们的输入,一个字符加密成了两个字符,那么我们输入的flag的长度就是22,因为这里并不确定,所以只能猜测是44。

程序有反调试,我尝试将反调试给nop掉,但是发现反调试似乎又与加密代码有着一定的关系,我尝试了,没能理清楚反调试和加密代码的关系,所以这里和视频中的一样,还是带着反调试来分析,这里用IDA附加运行中的程序就行,因为已经执行完反调试的那句代码了。

测试是否加密与解密是相同的算法

在加密函数处断下

image-20240502223047670

先输入:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

查看input的值

image-20240502222926791

再F8单步步过,查看此时加密后的input

image-20240502223302203

用插件将数据提取出来

image-20240502225423609

[+] Dump 0xCFF1BC - 0xCFF1E8 (44 bytes) :
D62DE6F797244F2EA92DDDA37904C885B9E4E8D90B325F9908C07B804E134AC497DA7562D0AD31C558C3BBF6

可以看到我们输入的44个a被加密成了上述数据

这次我们将上述数据进行输入,看执行之后是否可以还原成44个a

上述数据存在不可见字符,不能从命令框里直接输入,这里需要用到Paste Data来改栈上的数据。

这次我们先输入41个b

image-20240502231707435

通过Paste Data将数据改成D62DE6F797244F2EA92DDDA37904C885B9E4E8D90B325F9908C07B804E134AC497DA7562D0AD31C558C3BBF6

image-20240502231739109

再F8单步步过,查看此时加密后的input

image-20240502231816745

可以看到数据恢复成了41个a

  fun1((int)v13, (int)input, len);//加密函数
  for ( j = 0; j < 44; ++j )
  {
    if ( v7[j] == input[j] )
      ++v10;
  }
  if ( v10 == 44 )
    puts("Yes, u right!\n");
  else
    puts("no no no\n");
  system("pause");

再回头看一下程序,程序是将v7和input进行比较,v7其实就是flag加密之后的形式,我们此时只要将v7dump下来,把v7的数据当作input进行传入,经过加密函数之后就可以得到flag了。

v7:

[+] Dump 0x7DF5F0 - 0x7DF61C (44 bytes) :
E415C4EDA62F5610BB13EBAD7556C7BBBBE9B9CC023A509F369069BE7C4244CAC6D4245CD2B924C11893B3EA

再一次执行程序

image-20240502232226350

将input用Paste Data改成E415C4EDA62F5610BB13EBAD7556C7BBBBE9B9CC023A509F369069BE7C4244CAC6D4245CD2B924C11893B3EA

image-20240502232319008

再F8单步步过,查看此时加密后的input

image-20240502232348326

可以看到flag已经被还原了,按一下键盘上的A键就能转成字符串形式方便复制

SYC{Pjx_s_Wom3n_cl0thing_1s_S0oo0o0_cute!1i}

今天就先这样,等明天我试着做一下其它题目,看是否学到了精髓。

2024年5月2日23点28分


例题一:[第五章 CTF之RE章]BabyAlgorithm

IDA远程调试:https://blog.csdn.net/m0_74148881/article/details/134451159

和原理里面的那道题几乎一样,区别就是这个题是elf文件,得在linux下运行,还有就是恰好加密后的flag会有一个\x00截断,这个需要处理一下。

嘿呀,不想写过程了,感觉没啥用。。。不再主动找例题了,遇到了再加到这篇博客吧

2024年5月3日20点01分

posted @   山西小嫦娥  阅读(224)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示