XCTF进阶刷题-2
0x01 666
IDA分析
进入encode去看具体的加密操作,是几个异或操作,然后3个字符一组
编写脚本,flag就出来了
0x02 signin-rsa算法
rsa相关知识:
https://www.52pojie.cn/thread-1100545-1-1.html
ida查看主函数,根据算法特征得知是rsa算法
以下函数的作用是将输入字符串转为十六进制ascii码字符串:
利用yafu分解(windows安装:https://blog.csdn.net/weixin_41603028/article/details/97167312),然后编写脚本如下,然后转换即可
问题:
python3一直无法导入gmpy2的包,只能用python2写了
0x03 igniteme
ida分析,主函数如下:
可以看到前四位和最后一位是定的,对v7做一个sub_4011C0函数的判断
跟进函数看看:
把值给了v8,然后v8经过一些操作变成v4,v4和最后的字符串相同
查看unk_4420B0和sub_4013C0
编写脚本如下即可,然后转一下大小写
0x04 hackme(&0xff)
ida分析,找到主函数,分析一下就是,输入字符串,长度为22位,然后抽取其中的10位进行检验(可以看到数组byte_6B4270是22位的),检验方法就是v9和输入的字符串进行异或后要和固定的数组内容相同
注意:循环10次不代表字符串只有10位
查看byte_6B4270的内容
可以编写脚本如下:
要注意的是,v1[i]的值很大,需要和0xff相与,0xff最大值是255,由于整数值超过了255,所以用来控制
0x05 ReverseMe
ida分析:
0x06 easyre1
打开ida就能看到,提交即可
0x07 76号
发现有个upx的壳,脱壳
放到ida分析,搜索字符串可以看到有correct字符,查找位置,找到主函数
但是主函数反编译不出来,重要函数80485E0可以反编译,里面定义了很多变量和switch匹配,不是很理解,动态调试后发现就是匹配输入的字符串,v3就是输入的每一位,v5的由输入的字符串决定的位置是为1,然后再switch里做判断,最后return为1的话就正确
然后就一位一位推测就可以了
一开始推到了15位,发现在14位的时候直接会跳转到0,研究后发现和v5数组有关,当输入的是h的时候,v11并不会为1,所以就会return 0
找到对应关系后重新推测:
调试验证成功:
0x08 easyhook(hook)
主函数,关键函数为sub_401220和sub_401240,然后创建了一个文件
运行一下,发现输入的字符串被改变了:
动态调试一下,发现确实在这里写入的输入字符串被改变了
401220:点进4010D0看看
4010D0:
Virtualprotectex修改了指定进程,hprocess和lpaddress是要更改的进程的句柄和页面区域的基地址的指针,5是访问保护属性已更改的区域的大小,以字节为单位。
Writeprocessmemory写入了指定数据,byte_40C9BC是指向缓冲区的指针,该缓冲区包含要在指定进程的地址空间中写入的数据。5是写入的数据大小
返回401220看看是怎么修改的
byte_40C9BC是0xE9,但是这只有一个字节,所以后四个字节就是40C9BD的内容,40C9BD和401080有关
401080:调用了sub_401000,lpbuffer指向包含要写入文件或设备的数据的缓冲区的指针。同时,真正flag的判定条件numer==1也是这里决定的
401000:可以看到对a1进行的操作,编写脚本即可
401240:并没有什么作用
0x09 secret-string-400(js)
打开看是一个html和一个js文件,之前没接触过
打开html,是一个验证输入页面,随便输入一个字符串,会弹出nope
搜索了下怎么调试js,开始尝试在代码各处里加入console.log,然后f12查看输出情况
然后页面中出现了隐藏的代码:
根据这个代码写出脚本即可:
0x0A easymaze
ida分析主函数
由于分析两个step函数比较复杂,且容易分析错,可以动态调试(linux下的远程动态调试)找出生成的迷宫,下断点,找v5的位置
再看step2,告诉我们怎么走
根据迷宫走即可
0x0B reverse reverse-for-the-holy-grail
ida分析,可以看到v4的值是判定条件,跟进stringmod看看
stringmod:是一大堆函数,理解一下
编写脚本:
0x0C serial-150(动态调试)
ida动态调试:
看到比较长度的代码,10h,所以长度为16
比较第一个字符,所以第一个字符是E
第一个字符加上最后一个字符为9B,所以最后一个字符是V(9B-45=56的ascii码)
第二位是5A,即Z
第二位和倒数第二位加起来还是9B,倒数第二位是A
按理类推即可:EZ9dmq4c8g9G7bAV
0x0D babymips(mips,位运算符)
下载了一个软件用来反汇编mips
就很清楚了。先比较前五个字符,然后在FUN_004007f0里比较后面的
注意:-的优先级大于^
进入函数查看,重点其实就是 b = (a<<0x1a)>>0x18 | a >>6这两句,现在已知b,求a
注意:<<和>>操作是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)
编写脚本如下:
0x0E Windows_Reverse2(base64)
先ida看看主函数:
看看401240具体干了什么,有点复杂,再进入401000
还是很复杂,决定动态调试看看:
动态后可以明白401240是先将输入的字符两个两个一组然后代表一位十六进制
然后401000将前3位和后三位分开,分别经过操作转为4位,最后输出
那么可以编写脚本如下:
最终flag是ADEBDEAEC7BE
0x0F Windows_Reverse1
加壳了:
脱一下:
怎么既视感这么强,这是一个系列吗
进入401000看看:
看起来只要赋值一下,看看这个402FF8数组
空的,不是很理解,决定动态跑一下,输入了1
可以看到是到aZyxwvutsrqponm这个数组里去找了
但是也不是正常的输入的序号就是对应的第几位
多尝试几个后发现是输入的ascii码-32
所以编写脚本即可:
相差的32位是在这里:数组起始位置是2ff8,下面对于开始有字符对应的是3018