首页 > 系统相关 >shellcode编写实验

shellcode编写实验

时间:2024-10-30 16:43:31浏览次数:1  
标签:bin 压入 eax 地址 实验 字符串 编写 shellcode

 

 

 

作业题目

shellcode广泛用于许多涉及代码注入的攻击中。编写shellcode是相当有挑战性的。虽然我们可以很容易地从互联网上找到现有的shellcode,但是能够从头开始编写我们自己的shellcode总是令人兴奋的。shellcode中涉及到几种有趣的技术。本实验室的目的是帮助学生理解这些技术,以便他们能够编写自己的shellcode。

编写shellcode有几个挑战,一个是确保二进制文件中没有0x00,另一个是找出命令中使用的数据的地址。第一个挑战不是很难解决,有几种方法可以解决它。第二个挑战的解决方案导致了编写外壳代码的两种典型方法。在一种方法中,数据在执行期间被推入堆栈,因此可以从堆栈指针获得它们的地址。在第二种方法中,数据存储在代码区域中,就在调用指令之后,因此在调用调用函数时,其地址被推入堆栈(作为返回地址)。两种解决方案都非常优雅,我们希望学生能够学习这两种技术。

实验步骤及结果

Task 1.a: The Entire Process

  1. 分析mysh.s

execve()是用来执行新程序的系统调用。这个调用会替换当前进程的映像(包括代码和数据),用新的程序文件(通常是一个二进制文件)来加载到内存并开始执行。

shellcode 最核心的部分是使用 execve() 系统调用来执行“/bin/sh”。

使用这个系统调用,需要设置以下 4 个寄存器:

(1) eax 寄存器: 必须保存 11, 11 是 execve() 的系统调用号。

(2) ebx 寄存器: 必须保存命令字符串的地址 (如“/bin/sh”)。

(3) ecx 寄存器: 必须保存参数数组的地址。

(4) edx 寄存器: 必须保存想要传给新程序的环境变量的地址。

还需要注意,一些函数把 0 视作数据复制源的结尾,为了确保完整的代码被复制进目标缓冲区, 尽管程序中需要使用 0 值, 但不能让 0 在代码中出现。

xor eax, eax 可以将eax置为0而代码中不出现0。

捕获

A:栈一次只能压入4个byte,所以将字符串以4个byte分为一份。不够的补上一个“/”变成“//sh”(execve()还是会按照一个“/”处理)。最后把 0(eax) 压入栈中, 代表字符串 “/bin//sh’’ 的结束。

捕获捕获2

B:将字符串动态地压入栈,新添加的元素总是在栈顶,通过读取esp就能知道字符串的地址。把 esp 的内容放入 ebx,就是把命令字符串的地址保存到 ebx 寄存器中。

捕获捕获3

C:构造argv[]数组,数组的第一个元素指向字符串 “/bin//sh”, 第二个元素是 0, 标志着数组的末尾。ecx寄存器保存argv[]数组的地址。

D:edx设成 0, 不传递任何环境变量。

E:0xb=11,将eax保存为execve() 的系统调用号11。

F:寄存器(eax,ebx,ecx,edx)的值被正确设置, 执行“int $0x80”指令后, 系统调用 execve() 将开启一个 shell。

  1. 完成整个流程

task1

将.s文件编译为.o文件,再将.o文件编译为可执行文件mysh。打印当前shell的进程ID为3132,执行mysh后,进程ID为3391与之前不一样,说明mysh启动了一个新的shell。

task1.2task1.3

得到mysh.o的机器码(没有0)。

task1.4

使用convert.py将机器码转换为shellcode。

Task 1.b. Eliminating Zeros from the Code

“/bin/bash”一共9个byte,以4个byte为一组还差3个byte,但题目规定不能用“/”。

替换

将ebx向左移24位,“###”被丢弃,再向右移24位,变为“h000”,凑够了位数,又在不引入0的情况下使用0作为字符串结束符。

task1.6task1.7

运行后,成功开启一个新shell。

task1.8task1.9

机器码中没有0。

Task 1.c. Providing Arguments for System Calls

在mysh.s基础上进行修改:

捕获

将字符串压入栈,再将它们的存储地址存入寄存器中。(利用1.b中的方法保证代码中没有0并以4byte为一组)。

捕获

压入字符串存储地址,构造argv[]数组,再将argv[]数组地址存入ecx。

task2.2

运行后得到结果如上。

与直接执行命令“/bin/sh -c “ls -al””得到的结果对比:

task2.1

一致。

查看机器码:

task2.3task2.4

机器码中没有0。

Task 1.d. Providing Environment Variables for execve()

在mysh.s的基础上修改:

捕获

A:将命令字符串“/usr/bin/env”压入栈

B:将环境变量字符串压入栈。

“cccc=1234”不是4的倍数,以4byte分组后将多出来的“4”放入al中(al是eax的低八位),再将eax压入栈,使字符串完整入栈,且结束符也入栈。

存储字符串的地址存在eax里。

捕获2IMG_0194(20231019-105850)

将edx置为0,压入栈,再将eax压入栈(eax指向“cccc=123”所存储的地址)。在eax上加0xc,这时eax指向“bbb=5678”,压入eax,将“bbb=5678”的存储地址压入了栈中,压入“aaa=1234”的存储地址同理。

