二进制安全虚拟机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变量=0
  gets(buffer);             //获取我们的输入,赋予到buffer变量里

  if(modified != 0) {               //如果modified不等于0
      printf("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

在这里插入图片描述

然后继续运行程序

在这里插入图片描述

破解成功

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【洛谷】P3853 路标设置

原题链接&#xff1a;https://www.luogu.com.cn/problem/P3853 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 整体思路&#xff1a;二分答案 由题意知&#xff0c;公路上相邻路标的最大距离定义为该公路的“空旷指数”。在公路上增设一些路标&…

【ELK日志收集系统】

目录 一、概述 1.作用 2.为什么使用&#xff1f; 二、组件 1.elasticsearch 1.1 作用 1.2 特点 2.logstash 2.1 作用 2.2 工作过程 2.3 INPUT 2.4 FILETER 2.5 OUTPUTS 3.kibana 三、架构类型 1.ELK 2.ELKK 3.ELFK 4.ELFKK 四、案例 - 构建ELK集群 1.环境…

MFC网络编程简单例程

目录 一、关于网络的部分概念1 URL(网址)及URL的解析2 URL的解析3 域名及域名解析3 IP及子网掩码4 什么是Web服务器5 HTTP的基本概念6 Socket库概念7 协议栈8 Socket库收发数据基本步骤 二、基于TCP的网络应用程序三、基于UDP的网络应用程序 一、关于网络的部分概念 1 URL(网址…

git在windows上安装

介绍git工具在windows上如何安装 git官网下载地址 1.1、下载 https://github.com/git-for-windows/git/releases/download/v2.36.0.windows.1/Git-2.36.0-64-bit.exe自行选择版本&#xff0c;这里我选择的是 Git-2.36.0-64-bit这个版本 1.2、安装 安装路径选择英文且不带空格…

【计算机网络】HTTP

文章目录 1.HTTP概念2. URLurlencode 和 urldecode转义规则 3. HTTP的宏观理解HTTP的请求HTTP的响应 4. 见一见HTTP请求和响应请求报头 1. 模拟一个简单的响应response响应报头 2. 从路径中获取内容ReadFile函数的实现 3.不同资源进行区分反序列化的实现ReadOneLine函数的实现P…

docker-compose 部署nacos 整合 postgresql 为DB

标题docker-compose 部署nacos 整合 postgresql 为DB 前提&#xff1a; 已经安装好postgresql数据库 先创建好一个数据库 nacos&#xff0c;执行以下sql: /** Copyright 1999-2018 Alibaba Group Holding Ltd.** Licensed under the Apache License, Version 2.0 (the "…

Java:Springboot和React中枚举值(数据字典)的使用

目录 1、开发中的需求2、实现效果3、后端代码4、前端代码5、接口数据6、完整代码7、参考文章 1、开发中的需求 开发和使用过程中&#xff0c;通常会涉及四个角色&#xff1a;数据库管理员、后端开发人员、前端开发人员、浏览者 数据库使用int类型的数值进行存储&#xff08;e…

POSTGRESQL WAL 日志问题合集之WAL 如何解析

开头还是介绍一下群&#xff0c;如果感兴趣polardb ,mongodb ,mysql ,postgresql ,redis 等有问题&#xff0c;有需求都可以加群群内有各大数据库行业大咖&#xff0c;CTO&#xff0c;可以解决你的问题。加群请加 liuaustin3微信号 &#xff0c;在新加的朋友会分到3群 &#xf…

最小二乘法处理线性回归

最小二乘法是一种数学优化技术&#xff0c;用于查找最适合一组数据点的函数。 该方法主要用于线性回归分析&#xff0c;当然&#xff0c;也可用于非线性问题。 开始之前&#xff0c;我们先理解一下什么是回归。 回归&#xff1a;回归是一种监督学习算法&#xff0c;用于建模和…

MySql时间

一、查询 查询mysql当前时间 SELECT now();查询mysql时区 show variables like%time_zone;二、修改时区 set global time_zone 8:00; &#xff08;修改mysql全局时区为北京时间&#xff0c;也就是我们所在的东8区&#xff0c;需要root权限&#xff09; set time_zone 8:0…

销量蹭蹭上涨!亚马逊上这几款宿舍神器火爆了!

一、BedShelfie床边置物架 每年返校季&#xff0c;收纳工具都是最畅销的产品。在亚马逊床头柜热销榜单中&#xff0c;这款产品位居第二。过去一个月里&#xff0c;有1000多名用户购买了这件产品。 二、U Brands磁性干擦日历板 目前&#xff0c;亚马逊上这款产品已经卖到断货。…

自建音乐服务器Navidrome之一

这里写自定义目录标题 1.1 官方网站 2. Navidrome 简介2.1 简介2.2 特性 3. 准备工作4. 视频教程5. 界面演示5.1 初始化页5.2 专辑页 前言 之前给大家介绍过 Koel 音频流服务&#xff0c;就是为了解决大家的这个问题&#xff1a;下载下来的音乐&#xff0c;只能在本机欣赏&…

The remote endpoint was in state [TEXT_FULL_WRITING]

报这个错是因为在websocket接收与发送消息时&#xff0c;资源互抢造成的&#xff0c;有很多帖子说将session锁住&#xff0c; 但是同一个账号多个客户端登陆的时候&#xff0c;session是不同的&#xff0c;所以只能锁住一个session&#xff0c;还是出现这个问题。 解决办法&a…

Go 官方标准编译器中所做的优化

本文是对#102 Go 官方标准编译器中实现的优化集锦汇总[1] 内容的记录与总结. 优化1-4: 字符串和字节切片之间的转化 1.紧跟range关键字的 从字符串到字节切片的转换&#xff1b; package mainimport ( "fmt" "strings" "testing")var cs10086 s…

正则表达式练习

(function() {//#region 定义正则表达式// const reg /前端/g;// ------------test-------------// const res reg.test("学java,找黑马");// console.log(res)// ------------exec--------------// const res reg.exec("学好前端&#xff0c;找黑马"…

【调试经验】Ubuntu22.04 安装和配置MySQL 8.0.34

本文共计1469字&#xff0c;预计阅读时间5分钟 在安装新版本的MySQL到电脑时&#xff0c;按着网上一些教程执行发现错误繁多&#xff0c;最后索性自己摸索并把服务装好了。自己也整理了一下在操作时的笔记&#xff0c;上传上来希望能帮助到大家。 目录 正文 安装MySQL 配置…

串口接收数据-控制LED灯

目标 通过串口接收数据&#xff0c;对数据分析&#xff0c;控制8个LED灯按照设定时间闪烁。 8个LED灯可以任意设计&#xff0c;是否闪烁。闪烁时间按ms计算&#xff0c;通过串口发送&#xff0c;可设置1~4,294,967,296ms&#xff0c;也就是4字节数据协议自拟&#xff0c;有数…

Oracle21C--Windows卸载与安装

卸载方法&#xff1a; &#xff08;1&#xff09;WinR&#xff0c;输入services.msc,打开服务&#xff0c;把Oracle相关的服务全部停止运行&#xff08;重要&#xff09; &#xff08;2&#xff09;WinR&#xff0c;输入regedit&#xff0c;打开注册表&#xff0c;删除Oracle开…

MATLAB中circshift函数转化为C语言

背景 有项目算法使用matlab中circshift函数进行运算&#xff0c;这里需要将转化为C语言&#xff0c;从而模拟算法运行&#xff0c;将算法移植到qt。 MATLAB中circshift简单介绍 circshift是循环移位函数。可以使用于数组和矩阵元素的循环移位。 当A是数组 Bcircshift(A,p);如果…

虚拟世界指南:从零开始,一步步教你安装、配置和使用VMware,镜像ISO文件!

本章目录 CentOS简介镜像下载一、新建虚拟机&#xff08;自定义&#xff09;1、进入主页&#xff0c;在主页中点击“创建新的虚拟机”2、点击创建虚拟机创建自己的虚拟机。可以选择自定义3、在“硬件兼容性(H)中选择&#xff1a;Workststion 15.x” ->下一步4、选择“稍后安…