0x04Xctf进阶刷题-2

XCTF进阶刷题-2

0x01 666

IDA分析

image-20201103174113594

进入encode去看具体的加密操作,是几个异或操作,然后3个字符一组

image-20201103174237818

编写脚本,flag就出来了

image-20201103174322010

0x02 signin-rsa算法

rsa相关知识:

https://www.52pojie.cn/thread-1100545-1-1.html

ida查看主函数,根据算法特征得知是rsa算法

image-20201110143659748

以下函数的作用是将输入字符串转为十六进制ascii码字符串:

image-20201110144019734

利用yafu分解(windows安装:https://blog.csdn.net/weixin_41603028/article/details/97167312),然后编写脚本如下,然后转换即可

image-20201110180421766

image-20201110180133377

问题:

python3一直无法导入gmpy2的包,只能用python2写了

0x03 igniteme

ida分析,主函数如下:

可以看到前四位和最后一位是定的,对v7做一个sub_4011C0函数的判断

image-20201110164753556

跟进函数看看:

把值给了v8,然后v8经过一些操作变成v4,v4和最后的字符串相同

image-20201110164900645

查看unk_4420B0和sub_4013C0

image-20201110161046021

image-20201110161059343

编写脚本如下即可,然后转一下大小写

image-20201110165109839

0x04 hackme(&0xff)

ida分析,找到主函数,分析一下就是,输入字符串,长度为22位,然后抽取其中的10位进行检验(可以看到数组byte_6B4270是22位的),检验方法就是v9和输入的字符串进行异或后要和固定的数组内容相同

注意:循环10次不代表字符串只有10位

image-20201110182250771

查看byte_6B4270的内容

image-20201110182511109

可以编写脚本如下:

image-20201111111154246

要注意的是,v1[i]的值很大,需要和0xff相与,0xff最大值是255,由于整数值超过了255,所以用来控制

0x05 ReverseMe

ida分析:

image-20201111143110520

0x06 easyre1

打开ida就能看到,提交即可

image-20201113115339027

0x07 76号

发现有个upx的壳,脱壳

image-20201125151636534

放到ida分析,搜索字符串可以看到有correct字符,查找位置,找到主函数

image-20201126113743706

但是主函数反编译不出来,重要函数80485E0可以反编译,里面定义了很多变量和switch匹配,不是很理解,动态调试后发现就是匹配输入的字符串,v3就是输入的每一位,v5的由输入的字符串决定的位置是为1,然后再switch里做判断,最后return为1的话就正确

image-20201126113826531

然后就一位一位推测就可以了

一开始推到了15位,发现在14位的时候直接会跳转到0,研究后发现和v5数组有关,当输入的是h的时候,v11并不会为1,所以就会return 0

image-20201126114240393

找到对应关系后重新推测:

image-20201126114216580

调试验证成功:

image-20201126112823384

0x08 easyhook(hook)

主函数,关键函数为sub_401220和sub_401240,然后创建了一个文件

image-20201116134415789

运行一下,发现输入的字符串被改变了:

image-20201116141148468

动态调试一下,发现确实在这里写入的输入字符串被改变了

image-20201116141519684

401220:点进4010D0看看

image-20201116134620725

4010D0:

Virtualprotectex修改了指定进程,hprocess和lpaddress是要更改的进程的句柄和页面区域的基地址的指针,5是访问保护属性已更改的区域的大小,以字节为单位。

Writeprocessmemory写入了指定数据,byte_40C9BC是指向缓冲区的指针,该缓冲区包含要在指定进程的地址空间中写入的数据。5是写入的数据大小

image-20201116134806821

返回401220看看是怎么修改的

byte_40C9BC是0xE9,但是这只有一个字节,所以后四个字节就是40C9BD的内容,40C9BD和401080有关

image-20201116142056410

401080:调用了sub_401000,lpbuffer指向包含要写入文件或设备的数据的缓冲区的指针。同时,真正flag的判定条件numer==1也是这里决定的

image-20201116142205966

401000:可以看到对a1进行的操作,编写脚本即可

image-20201116142459347

image-20201116154606478

401240:并没有什么作用

image-20201116134559636

0x09 secret-string-400(js)

打开看是一个html和一个js文件,之前没接触过

打开html,是一个验证输入页面,随便输入一个字符串,会弹出nope

搜索了下怎么调试js,开始尝试在代码各处里加入console.log,然后f12查看输出情况

image-20201116171456917

然后页面中出现了隐藏的代码:

image-20201116170210757

根据这个代码写出脚本即可:

image-20201116171607888

0x0A easymaze

ida分析主函数

image-20201116172904202

由于分析两个step函数比较复杂,且容易分析错,可以动态调试(linux下的远程动态调试)找出生成的迷宫,下断点,找v5的位置

image-20201117091836672

再看step2,告诉我们怎么走

image-20201117092345267

根据迷宫走即可

image-20201117092811994

image-20201117092755620

0x0B reverse reverse-for-the-holy-grail

ida分析,可以看到v4的值是判定条件,跟进stringmod看看

image-20201117160814789

stringmod:是一大堆函数,理解一下

image-20201117160928953

image-20201117161027159

编写脚本:

image-20201117160731736

0x0C serial-150(动态调试)

ida动态调试:

image-20201117180507650

8F5E6F84-02A8-4523-874E-03A0F3AA1C02

看到比较长度的代码,10h,所以长度为16

915BC464-5DEA-4841-9715-7CACBA9B7E68

比较第一个字符,所以第一个字符是E

97BED366-6105-4D26-A4E7-6808DAF3C544

第一个字符加上最后一个字符为9B,所以最后一个字符是V(9B-45=56的ascii码)

23F762B1-FEB7-48EA-920E-F7F852E166D3

第二位是5A,即Z

image-20201117180907737

第二位和倒数第二位加起来还是9B,倒数第二位是A

image-20201117181154507

按理类推即可:EZ9dmq4c8g9G7bAV

0x0D babymips(mips,位运算符)

下载了一个软件用来反汇编mips

就很清楚了。先比较前五个字符,然后在FUN_004007f0里比较后面的

注意:-的优先级大于^

image-20201120083337582

进入函数查看,重点其实就是 b = (a<<0x1a)>>0x18 | a >>6这两句,现在已知b,求a

image-20201120083511211

注意:<<和>>操作是32位的,优先级大于|

因为a肯定是字符,所以1只会出现在后8位,b也是字符,

那么(a<<0x1a)>>0x18的操作就相当于在原来的后面加两个0,即a<<2

b = a<<2|a>>6

同时byte(8位)对整个式子做了限制(强制转换时计算机只保留其后8位),uint和int修饰第一个式子

所以这个式子需要这样理解:

a<<2,即高两位消失,低两位变0

a>>6,即低六位消失,高两位变成低两位

即循环位移

例如:a = 10100011

1010001100|0000010 = 1010001110 ->10001110 = b

所以我们的a可以这样用b来表示

a = (b & 00000011(0x3) )<<6|(b & 11111100(0xfc))>>2

或者a = (byte)(b<<6|b>>2)

编写脚本如下:

image-20201120095913785

0x0E Windows_Reverse2(base64)

先ida看看主函数:

image-20201123170313048

看看401240具体干了什么,有点复杂,再进入401000

image-20201124165655973

还是很复杂,决定动态调试看看:

image-20201124165724832

动态后可以明白401240是先将输入的字符两个两个一组然后代表一位十六进制

image-20201123170618917

然后401000将前3位和后三位分开,分别经过操作转为4位,最后输出

那么可以编写脚本如下:

image-20201124165542112

最终flag是ADEBDEAEC7BE

0x0F Windows_Reverse1

加壳了:

image-20201125100611130

脱一下:

image-20201125100741673

怎么既视感这么强,这是一个系列吗

image-20201125100955283

进入401000看看:

image-20201125110924068

看起来只要赋值一下,看看这个402FF8数组

image-20201125111016733

空的,不是很理解,决定动态跑一下,输入了1

image-20201125103632415

可以看到是到aZyxwvutsrqponm这个数组里去找了

但是也不是正常的输入的序号就是对应的第几位

多尝试几个后发现是输入的ascii码-32

所以编写脚本即可:

image-20201125111234444

相差的32位是在这里:数组起始位置是2ff8,下面对于开始有字符对应的是3018

image-20201125112156887