运行代码:

task3

成功打印环境变量。

查看机器码:

task3.2task3.3

机器码中没有0。

Task 2: Using Code Segment

逐行解释代码:

task4

捕获

(1)why this code would successfully execute the /bin/sh program, how the argv[] array is constructed?

代码创建了命令字符串“/bin/sh”和占位符构成的字符串,通过函数调用会存储返回地址(原函数下一条指令)的原理,使用pop得到字符串的地址,通过这个地址,我们修改代码段,为命令字符串加上结束符,将原本的占位符“AAAA”替换为命令的地址,“BBBB”替换为0,构造argv[]数组。最后,做好系统调用execve()前的准备(为eax,ebx,ecx,edx设置正确的值),调用execve(),执行“/bin/sh”开启新的shell。

(2)

task6.2

创建一个字符串‘/usr/bin/env****argv****aa=11*bb=22*env1env2****’,再将字符串替换为‘/usr/bin/env%0%0%0%0

(/usr/bin/env的地址)

%0%0%0%0

aa=11%0bb=22%0

(aa=11的地址)(bb=22的地址)%0%0%0%0’

再将eax,ebx,ecx,edx设置为应该的值,系统调用execve()。

默认情况下,代码段不可写的,所以,在运行链接器程序(ld)时,我们需要使用——omagic选项让代码段可写。

执行:

task6

成功。

Task 3: Writing 64-bit Shellcode

对于x64体系结构,调用系统调用是通过系统调用指令完成的,系统调用的前三个参数分别存储在rdx、rsi、rdi寄存器中。

IMG_0195(20231019-194248)

代码如下:

task7.3

在64-bit shellcode中,以8byte为一组分割命令字符串,将字符串存入rax,再将rax压入栈。

执行代码:

task7

成功。

查看机器码:

task7.2

机器码中没有0。

如果直接使用 push “/bin/bas” 压入栈,会遇到关于“立即数超出边界”的警告,最终导致segmentation fault。

捕获

标签:bin,压入,eax,地址,实验,字符串,编写,shellcode
From: https://www.cnblogs.com/wxrwajiez/p/18516097

相关文章

  • 环境变量与set-uid实验
       作业题目本实验室的学习目标是让学生了解环境变量如何影响程序以及系统行为。环境变量是一组动态命名值,可以影响正在运行的进程将在计算机上运行。大多数操作系统都使用它们,因为它们是1979年引入Unix。尽管环境变量会影响程序行为,但它们是如何实现的这一点很多程序员都......
  • XSS攻击实验(Elgg)
       作业题目跨站点脚本(XSS)是一种常见于web应用程序中的计算机安全漏洞。此漏洞使攻击者有可能将恶意代码(如JavaScripts)注入受害者的web浏览器。为了演示攻击者可以做什么,我们在预先构建的UbuntuVM映像中设置了一个名为Elgg的web应用程序。我们已经注释掉了Elgg的一些保护......
  • 实验 1:域名信息收集工具
    作业题目本次实验主要考察大家的编程能力及子域名的信息收集方法,在文件夹“Lab1_code”提供了使用Bing搜索引擎的域名收集功能。请对该代码进行扩展,使其可支持百度搜索引擎的域名收集功能。需要实现如下功能:a)支持百度搜索引擎的域名提取,其中从百度搜索引擎提取的域名需......
  • Javaweb 实验6 JSP内置对象
    我发现了有些人喜欢静静看博客不聊天呐,但是ta会点赞。这样的人呢帅气低调有内涵,美丽大方很优雅。说的就是你,不用再怀疑哦目的:掌握JSP内置对象的使用。理解JSP的作用域掌握JSP的表达式使用实验要求:完成实验题目要求提交实验报告,将代码和实验结果页面截图放入报告中第......
  • 实验3
    task11#include<stdio.h>23charscore_to_grade(intscore);4intmain(){5intscore;6chargrade;78while(scanf("%d",&score)!=EOF){9grade=score_to_grade(score);10printf(&quo......
  • 实验三
    实验一源代码#include<stdio.h>charscore_to_grade(intscore);intmain(){intscore;chargrade;while(scanf("%d",&score)!=EOF){grade=score_to_grade(score);printf("分数;%d,等级:%c\n\n",score......
  • 实验2 类和对象_基础编程1
    实验任务1头文件#pragmaonce#include<string>//类T:声明classT{ //对象属性、方法public: T(intx=0,inty=0);//普通构造函数 T(constT&t);//复制构造函数 T(T&&t);//移动构造函数 ~T();//析构函数 voidadjust(intratio); voiddispla......
  • 实验3_C语言函数应用编程
    task1:输入分数,返回等级有问题。当输入高于E等级对应的分数时,函数返回值将是从该等级到E等级全部等级,如输入9将返回BCDE。 #include<stdio.h>charscore_to_grade(intscore);//函数声明intmain(){intscore;chargrade;while(scanf("%d",&score)!......
  • 实验3
    任务11#include<stdio.h>2charscore_to_grade(intscore);3intmain(){4intscore;5chargrade;6while(scanf("%d",&score)!=EOF){7grade=score_to_grade(score);8printf("分数:%d,等级:%c\n\n......
  • makefile如何编写?
    什么是makefile?        makefile文件中定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令. makefile带来的好处就是——“......