akde/infosec

Information security is ultimately about managing risk


The stack can be pro­tect­ed against buffer overflows.

Stack protection with canaries

Like in a coal mine, a canary can pro­vide an indi­ca­tion if some­thing goes wrong. Here, a canary is a defined val­ues which is added between the buffer (where an attack­er will start writ­ing the pay­load) and the SFP Stack Frame Point­er and RP Return point­er. To over­write the RP Return Point­er, an attack­er has to over­write the canary as well. In the func­tion epi­log, the canary is always val­i­dat­ed. If it con­tains not the expect­ed val­ue, the pro­gram terminates.

Microsoft calls canaries secu­ri­ty cook­ies (?!).

If SSP Stack Smash­ing Pro­tec­tion is active and a process ter­mi­nates because of SSP, the error mes­sage will be the following:

*** stack smashing detected ***: <unknown> terminated

Types of canaries

  • A null canary con­tains only null bytes. (0x00000000)
  • A ter­mi­na­tor canary con­tains “bad char­ac­ters” for many func­tions like line­break, bina­ry zero, car­riage return, etc. (e.g. 0x000a0dff)
  • A ran­dom canary con­sists out of ran­dom bytes which are defined when the process starts.
    • To deter­mine a ran­dom canaries val­ue, an attack­er could try to guess the first byte 0x03 by over­writ­ing only one byte after the buffer. If the pro­gram exe­cu­tion stops, then this byte was wrong. If not, the val­ue was guess­es and he can repeat it until the whole canary is known.

Canaries in action

Let’s see how a canary works by dis­as­sem­bling a func­tion with gdb.

   ...
   0x08048541 <+18>:	mov    eax,DWORD PTR [ebp+0x8]
   0x08048544 <+21>:	mov    DWORD PTR [ebp-0x2c],eax
   0x08048547 <+24>:	mov    eax,DWORD PTR [ebp+0xc]
   0x0804854a <+27>:	mov    DWORD PTR [ebp-0x30],eax
   0x0804854d <+30>:	mov    eax,DWORD PTR [ebp+0x10]
   0x08048550 <+33>:	mov    DWORD PTR [ebp-0x34],eax
   0x08048553 <+36>:	mov    eax,gs:0x14
   0x08048559 <+42>:	mov    DWORD PTR [ebp-0xc],eax
   ...
   0x080485ab <+124>:	mov    edx,DWORD PTR [ebp-0xc]
   0x080485ae <+127>:	xor    edx,DWORD PTR gs:0x14
   0x080485b5 <+134>:	je     0x80485bc <testfunc+141>
   0x080485b7 <+136>:	call   0x80486b0 <__stack_chk_fail_local>
   0x080485bc <+141>:	mov    ebx,DWORD PTR [ebp-0x4]

In the first block, the canary is writ­ten. The sec­ond block is at the end of a func­tion and checks the canary. To see the canary, we can add a break­point at the last instruc­tion of the “canary pro­log” at 0x08048559 and inspect the con­tent of the eax reg­is­ter, which then con­tains the canary.

gdb-peda$ break *0x08048559
Breakpoint 1 at 0x8048559
gdb-peda$ run AAAAAAAAAAAAAAAAAAA BBB CCC
...
Breakpoint 1, 0x08048559 in testfunc ()
gdb-peda$ x/i $eip
=> 0x8048559 <testfunc+42>:	mov    DWORD PTR [ebp-0xc],eax
gdb-peda$ i r $eax
eax            0xff0a0000	0xff0a0000     <= Canary

Let’s try it again with eight A’s — which still should be possible.

gdb-peda$ run AAAAAAAA BBBB CCCC
...
Breakpoint 2, 0x0804856d in testfunc ()
gdb-peda$ x/20x $esp
0xffffd480:	0xffffd4b4	0xffffd709	0x00000000	0x0804853b
0xffffd490:	0xf7fb3c40	0xffffd717	0xffffd712	0xffffd709
0xffffd4a0:	0x080499f0	0xf7ffd940	0xf7e0ff65	0x0804851c
0xffffd4b0:	0x080486e0	0x41414141	0x41414141	0xff0a0000
0xffffd4c0:	0xf7fb33fc	0x080499f0	0xffffd4e8	0x08048621

Here are our A’s and the canary lies behind it. Good. Now lets try to fur­ther over­write the stack and set the prop­er canary.

gdb-peda$ run "AAAAAAAA `echo -e '\x00\x00\x0a\xffAAAAAAAASSSSRRRR'`" BBBBBBBB CCCCCCCC
...
Breakpoint 2, 0x0804856d in testfunc ()
gdb-peda$ x/20x $esp
0xffffd470:	0xffffd4a4	0xffffd6ee	0x00000000	0x0804853b
0xffffd480:	0xf7fb3c40	0xffffd713	0xffffd70a	0xffffd6ee
0xffffd490:	0x080499f0	0xf7ffd940	0xf7e0ff65	0x0804851c
0xffffd4a0:	0x080486e0	0x41414141	0x41414141	0x41ff0a20
0xffffd4b0:	0x41414141	0x53414141	0x52535353	0x00525252

That is not our canary. Bad. The prob­lem is that our bina­ry zeros were not copies because strcpy sees them as terminators.

Leave a Reply

About

Personal collection of some infosec stuff. Primary purpose of this site is to collect and organize for myself.

Note: Some content is not publicly visible due to copyright issues. Therefore, some links could be broken.

Checklists

Categories

Checklists: Ports

python -c 'import pty;pty.spawn("/bin/bash")';

python3 -c 'import pty;pty.spawn("/bin/bash")';