学破解第139天,《攻防世界reverse练习区666》学习
## 学破解第139天,《攻防世界reverse练习区666》学习前言:
  从小学到大专(计算机网络技术专业),玩过去的,所以学习成绩惨不忍睹,什么证书也没考,直到找不到工作才后悔,不知道怎么办才好。
  2017年12月16日,通过19元注册码注册论坛账号,开始做伸手党,潜水一年多,上来就是找软件。(拿论坛高大上的软件出去装X)
  2018年8月10日,报名了华中科技大学网络教育本科(计算机科学与技术专业)2018级秋季。(开始提升学历)
  2019年6月17日,不愿再做小菜鸟一枚,开始零基础学习破解。(感谢小糊涂虫大哥在我刚开始学习脱壳时,录制视频解答我的问题)
  2020年7月7日,感谢H大对我的鼓励,拥有了第一篇获得优秀的文章。(接下来希望学习逆向,逆天改命)
  2021年8月11日,华科学位英语2次不过,仅取得了毕业证书,学业提升失败,开始琢磨考注册类和职称类证书,谋求涨薪
  坛友们,年轻就是资本,和我一起逆天改命吧,我的学习过程全部记录及学习资源:(https://www.52pojie.cn/thread-1278021-1-1.html)
立帖为证!--------记录学习的点点滴滴
### 0x1下载文件
  1.下载CM,是一个压缩包,解压后发现并不是exe文件。
  2.通过exeinfo软件查壳,发现是64位ELF文件,如图所示:
!(https://z3.ax1x.com/2021/08/19/fqPj0S.png)
  3.不会Linux操作,这就没法动态调试了,用IDA静态分析看看,毕竟只是1分题,应该难度不大。
### 0x2代码分析
  1.使用64位IDA程序打开,这是main函数:
```
int __cdecl main(int argc, const char **argv, const char **envp)
{
char s; // BYREF
char v5; // BYREF
memset(s, 0, 0x1EuLL);
printf("Please Input Key: ");
__isoc99_scanf("%s", v5);
encode(v5, (__int64)s);
if ( strlen(v5) == key )
{
if ( !strcmp(s, enflag) )
puts("You are Right");
else
puts("flag{This_1s_f4cker_flag}");
}
return 0;
}
```
可以看到我输入v5,然后调用encode函数得到处理后的s,和enflag相等就是正确的。
  2.那么我们看看encode函数:
```
int __fastcall encode(const char *a1, __int64 a2)
{
char v3; //
int v4; //
int i; //
i = 0;
v4 = 0;
if ( strlen(a1) != key )
return puts("Your Length is Wrong");
for ( i = 0; i < key; i += 3 )
{
v3 = key ^ (a1 + 6);
v3 = (a1 - 6) ^ key;
v3 = a1 ^ 6 ^ key;
*(_BYTE *)(a2 + i) = v3;
*(_BYTE *)(a2 + i + 1LL) = v3;
*(_BYTE *)(a2 + i + 2LL) = v3;
}
return a2;
}
```
打开数据段看一下,key是什么,key的长度是什么,一目了然。
.data:0000000000004060 enflag db 'izwhroz""w"v.K".Ni',0
.data:0000000000004060 ; DATA XREF: main+8F↑o
.data:0000000000004073 align 20h
.data:0000000000004080 public key
.data:0000000000004080 key dd 12h ; DATA XREF: encode+2D↑r
.data:0000000000004080 ; encode+5F↑r ...
.data:0000000000004080 _data ends
  3.把处理v5的算法手动优化一下成:
```
for ( i = 0; i < flag; i += 3 )
{
flag = key ^ (a1 + 6);
flag = (a1 - 6) ^ key;
flag = a1 ^ 6 ^ key;
}
```
现在就是一个数学代数问题了,已知a,x,a=b+x,求b的值。
  4.现在就是带入已知的值,求未知的值,a=b+x,可以变成b=a-x,用代码表示就是:
```
for (i = 0; i < key; i += 3)
{
(a1 + 6) = flag ^ key;
(a1 - 6)= flag ^ key;
a1 ^ 6 = flag ^ key;
}
```
继续化简,我用arr数组代替a1,看着舒服点:
```
for (i = 0; i < key; i += 3)
{
arr = flag ^ key - 6;
a1 = flag ^ key + 6;
a1= flag ^ key ^ 6;
} for (i = 0; i < key; i += 3)
```
  5.解密算法已经反推出来了,接下来写程序爆破吧,完整代码如下:
```
#include <iostream>
using namespace std;
int main()
{
char flag = "izwhroz\"\"w\"v.K\".Ni";
char arr = "";
for (int i = 0; i < 18; i += 3)
{
arr = (flag ^ 18) - 6;//避免因为运算符优先级导致结果不对,我加了小括号
arr = (flag ^ 18) + 6;
arr= (flag ^ 18) ^ 6;
}
arr = '\0';
cout << arr << endl;
system("pause");
}
```
  6.编译运行结果如下:
unctf{b66_6b6_66b}
请按任意键继续. . .
  7.输入flag进行验证:
!(https://z3.ax1x.com/2021/08/19/fquDRU.png)
### 0x3总结
  1.IDA F5功能太强大,直接把源码反编译出来了。
  2.运用逆向思维和数学逻辑,不用理解算法,直接恒等式变换,把结果作为输入,推出flag。
  3.总体来说,本题比较简单,适合我这样的菜鸟练手。
### 0x4参考资料
  1.无
  **PS:善于总结,善于发现,找到分析问题的思路和解决问题的办法。虽然我现在还是零基础的小菜鸟一枚,也许学习逆向逆天改命我会失败,但也有着成功的可能,只要还有希望,就决不放弃!** @小菜鸟一枚 学破解第365天从入门到放弃 ,全剧终,哈哈哈~ yulai3230 发表于 2021-8-21 11:36
大佬可以帮忙研究一个软件的机器码吗,100吾爱币
我是小菜鸟,还在学习呀,技术还没学成,帮不了你{:1_909:} 前排学习,坐好,多谢分享 坚持!年轻就是资本,只管干! 感谢分享,坚持学习! 康木昂,,继续加油。。我看好你。。:lol
感谢分享,坚持学习! 现在菜鸟的门槛都这么高了吗 大哥牛逼了 我想问 我的专业计算机科学与技术 我该怎么办 我也来慢慢学学破解把 谢谢大哥 {:1_921:}给你点赞