简体   繁体   English

简单的“Hello-World”,Windows的无空shellcode需要

[英]Simple “Hello-World”, null-free shellcode for Windows needed

I would like to test a buffer-overflow by writing "Hello World" to console (using Windows XP 32-Bit). 我想通过将“Hello World”写入控制台(使用Windows XP 32位)来测试缓冲区溢出。 The shellcode needs to be null-free in order to be passed by "scanf" into the program I want to overflow. shellcode需要为null,以便通过“scanf”传递到我想要溢出的程序中。 I've found plenty of assembly-tutorials for Linux, however none for Windows. 我已经找到了很多适用于Linux的汇编教程,但是没有适用于Windows的汇编教程。 Could someone please step me through this using NASM? 有人可以使用NASM来指导我吗? Thxxx! Thxxx!

Assembly opcodes are the same, so the regular tricks to produce null-free shellcodes still apply, but the way to make system calls is different. 汇编操作码是相同的,因此产生无空shellcode的常规技巧仍然适用,但是进行系统调用的方式不同。

In Linux you make system calls with the "int 0x80" instruction, while on Windows you must use DLL libraries and do normal usermode calls to their exported functions. 在Linux中,您可以使用“ int 0x80”指令进行系统调用,而在Windows中,您必须使用DLL库并对它们的导出函数进行常规的用户模式调用。

For that reason, on Windows your shellcode must either: 因此,在Windows上,您的shellcode必须:

  • Hardcode the Win32 API function addresses (most likely will only work on your machine) 硬编码Win32 API函数地址(最有可能只适用于您的计算机)
  • Use a Win32 API resolver shellcode (works on every Windows version) 使用Win32 API解析器shellcode(适用于每个Windows版本)

If you're just learning, for now it's probably easier to just hardcode the addresses you see in the debugger. 如果您只是在学习,那么现在就硬编码在调试器中看到的地址可能会更容易。 To make the calls position independent you can load the addresses in registers. 要使呼叫位置独立,可以将地址加载到寄存器中。 For example, a call to a function with 4 arguments: 例如,调用具有4个参数的函数:

PUSH 4                  ; argument #4 to the function
PUSH 3                  ; argument #3 to the function
PUSH 2                  ; argument #2 to the function
PUSH 1                  ; argument #1 to the function
MOV EAX, 0xDEADBEEF     ; put the address of the function to call
CALL EAX

Note that the argument are pushed in reverse order. 请注意,参数以相反的顺序推送。 After the CALL instruction EAX contains the return value, and the stack will be just like it was before (ie the function pops its own arguments). 在CALL指令之后,EAX包含返回值,并且堆栈将像以前一样(即函数弹出自己的参数)。 The ECX and EDX registers may contain garbage, so don't rely on them keeping their values after the call. ECX和EDX寄存器可能包含垃圾,因此不要依赖它们在调用后保持其值。

A direct CALL instruction won't work, because those are position dependent. 直接的CALL指令将无效,因为它们取决于位置。

To avoid zeros in the address itself try any of the null-free tricks for x86 shellcode, there are many out there but my favorite (albeit lengthy) is encoding the values using XOR instructions: 为了避免地址本身为零,请尝试使用x86 shellcode的任何无空技巧,那里有很多,但是我最喜欢的(尽管很长)是使用XOR指令对值进行编码:

MOV EAX, 0xDEADBEEF ^ 0xFFFFFFFF   ; your value xor'ed against an arbitrary mask
XOR EAX, 0xFFFFFFFF                ; the arbitrary mask

You can also try NEG EAX or NOT EAX (sign inversion and bit flipping) to see if they work, it's much cheaper (two bytes each). 您还可以尝试NEG EAX或NOT EAX(符号反转和位翻转)以查看它们是否有效,它更便宜(每个两个字节)。

You can get help on the different API functions you can call here: http://msdn.microsoft.com 您可以获得有关可以在此处调用的各种API函数的帮助: http : //msdn.microsoft.com

The most important ones you'll need are probably the following: 您需要的最重要的内容可能是:

The first launches a command, the next two are for loading DLL files and getting the addresses of its functions. 第一个启动命令,接下来的两个用于加载DLL文件并获取其功能的地址。

Here's a complete tutorial on writing Windows shellcodes: http://www.codeproject.com/Articles/325776/The-Art-of-Win32-Shellcoding 这是有关编写Windows Shellcode的完整教程: http : //www.codeproject.com/Articles/325776/The-Art-of-Win32-Shellcoding

