Shellcode 开发实验
文章目录
Task 1:编写 Shellcode
Task 1.a:整个过程
-
//使用 nasm 编译 nasm -f elf32 mysh.s -o mysh.o //链接以生成最终的二进制文件 ld -m elf_i386 mysh.o -o mysh //获取机器码和进程id echo $$ mysh //打印出二进制文件的内容 echo $$
-
31c050682f2f7368 682f62696e89e3505389e131d231c0b00bcd80
Task 1.b:从代码中消除零
- Q:xor eax eax的原因和好处
- 异或寄存器中相同的容得到的一定为0
- 做异或运算比赋值运算块,因为前者只需要再CPU内部计算,而后者需要访问内存
- 异或运算的使用的机器码少
Task 1.c:为系统调用提供参数
此处需要构建shellcode,调用/bin/sh -c “ls -la”。修改mysh.s的堆栈,同样需要在shellcode中没有字符0,以及程序可以正确执行,打印出当前文件夹中的文件内容
-
将命令分解为三个部分
/bin//sh -c ls - la
首先压入的是0,用来终止string,其次,根据4byte来划分,不足的时候可以补/ 或者补空格 。在连接指令的时候补/,在单个参数的时候补空格。最后是要取这个string的地址,用栈指针寄存器esp的值赋值给相应的寄存器保存每个字符串的地址。
-
验证:没有出现0
-
正确执行了构造的指令
-
注意:刚开始需要push eax阶段字符串;注意空格的位置,是否映像指令正常运行
Task 1.d:为系统调用提供参数
-
结果:
-
验证没有0
Task 2: Using Code Segment
-
编译链接并显示验证结果
-
检查shellcode没有0,满足要求
-
解释代码:
-
分析执行成功的原因:
-
执行execve()系统调用,查表可知 ,excve的调用号是0x0b,也就是说需要把这个值传递给eax,而在第二步就对eax置0,因此最后只对eax的低字节操作,使其得到0x0b的值
-
接着在ebx存放了函数调用的第一个参数,ecx存放第二个参数,edx存放第三个参数。
ebx存放的是字符串/bin/sh的地址。这里因为对*替换为了0,因此只读取到/bin/sh即可。
ecx是一个指针数组,存放的是第一个参数也就是ebx的地址
第三个参数是edx,没有环境变量,置空。最后系统调用好0x0b就存放在了eax寄存器中。
-
最后是通过int 0x80系统调用execve()即可
-
-
打印环境变量
-
仿照task1即可(这里参考了网络)
-
Task 3:编写 64 位 shellcode
- 没有0