导言
作为一个Pwn手,在经历ccb下午渗透赛只能给队友提供情绪价值去看应急响应被内核马戏耍后,~~痛定思痛,~~决定学习一些应急响应,为队友提供一些绵薄之力
前置工具
仅需Xshell8
Webshell应急响应
概念
首先介绍Webshell是什么
WebShell 是攻击者上传到服务器的一种恶意脚本文件,可以像后门一样远程控制服务器,可以做到但不限于如下功能:
1 | 查看/下载/上传文件 |
而其应急响应指的是在发现服务器或网站被植入WebShell(一种通过Web页面远程控制服务器的恶意脚本)后的快速处置和修复过程,其目的是尽快阻止攻击者的进一步操作、查明入侵路径、修复漏洞并恢复系统安全状态。
查杀手段
特征值搜索
首先是确定文件类型,一般而言在Web中容易成为恶意脚本文件的文件后缀是jsp,php,asp,aspx
,刚开始的时候可以从这种文件类型着手调查。
然后是查找特征值,常见后门函数是exec(),eval(),system(),assert(),base64_decode()
等,如果能查到是最好,不能的话就只能从其它方面入手
日志搜寻
Webshell的执行时通常在web日志中留下痕迹**(不是系统日志),我们通常需要在海量的请求中寻找异常的操作。通常是看哪个请求平时是GET此时却是POST**,并且返回状态码200(成功执行)。那这个请求路径就很有可能是Webshell,但也不能完全确定,还是得输出看看文件内容是什么
1 | 状态码补充 |
使用工具
相比于人工排查,使用工具的效率显然是更加高效,这里主要就推荐两个一个是D盾,一个是微步在线的云沙箱
D盾的优势是界面简洁、清晰明了,最重要的是无需网络要求,是线下比赛的好帮手
而云沙箱胜在功能强大,唯一的缺点是没有钞能力就只能体验,免费版每日分析有限
解题步骤
黑客webshell里面的flag flag{xxxxx-xxxx-xxxx-xxxx-xxxx}
在Xshell中通过把主机改成玄机靶场提供的IP,端口默认22,输入靶机的账号密码即可成功连接靶机
在开始链接后,得先回到根目录,不然没有回显
Linux根目录下各文件夹和文件的作用
目录 | 作用说明 |
---|---|
/bin |
存放基本用户命令,如 ls 、cp 、mv 、bash 等,单用户模式下也可使用。 |
/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 |
系统管理员命令,如 iptables 、reboot 、fsck 等,通常不供普通用户使用。 |
/srv |
服务数据目录,Web、FTP 等服务可在此处放数据(如 /srv/www/ )。 |
/sys |
内核虚拟文件系统,暴露设备、驱动等结构,供用户空间与内核交互。 |
/tmp |
临时文件目录,系统重启时可能会清空,用户和程序常用于临时写文件。 |
/usr |
用户程序和共享资源目录,包括大部分程序和库,如 /usr/bin 、/usr/lib 。 |
/var |
可变数据目录,如日志(/var/log )、邮件、缓存、数据库数据等。 |
当然这么多文件夹一个个找是不现实的,我们得找到特定的文件,肯定需要需要借助Linux的指令取寻找特定的文件
find [路径] [行为模式] [表达式]
例如我们想查找php的危险函数,就用如下表达式
1 | find ./ -type f -name "*.php" | xargs grep "eval(" |
找其它类型文件的危险函数也同上
如果想查询免杀马是否采用了某种编码进行隐藏,可用如下指令
1 | find ./ type f -name "*.php" | xargs grep "base64_decode" |
经过查找,发现确实有两个webshell,但是只有一个有flag
这一串字符就是flag
分析一下这个webshell做了什么吧
@session_start()
启动了会话,@
用于抑制任何可能的错误信息输出和警告
@set_time_limit(0)
设置了时间无限,意味着该脚本可以无限时长存在
@error_reporting
禁止错误输出,更加保险
1 | function encode($D,$K){ |
以$K
为密钥将$D
进行数据加密,隐藏恶意输入的内容
$payloadName='payload'
定义一个常量,表示存储恶意输入的会话的键名
$key='3c6e0b8a9c15224a'
密钥
$data=file_get_contents("php://input")
获取php://input
流数据
1 | if ($data!==false){ |
如果data是否成功读取了数据,成功就通过key进行加密
1 | if (isset($_SESSION[$payloadName])){ |
首先检查会话中是否有payloadName,若存在就将payload再通过key加密,然后检测payload的加密数据中是否存在getBasicsInfo
,若不存在,就再次加密,然后再执行payload中的字符串
@run($data)
会尝试执行data中的命令,然后通过key加密再echo出,这样可以隐藏返回数据,使恶意代码不易被查看
1 | }else{ |
若是会话中不存在payloadName,则会直接检查流数据中是否存在getBasicsInfo
,若存在,则会将加密后的data数据存储如会话中,便于再后续请求中继续利用该恶意代码
黑客使用的什么工具的shell github地址的md5 flag{md5}
将这些代码直接丢进安恒云沙箱里,这个可以检测出是什么类型的病毒,方便我们找flag
确定是哥斯拉木马,只需要找它的github项目地址就行,网上一搜有好些,最终找到如下
1 | https://github.com/BeichenDream/Godzilla |
再md5一下就好
黑客隐藏shell的完整路径的md5 flag{md5} 注 : /xxx/xxx/xxx/xxx/xxx.xxx
题目明说了是隐藏,所以无法直接ls查询到,寻找隐藏文件的指令如下
1 | ls -al |
不过其实我们在最开始的时候就找到了,就是**.Mysqli.php**文件,路径如下
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
里有什么
已知我们是webshell,所以不在系统日志里找,得在web日志里,而我们又看到了apache2
,就很可能在apache(最流行的 Web 服务器之一)里的日志里有免杀马的信息
我们直接看access.log
,发现有几个可疑请求
我们先看/data/tplcache/top.php
看起来是个很正常的php代码,是一个管理系统,那我们看下一个/wap/top.php
我们来解析这串代码
<?php
是php代码的标准开头
$key = "password"
定义了一个密钥
$fun = base64_decode($_GET['func'])
请求fuc的资源并进行base64解码(ERsDHgEUC1hI),将解码内容赋值给fun。不过我很好奇为什么日志里是fuc才拥有这串字符串,可仍然能请求资源成功
1 | for($i=0;$i<strlen($fun);$i++){ |
进行异或操作,算是将混淆的内容进行解密,解密内容是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