Assembly language is defined by your processor, and assembly syntax is defined by the assembler (hence, at&t, and intel syntax) The main difference (at least i think it used to be...) is that windows is real-mode (call the actual interrupts to do stuff, and you can use all the memory accessible to your computer, instead of just your program) and linux is protected mode (You only have access to memory in your program's little cubby of memory, and you have to call int 0x80 and make calls to the kernel, instead of making calls to the hardware and bios) Anyway, hello world type stuff would more-or-less be the same between linux and windows, as long as they are compatible processors. 汇编语言由处理器定义,汇编语法由汇编程序定义(因此,at&t和intel语法)主要区别(至少我认为它曾经是......)是windows是实模式的(调用实际的中断处理工作,您可以使用计算机可访问的所有内存,而不仅仅是使用程序),并且linux是受保护的模式(您只能在程序的小块内存中访问内存,并且必须调用int 0x80并调用内核,而不是调用硬件和BIOS)无论如何,只要它们是兼容的处理器,hello world类型的东西在linux和windows之间或多或少都是相同的。

To get the shellcode from your program you've made, just load it into your target system's debugger (gdb for linux, and debug for windows) and in debug, type d (or was it u? Anyway, it should say if you type h (help)) and between instructions and memory will be the opcodes. 要从您制作的程序中获取shellcode,只需将其加载到目标系统的调试器中(对于Linux为gdb,对于Windows为debug),然后在调试中键入d(或者是u?无论如何,它应该说明您是否键入h(帮助)),指令和内存之间将是操作码。 Just copy them all over to your text editor into one string, and maybe make a program that translates them all into their ascii values. 只需将它们全部复制到文本编辑器中,然后创建一个程序,将它们全部转换为ascii值。 Not sure how to do this in gdb tho... 不确定如何在gdb中执行此操作...

Anyway, to make it into a bof exploit, enter aaaaa... and keep adding a's until it crashes from a buffer overflow error. 无论如何,要使其成为bof漏洞,请输入aaaaa ...并继续添加a直到它由于缓冲区溢出错误而崩溃。 But find exactly how many a's it takes to crash it. 但是,要确切找出使它崩溃所需的数量。 Then, it should tell you what memory adress that was. 然后,它应该告诉您那是什么内存地址。 Usually it should tell you in the error message. 通常它应该在错误消息中告诉你。 If it says '9797[rest of original return adress]' then you got it. 如果它显示“ 9797 [原始原始地址的其余部分]”,那么您就明白了。 Now u gotta use ur debugger to find out where this was. 现在,您必须使用ur调试器来找出问题所在。 disassemble the program with your debugger and look for where scanf was called. 使用调试器反汇编程序,并查找调用scanf的位置。 Set a breakpoint there, run and examine the stack. 在那里设置断点,运行并检查堆栈。 Look for all those 97's (which i forgot to mention is the ascii number for 'a'.) and see where they end. 寻找所有那些97(我忘了提到的是'a'的ascii数字。)并看看它们的结束位置。 Then remove breakpoint and type the amount of a's you found out it took (exactly the amount. If the error message was "buffer overflow at '97[rest of original return adress]" then remove that last a, put the adress you found examining the stack, and insert your shellcode. If all goes well, you should see your shellcode execute. 然后删除断点并键入您发现用过的a的数量(确切的数量。如果错误消息是“ '97处的缓冲区溢出[原始返回地址的其余部分]”,然后删除最后一个a,则将您发现的地址放入检查中堆栈,并插入你的shellcode。如果一切顺利,你应该看到你的shellcode执行。

Happy hacking... 骇客入侵...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 对 Docker-On-Windows 尝试运行 hello-world 进行故障排除 - Troubleshoot Docker-On-Windows attempt to run hello-world 无法在Windows 7上的docker中运行默认的hello-world程序 - Not able to run the default hello-world program in docker on Windows 7 Windows上的docker工具箱,然后docker run hello-world获取x509:未知授权机构签名的证书 - docker toolbox on windows then docker run hello-world gets x509: certificate signed by unknown authority Docker:执行'docker run hello-world'命令时出错 - Docker: Error while executing 'docker run hello-world' command x86 ASM中的简单Hello World-Windows控制台 - Simple Hello World in x86 ASM - Windows console 适用于Windows 7的Docker-获取https://registry-1.docker.io/v1/repositories/library/hello-world/tags/latest:x509:未知授权机构签署的证书 - Docker for windows 7- Get https://registry-1.docker.io/v1/repositories/library/hello-world/tags/latest: x509: certificate signed by unknown authority 在Windows 7上构建React Native Hello World APK所需的最低软件是什么? - What is the minimum software needed to Build a React Native Hello World APK on Windows 7 当我在docker中运行`docker run hello-world`时,已连接的主机无法响应 - connected host has failed to respond when I run `docker run hello-world` in docker 由Windows运行的简单“Hello World!”控制台应用程序崩溃TaskScheduler(1.0) - Simple “Hello World!” console application crashes when run by windows TaskScheduler (1.0) Docker“ hello-world”给出“进程无法访问该文件,因为该文件正在被另一个进程使用” - Docker “hello-world” is giving “process cannot access the file because it is being used by another process”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM