攻防世界Reverse(2)

secret-galaxy-300

来大致看看信息(看看会不会有所发现)
在这里插入图片描述
没有太大的发现,那我们就用ida打开去看看呗。
在这里插入图片描述
先看看print_starbase((int)&starbase);这个呗。
在这里插入图片描述
再来来看看看fill_starbase((int)&starbase);
在这里插入图片描述
再仔细看了一番,第一步查看信息的时候,它就提示尝试用ollydbg,其实上面应该是个结构体,而我们就需要去看看结构体内的信息:
大致用od运行一遍看一下是个什么:
在这里插入图片描述
其实再看看ida就会发现结构体里的数据没有完全被打印出来,这就需要我们去看看内存里存储的是什么了,不过ida里如发现它少打的字符所在位置:

在这里插入图片描述

在这里插入图片描述
突然发现了这个函数(这个是真的脑洞啊!!!)
在这里插入图片描述
然后我就用od找道这个地址进行调试,真不容易呀!


Newbie_calculations

我们打开这个文件,会发现输入的东西什么也不会显示出来,这点需要我们留下心。在这里插入图片描述
然后我们常规操作(ida打开)我们是可以先用PE看看信息的。看到main函数是有点长的,我们就看最后的判断:在这里插入图片描述
此时我们就去看看sub_401C7F(其实它是可以猜出来的,就是一个输出,我们也就不去看了)
而上面我们可以看到有很多函数,这点是有点工作量(其实就几个函数,我们都给它分析一下就行了)
在这里插入图片描述
先来看看sub_401000这个函数,它其实就是讲两个数相加,a1=a1+a2,既然知道了第一个函数的作用,那我们就来看看第二个函数的作用:在这里插入图片描述
那这个函数我们就应该知道它是个什么函数了,它有什么作用呢?循环了a2次,有a2个a1个相加,那就是a1*a2了呗。
那来来看看看sub_401220这个函数吧:
在这里插入图片描述
这个其实就是减法了!
这样的话,就是再主函数里的那些代码我们就可以看懂了,然后我们就可以去编写一个脚本了,不过编写的话是有点麻烦的。

s = [100, 97, 102, 56, 102, 52, 100, 56, 49, 54, 50, 54, 49, 97, 52, 49, 97, 49, 49, 53, 48, 53, 50, 97, 49, 98, 99, 50, 49, 97, 100, 101]
a = ''
for i in s:
	a += chr(i)
print(a)

这个s是手动计算上面的值,不建议这样(实在没办法也可以)
而我们是可以直接复制粘贴到C里面,改几个东西就行了:

#include <stdio.h>
#include<iostream>
#include<iomanip>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<iostream>
#include<map>
#include<time.h>
#include<queue>
#include <Windows.h>
#include "windows.h"
using namespace std;
int mul(int a,int b)
{
    return a*b;
}
int add(int a,int b)
{
    return a+b;
}
int sub(int a,int b)
{
    return a-b;
}
int main()
{
  int v3; // eax
  int v4; // ST1C_4
  int v5; // ST20_4
  int v6; // ST20_4
  signed int i; // [esp+4h] [ebp-90h]
  signed int j; // [esp+8h] [ebp-8Ch]
  int v10[32]; // [esp+Ch] [ebp-88h]
  int v11; // [esp+8Ch] [ebp-8h]
 
  for ( i = 0; i < 32; ++i )
    v10[i] = 1;
  v11 = 0;
  puts("Your flag is:");
  v3 = mul(v10[0], 1000000000);
  v3 = sub(v3, 999999950);
  v10[0]=mul(v3, 2);
  v3 = add(v10[1], 5000000);
  v3 = sub(v3, 6666666);
  v3 = add(v3, 1666666);
  v3 = add(v3, 45);
  v3 = mul(v3, 2);
  v10[1]=add(v3, 5);
  v3 = mul(v10[2], 1000000000);
  v3 = sub(v3, 999999950);
  v3 = mul(v3, 2);
  v10[2]=add(v3, 2);
  v3 = add(v10[3], 55);
  v3 = sub(v3, 3);
  v3 = add(v3, 4);
  v10[3]=sub(v3, 1);
  v3 = mul(v10[4], 100000000);
  v3 = sub(v3, 99999950);
  v3 = mul(v3, 2);
  v10[4]=add(v3, 2);
  v3 = sub(v10[5], 1);
  v3 = mul(v3, 1000000000);
  v3 = add(v3, 55);
  v10[5]=sub(v3, 3);
  v3 = mul(v10[6], 1000000);
  v3 = sub(v3, 999975);
  v10[6]=mul(v3, 4);
  v3 = add(v10[7], 55);
  v3 = sub(v3, 33);
  v3 = add(v3, 44);
  v10[7]=sub(v3, 11);
  v3 = mul(v10[8], 10);
  v3 = sub(v3, 5);
  v3 = mul(v3, 8);
  v10[8]=add(v3, 9);
  v3 = add(v10[9], 0);
  v3 = sub(v3, 0);
  v3 = add(v3, 11);
  v3 = sub(v3, 11);
  v10[9]=add(v3, 53);
  v3 = add(v10[10], 49);
  v3 = sub(v3, 2);
  v3 = add(v3, 4);
  v10[10]=sub(v3, 2);
  v3 = mul(v10[11], 1000000);
  v3 = sub(v3, 999999);
  v3 = mul(v3, 4);
  v10[11]=add(v3, 50);
  v3 = add(v10[12], 1);
  v3 = add(v3, 1);
  v3 = add(v3, 1);
  v3 = add(v3, 1);
  v3 = add(v3, 1);
  v3 = add(v3, 1);
  v3 = add(v3, 10);
  v10[12]=add(v3, 32);
  v3 = mul(v10[13], 10);
  v3 = sub(v3, 5);
  v3 = mul(v3, 8);
  v3 = add(v3, 9);
  v10[13]=add(v3, 48);
  v3 = sub(v10[14], 1);
  v3 = mul(v3, -294967296);
  v3 = add(v3, 55);
  v10[14]=sub(v3, 3);
  v3 = add(v10[15], 1);
  v3 = add(v3, 2);
  v3 = add(v3, 3);
  v3 = add(v3, 4);
  v3 = add(v3, 5);
  v3 = add(v3, 6);
  v3 = add(v3, 7);
  v10[15]=add(v3, 20);
  v3 = mul(v10[16], 10);
  v3 = sub(v3, 5);
  v3 = mul(v3, 8);
  v3 = add(v3, 9);
  v10[16]=add(v3, 48);
  v3 = add(v10[17], 7);
  v3 = add(v3, 6);
  v3 = add(v3, 5);
  v3 = add(v3, 4);
  v3 = add(v3, 3);
  v3 = add(v3, 2);
  v3 = add(v3, 1);
  v10[17]=add(v3, 20);
  v3 = add(v10[18], 7);
  v3 = add(v3, 2);
  v3 = add(v3, 4);
  v3 = add(v3, 3);
  v3 = add(v3, 6);
  v3 = add(v3, 5);
  v3 = add(v3, 1);
  v10[18]=add(v3, 20);
  v3 = mul(v10[19], 1000000);
  v3 = sub(v3, 999999);
  v3 = mul(v3, 4);
  v3 = add(v3, 50);
  v10[19]=sub(v3, 1);
  v3 = sub(v10[20], 1);
  v3 = mul(v3, -294967296);
  v3 = add(v3, 49);
  v10[20]=sub(v3, 1);
  v3 = sub(v10[21], 1);
  v3 = mul(v3, 1000000000);
  v3 = add(v3, 54);
  v3 = sub(v3, 1);
  v3 = add(v3, 1000000000);
  v10[21]=sub(v3, 1000000000);
  v3 = add(v10[22], 49);
  v3 = sub(v3, 1);
  v3 = add(v3, 2);
  v10[22]=sub(v3, 1);
  v3 = mul(v10[23], 10);
  v3 = sub(v3, 5);
  v3 = mul(v3, 8);
  v3 = add(v3, 9);
  v10[23]=add(v3, 48);
  v3 = add(v10[24], 1);
  v3 = add(v3, 3);
  v3 = add(v3, 3);
  v3 = add(v3, 3);
  v3 = add(v3, 6);
  v3 = add(v3, 6);
  v3 = add(v3, 6);
  v10[24]=add(v3, 20);
  v3 = add(v10[25], 55);
  v3 = sub(v3, 33);
  v3 = add(v3, 44);
  v3 = sub(v3, 11);
  v10[25]=add(v3, 42);
  v10[26]=add(v10[26], v10[25]);
  v10[27]=add(v10[27], v10[12]);
  v4 = v10[27];
  v3 = sub(v10[28], 1);
  v3 = add(v3, v4);
  v10[28]=sub(v3, 1);
  v5 = v10[23];
  v3 = sub(v10[29], 1);
  v3 = mul(v3, 1000000);
  v10[29]=add(v3, v5);
  v6 = v10[27];
  v3 = add(v10[30], 1);
  v10[30]=mul(v3, v6);
  v10[31]=add(v10[31], v10[30]);
  printf("CTF{");
  for ( j = 0; j < 32; ++j )
    printf("%c", (v10[j]));
  printf("}\n");
  return 0;
}

挺麻烦的,不过坚持下来时能够成功的。

知识点

这道题主要是考察我们对于

a = -1
b = 123
while(a)
{
	a--;
	b--;
}//函数部分

这个其实就是如同一个时钟,负数和正数在一个点,0和-0在一个点,构成一个圆圈,好像一个时钟。


re1-100

先来简单看下信息,了解一下这个文件的信息。
在这里插入图片描述
然后用ida打开:在这里插入图片描述
然后大致找一下,看看主体部分,然后再看看下面的辅助信息:
在这里插入图片描述
然后我们就去看看confuseKey这个关键函数到底是些什么内容:
在这里插入图片描述
那flag就是53fc275d81053ed5be8cdaf29f59034938ae4efd这个东西了,这道题不算太难。

知识点

这道题主要还是分析函数,其它没有什么要讲的。


666

刚开始一定是看看信息了:
在这里插入图片描述
然后再用ida打开,去看看到底在弄什么名堂,说什么666(哈哈哈)
在这里插入图片描述
那我们就再看看它的伪代码,来仔细分析一下里面的程序:
在这里插入图片描述
此时我们就看看encode这个东西,并且我们还可以知道key的值为12(十六进制),enflag为izwhroz"“w"v.K”.Ni这一串字符。
在这里插入图片描述
此时我们就来编个脚本来进行解密:
在这里插入图片描述
此时就可以了。

知识点

一个小知识吧,就是有时候你要加上括号(符号运算的优先级)平时我们是并不怎么去记忆这些符号运算级的,所以我们加上括号的话,就可以避免这些了。


IgniteMe

发现是个exe文件(不错,好久没有遇到了)
点开程序和其它的一样,没什么不同之处:
在这里插入图片描述
这是一些基本信息,再来看看ida里面有些什么:
在这里插入图片描述
眼尖的我们就能一眼看到我们需要哪里,它说,开始是’EIS{‘末尾是’}‘,这个东西,还有关键函数sub_4011C0(v12):
在这里插入图片描述
然后根据这个就可以进行解密了(来个脚本)
通过分析这个函数,我们可以发现它不允许有小写的字母,如果是大写会变成小写,然后来个异或进行加密(对byte_4420B0进行异或,还有个sub_4013C0(v8[i])函数里的异或),那我们就也来个这样的加密:
在这里插入图片描述
最后加上一个EIS{和}就可以了。
最后的flag是EIS{wadx_tdgk_aihc_ihkn_pjlm}

知识点

这道题也没什么知识点,主要还是分析能力,还有一个要强调的地方,就是括号的使用,多用括号,出错的概率就小了很多,因为很多的地方都是因为没有括号,所以导致脚本的编写的结果会出错。


debug

看到了这个exe文件(不错,又来个exe)
那就先运行一下看看是个什么东东?很简单,什么都没有。
在这里插入图片描述
先来个基本信息压压惊,再来个ida打开(发现没有办法反编译)然后我想的是看看汇编语言来进行逆向,不过找到了flag却没办法弄出来,所以弄个dnspy这个软件。
用dnspy这个打开,运行到入口点即可看到源码,我们找到wrong设置断点,运行一下,看看内存里面有没有我们想要的东西:
在这里插入图片描述
这样就可以了得到flag了。
这道题就是让我们知道一下.net这样的程序怎么来进行反编译的。

知识点

dnSpy是一款针对.NET程序的逆向工程工具。开发人员可以使用它反编译.NET代码,了解到它是如何工作的,以便学习或指导。


Guess-the-Number

