一、PWN
1、babyheap
一道2.27的新机制的题目
https://www.anquanke.com/post/id/219292
但是直接改bk指针即可,因为和2.31一样
漏洞点:UAF
输入点:只能改bk指针,所以需要切割实现overlap通过上一个堆块改下一个堆块的fd指针
1 | #coding=utf8 |
2、babypac
这题是ubuntu20下的aarch64的arm题,所以一开始要先strings看清楚版本先,然后ida分析每个地方都有个神奇的签名:这是一种pac机制,一种全新的保护机制,通过在一个内存地址的高位设置一个值,然后当使用到这个内存地址时,要进行check,使用时的值要和设置完的整体值相等,才会真正使用到这个内存地址的值(去掉高位那个标志值)
就是这个玩意,ida7.5完美编译出来,也就是说如果我们想要栈溢出,ret地址必须先签名后才能使用。
具体原理学习:
https://www.jianshu.com/p/62bf046b7701
https://juejin.cn/post/6883002562581102600
https://www.jianshu.com/p/03580e3a1a05
https://justinyan.me/post/4129
https://www.anquanke.com/post/id/171358
现在来看看函数:
漏洞点在lock:
漏洞点数组下标溢出,输入负数,可以达到name的位置:
来看看show函数
可以打印出来我们输入的值以及签名的值(负数溢出)
来看看auth:
先绕过逆向部分的sign,然后有个栈溢出漏洞给我们利用。
往name的地址写入逆向的key和ret地址,我们在lock中利用下标溢出使得他们签名成功,实现利用,完整的exp如下:(封装了ret2rsc的使用)
1 | # -*- coding: utf-8 -*- |
这题也可以用shellcode的方式去打(虽然我也好奇,aarch64没有执行权限的段也能执行shellcode?我觉得是checksec和vmmap的误判,因为qemu的原因~)
1 | aarch64_getshell_code = "\xe1\x45\x8c\xd2\x21\xcd\xad\xf2\xe1\x65\xce\xf2\x01\x0d\xe0\xf2\xe1\x8f\x1f\xf8\xe1\x03\x1f\xaa\xe2\x03\x1f\xaa\xe0\x63\x21\x8b\xa8\x1b\x80\xd2\xe1\x66\x02\xd4" |
1 | from pwn import * |
3、flag1
这题和flag0的那个逆向题是同一个文件,都是riscv64的架构。
首先下载个交叉编译链(别人写好的):
1 | https://static.dev.sifive.com/dev-tools/riscv64-unknown-elf-gcc-8.3.0-2019.08.0-x86_64-linux-ubuntu14.tar.gz |
将文件夹名字改成riscv64,打开长这样:
交叉编译链都在bin目录下,下面继续分析这个程序:
在做逆向时已经把程序逻辑搞清楚了,其实这题就是在利用gets进行栈溢出的操作,然后通过ghidra9.2的分析:
我们已经知道栈大小为0x120,这里调试用gef进行,因为这题开了沙箱,只能orw打印flag,所以我们需要做的是先找到放置参数的gadget,调用gets函数读取shellcode,然后跳转到shellcode的位置,这里先研究下shellcode怎么写,对于一种新的架构语言,写系统调用都是比较头疼的问题,这里总结一下方法:
1、用交叉编译链静态编译生成含有orw或者execve函数的程序
1 |
|
1 | ./riscv64-unknown-elf-gcc -static -o 1 1.c |
ghidra9.2分析汇编:
可以知道的信息就是li是将参数放到寄存器的操作,然后a0,a1,a2是函数调用的前3个参数寄存器,a7是系统调用号放置的寄存器,orw对应是0x400,0x3f,0x40,而execve好像没有系统调用号(奇奇怪怪的~)
下面我们需要做的就是书写汇编然后编译成程序来提取shellcode
1 | .global _start |
1 | ./riscv64-unknown-elf-gcc -c 1.s -o 1 |
C一下转成数据,cd操作依然有效:
shellcode成功提取出来:
1 | shellcode_int = [ |
现在我们只要调用一下gets读取shellcode然后跳转过去即可,这里需要先找下gadget,找到rop控制a0的指令,在0x11b12处,同时读入函数在0x16a5a(应该是gets)处,如果直接返回到gets,那会进入gets无限循环,我们可以控制到0x16a68的位置,只需要多控制s1指向stdin结构体,就不会因为lr寄存器无限循环了,最后跳转到shellcode的位置去执行:
1 | # -*- coding: utf-8 -*- |
这里猜测一下栈的位置也是不变的,盲猜爆破栈地址,实现跳栈上的shellcode,就像之前做那个arm的题目一样,以后有机会再试试看,因为栈是可以执行的。
二、RE
1、flag0
环境准备
这题是riscv64架构的题目,首先下载安装ghidra9.2,网盘地址是:
https://pan.baidu.com/s/1C9JYsPq0xvF5pGW8yefeaw
pass:e57x
因为9.2静态分析加入了对于riscv架构的反编译,也可以装个choco包管理器,然后在管理员状态下的命令行输入
1 | choco install ghidra |
同时为了进行动态调试,我们还需要搭建调试的环境,这里经过踩坑发现,只有ubuntu20下利用gdb9.2,装上最新版的gef插件,才能进行动态调试,这里给个gef的地址:
配置时只需要把pwndbg切换下即可,因为pwndbg和peda对于调试有点问题,不支持,所以用gef。
开始做题
先结合输出的字符串用ghidra定位到main函数的位置
找到了main函数的位置,但是因为反编译会报错,所以我们直接看汇编即可,这里先学习一下riscv64的汇编看看(略),最简单最快的方法就是自己写测试demo,然后生成.s文件去看汇编即可
1 |
|
1 | Dump of assembler code for function main: |
知道了a0和a1等是用来传参数的,返回值放到a0,然后继续分析:
这里通过动态调试发现,输入的字符长度是a3(strlen计算后的值),然后要check的字符串长度经过调试发现是0x59个字符,所以第一步输入长度确定了是89个字符,继续分析汇编以及动态调试:
malloc_store将flag后面的48位用堆块保存了起来(动态调试得到),同时分析store函数可知
store函数通过扩展将table1和table2的值以及我们的flag一起填充到栈上保存:
接着进行chacha20加密,其实说白了也就是和rc4一样,先初始化数据,再进行异或加密而已
这里提取出xor后stack上面进行异或的key(一共0x29个字符):
然后进行密文的check1,这里只check前0x29个字节
调用check1时动态调试获取到check的密文,一共0x29位:
这样第一部分的flag就可以解出来了:
1 | c = '88 e7 03 b4 36 cd 97 ab 5a a5 a6 0b df ce 08 3b 9d 90 32 3c 4e 15 14 bd 8d 38 38 b0 ee 2a bc 4b f9 aa 24 26 76 a3 a5 75 5e'.split(' ') |
下面继续运行看下第二层加密,针对后面48个字符,我们将断点下到tea那里,然后看下a0和a1的参数:
可以知道a0是我们的后48个字符,a1是我们tea算法的key:
分析下tea算法:
这里可以很清楚看到,除了while循环的轮转数从32变为16外,其他的不变,这里key和输入的明文都以int形式存储(动态调试可以知道),也就是4字节为单位,小端序,48个字符,就有12个4字节的数据,每次运算2个,所以只需要写个python脚本即可实现求解,现在继续寻找我们的check2密文,同样下断点然后看check的参数
4字节为单位,就是:
提取密文,我们再次写脚本求解即可
1 | k = [0x1368a0bb, 0x190ace1e , 0x35d8a357 ,0x26bf2c61] |
现在将2部分的脚本合并在一起即可:
1 | c = '88 e7 03 b4 36 cd 97 ab 5a a5 a6 0b df ce 08 3b 9d 90 32 3c 4e 15 14 bd 8d 38 38 b0 ee 2a bc 4b f9 aa 24 26 76 a3 a5 75 5e'.split(' ') |
最后检验下结果:
2、chinesegame
这题给了本地的附件,也就是本地输入正确,远程会回显flag回来,盲猜会执行cat flag命令,于是查找一波字符串:
确实有,交叉引用既可定位到main函数了,然后经过静态分析和动态调试,知道了函数的功能,更改函数名如下,方便自己理解:
逻辑很简单,首先初始化heap,动态调试会发现,init_heap完成后,会生成堆块链表,bk指针作为链接,fd指针存储值,然后输入我们的操作,这里只能输入0和1的字符,输入完,0和1分别有自己的handle函数,等输入全部处理完后退出,或者856次操作后才从for循环退出来(就算输入900个字符,第856次也会退出),我们再看下check函数:
check是检查是不是堆块中的所有值都是小于0x64(100),是的话就cat flag结束程序,现在重点就是分析那个0和1的操作在干什么?
看下0:
再看下1:
在for循环中我们可以知道,堆中数据的下标和table的下标满足这样的等式
1 | j = table[i]//获取到的值 |
根绝这个规则我们可以知道table前面2行的值对应修改的堆块下标关系:
1 | //table值 |
通过分析可以知道handle1和handle2的功能:
我们把大于100的数字看成1,小于100的看成0,那么2个handle函数能实现以下的转化关系
1 | 110000--->010000 //1->0 handle1功能,也就是输入0 |
如果第一个值是我们想要变换的值,需要满足它的下一位为1,再往后的其他全部位为0,才能把当前值从1变为0,也就是
1 | 110000--->010000 //1->0 handle1功能,也就是输入0 |
如果第一个值是我们想要变换的值且为0,需要满足它的下一位为1,再往后的其他全部位为0,才能把当前值从0变为1,也就是
1 | 010000--->110000 //0->1 handle2功能,也就是输入1 |
且最后一位可以随意变换,当最后一位为1时输入0可以变为0,当最后一位为0时输入1可以变为1,也就是
1 | 000000--->000001 //0->1 handle2功能,也就是输入1 |
1 | 000001--->000000 //1->0 handle1功能,也就是输入0 |
其实一开始我也自己研究了下,怎么利用上面的规则实现把所有的值变为小于0,但是搞了一波发现,好像有点难,但是也发现了好像有一些套路的,然后那个table里面的值对应改变堆块的值,要是遇到堆块的值为1,我们输入0,看能不能把堆块值变为0,如果遇到堆块值为0,输入1,看能不能把堆块值变为1,说干就干,以下是手动的测试例子:
1 | //原始值 |
通过演示可以知道,由table表可以知道堆下标,然后只要那个值为1,我们就输入0,使它变为0,如果它是0,我们就输入1,使它变为1,经过856次操作就可以把所有的都变换成小于0的数,现在我们可以写个exp脚本了:
1 | table = [0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000007, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000006, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000009, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000006, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000007, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000006, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000008, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000006, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000007, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000006, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x0000000A, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000006, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000007, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000006, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000008, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000006, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000007, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000006, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000009, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000006, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000007, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000006, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000008, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000006, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000007, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000006, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000005, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001, 0x00000004, 0x00000001, 0x00000002, 0x00000001, 0x00000003, 0x00000001, 0x00000002, 0x00000001,0,0x4058A,0] |
通过调试打印值可以发现在第852次就实现了全部变为0,所以输入就可以确定了
最后检验下
3、stream
先来看看程序的输入输出,打开失败,好像要有输入文件
ida查找字符调试一波:
交叉引用定位过去main函数的主要操作:
因为看不太懂rust语言,然后干脆直接动态调试查看逻辑好了,发现会打开flag文件,然后读取里面的字符,继续分析,先来看看一个随机数函数的生成:
这里经过动态调试发现传进去的flag的一个值作为一个种子进行了随机数的生成,然后随机数存储到stack上,然后这个值进行了异或加密存回去,然后pi的值加了7,第二次时,把前一次的种子和新种子放到一起进行加密生成随机数,这里可以知道每一次要进行随机数加密取的种子下标顺序:i
1 | pi = 4 |
这里可以知道因为是单字节加密,然后取明文的累积作为key生成的一个种子,所以知道了输入就知道了随机数。但是功底太差了,看不懂随机数是怎么生成的,只是知道了怎么加密的现在,继续分析:
最后是打开output文件,将加密后的密文放进去。
这里逻辑已经比较清楚了,我们要做的就是写个爆破脚本去一一碰撞check的密文即可,这里因为不同的明文值加密得到的可能是相同的密文值(动态调试结合写脚本尝试爆破时知道的),所以实际上是一棵树深度搜索的过程!只有一个可能是正确的或者说可能出现多解也不一定,反正能走到最后的根节点的都试试,自己写个脚本如下:
1 | import os |
其实我还想到用之前自己做的钩子程序,直接测试函数片段,把那个随机数生成函数提取出来,做逆向也可以(理论上),但是现在这种做法这样也不会慢到哪里去所以还是可以的,不说了,ex师傅牛逼!加深了自己对于深度搜索的学习,get新技能。
4、wherekey
这道题因为是静态编译的文件,所以我们先通过strings过滤字符串得知是ubuntu20下的程序,于是导入符号signal,恢复一下符号表,接着在通过字符串定位主逻辑时,f5时发现有花指令,这里去花指令的操作也比较简单,就是先定位到一大堆的机器码那里,先c一下,然后看跳转,接着nop掉没用的指令,然后将函数整体先u再p就可以实现f5的反编译了,去花完成得到主逻辑如下:
这里是通过tty和socket进行UDP交互的,绑定的8888端口
直接运行时没有问题的,select时选择的是本地的输入输出,在进行动态调试时,我们需要通过
1 | nc -u 127.0.0.1 8888 |
向调试程序发送输入的数据,然后在recvfrom时就会接收到我们的数据
接着主要逻辑就在0x4022de中,继续分析
这里初始化init时会将输入处理好:
可以得到每行取5个值:
1 | string='flag{are_you_sure_friend}' |
然后继续func函数处理,这里是将init里面的值和输入的值进行了乘法运算再相加,这里可以猜测是矩阵的乘法运算:
乘完取余再存储到table中,以矩阵的形式,最后进行了cmp比较
我们可以提取出密文crypto:
1 | enc=[0x38, 0x6D, 0x4B, 0x4B, 0xB9, 0x8A, 0xF9, 0x8A, 0xBB, 0x5C, 0x8A, 0x9A, 0xBA, 0x6B, 0xD2, 0xC6, 0xBB, 0x05, 0x90, 0x56, 0x93, 0xE6, 0x12, 0xBD, 0x4F] |
分析到这里其实已经比较明显了,就是个hill加密,所以我们要做的就是找到那个A的逆矩阵即可
1 | flag*A=C |
1 | //Sage求解 |
得到flag转成字符:
1 | *CTF{Ha23_f0n_9nd_G0od-1uck-OH} |
鉴于之前花指令和内嵌汇编做的少,这里也刚好可以学习一下操作,我看了下源码,大概了解了怎么使用:
1 |
|
内嵌汇编的形式加入到里面,其实也可以在pwn中相当于自己提前加想要的gadget,花指令可以起到扰乱逆向工程师分析的目的,同时sage在逆向中的运用还是可以学习一下的,在ubuntu装一个sage,以后也可以用:
1 | sudo apt install sagemath-common |