我们可以看到题目的要求为:
在这里插入图片描述
并且它是个java的代码,我们就要用到java的反编译工具了(JD-GUI)
在这里插入图片描述
这样子我们就有了点思路了。只要把加密方式搞懂就可以得到flag了(或者直接修改代码,或运行代码来进行解密)。此时我们要注意几个点:一个是guess_number = Integer.parseInt(args[0]);它的意思就是将字符串转成整型(可以理解成强制转换)
然后命令行中进行运行尝试:
在这里插入图片描述
这样子运行一下就得到flag了,也许逆会问到309137378这个怎么来的?它就是判断语句了,
if (my_number / 5 == guess_number) {
int my_number = 1545686892;(这个数据我们也知道了)
那么309137378就是1545686892除于3咯咯!!!

知识点

《JD-GUI》是一款反编译软件,JD分为JD-GUI、JD-Eclipse两种运行方式,JD-GUI是以单独的程序的方式运行,JD-Eclipse则是以一个Eclipse插件的方式运行。
java:
/ * try catch:自己处理异常

  • try {
    *可能出现异常的代码
    *} catch(异常类名A e){
    *如果出现了异常类A类型的异常,那么执行该代码
    *} …(catch可以有多个)
  • finally {
    *最终肯定必须要执行的代码(例如释放资源的代码)
    }/

EasyRE

是个exe文件,用ida打开,发现没有Functions name里面是找不到main函数的(特别像打比赛,里面的很多逆向题都是如此,不让你找到主函数)那此时就通过搜索字符串进行确定主函数的所在位置。
在这里插入图片描述
然后一通分析,知道了我们想要的加密。
(const char *)&unk_402124而这个是xIrCj~<r|2tWsv3PtI\x7Fzndka
这一同字符。
我们再来看它有两个do~while循环,第一个就是将byte_40336C这里的数据里储存v7逆序的字符。
而我们再来根据第二个do~while来进行解密就可以了。
在这里插入图片描述
此时flag就得到了。

知识点

这道题如以往的一样,没有什么太大的难度。而知识点也没有什么要说的。


simple-check-100

我们可以看到这个是个压缩包,那我们就解压,发现有三个文件,就按exe文件来进行分析。
在这里插入图片描述
再来打开ida进行分析一下:
在这里插入图片描述
此时我们就看看着两个函数分别是什么?
check_key这个就是核实我们所输入的数据是否正确。
此时我们可以有两个思路,我们可以动态调试,这样是很简单的。
我们打开Ollydbg运行到check_key这个函数,修改eax里的值为1,但出现的是一堆乱码:
在这里插入图片描述
所以说OD可能不行,因为给了三个文件,我们可以用dbg来进行调试。
在这里插入图片描述
此时一直运行到check_key这里,期间我们随便输入一个key值就行了。
在这里插入图片描述
然后运行到结束就可以了,我们就能得到flag了。
在这里插入图片描述
flag就找到了。
这道题还有不同的解法,如ida的远程调试,或者静态分析,它之所以给了三个文件,就说明了有不同的解法。
后来发现ida上的调试好像也不行,会出乱码。

知识点

这道题我们可以再次学到如何用gdb调试,先用b main下到主函数断点,再n一步一步运行,再在eax中修改值(set ¥eax=1)然后c运行到结尾。


Windows_Reverse1

根据题目明显是个Windows下的逆向,文件是个exe的文件。在这里插入图片描述
信息上并没有太多的用处,但是有个ups的加壳,所以我们需要进行对它脱壳。在这里插入图片描述
我用的是kali,因为我的windows下是没有装upx脱壳工具的。此时我们再用ida打开就能找到main函数了。在这里插入图片描述
这时我们就可以去sub_401000这个函数里看看到底有些什么个东西。
在这里插入图片描述
但是我们是没有办法去找到这个byte_402FF8的具体值。而在字符串里面我们可以有点思路:在这里插入图片描述
既然我们静态没有办法了,就动态调试一下。不过,我们还是先来仔细分析一下伪代码,切记,伪代码其实是会编译错误的,我们来看是会发现v1是个地址,v4是a1与v1的地址差,而后面出现了byte_402FF8[(char)v1[v4]]这个,里面是个v1[v4]这个,它又是个什么东西呢?其实就是v1+v4这个值,那么byte_402FF8的索引里的值这个其实就是我们所输入的。
我们就需要找到byte_402FF8这个数组里面的值就可以了。然后我又去查看了一下byte_402FF8这个值。
在这里插入图片描述
这里出现的字符是与我们先前查看的字符串里对应住了,那为什么前面是?号呢?因为ascll码值前面的数值是没有具体字符表示的。
OD打开的发现了出现了反常的一些东西。
既然如此,那我们只好硬着头皮上去看看代码静态分析了,然后我将byte_402FF8这个值全部审查了一遍:
在这里插入图片描述
然后它们就是靠这这个表来进行检查的,这个表的内容和所在的位数,就构成了一个检查。在这里插入图片描述
这个时候我竟然有了一点迷惑,不知道这个是不是乱码,后来看到了题目的提示:提交的flag形式为flag{XXXX}
然后flag就是flag{ZZ[JX#,9(9,+9QY!}这个东西了。

知识点

这道题还是有点难度的,这里主要涉及到了一个地方:
*v1 = byte_402FF8[(char)v1[v4]]
这里的v1[v4]看着是两个地址,一个地址为另一个地址的索引,其实这里是伪代码出错了,它具体应该是v1+v4这样子了。涉及到指针ida就可能(一定)会出错,所以我们需要多做这类的题目,将我们做的记录下来,多了就成了我们的自我经验了。


posted @ 2020-12-30 21:54  望权栈  阅读(26)  评论(0编辑  收藏  举报  来源