文件上传反制跳板站点

本篇文章主要介绍一次通过黑客跳板站点,获取攻击者IP案例。利用前期的信息收集对跳板站点进行渗透测试,一步步取证攻击者的攻击手法、工具和IP的过程。

一、事件背景

这篇文章主要介绍实操利用文件上传漏洞对跳板站点反制。这个C2来自于某方向分析报告。攻击者黑了一批正常网站然后往上面丢了诱饵文档。利用此类结合了时事热点的恶意样本再对周边国家和地区发起了多次攻击活动。

网站首页中被插入了一个iframe,该iframe会判断用户IP等信息,若是目标用户则下发木马给受害者。

二、反制过程

对事件分析的完整溯源需要明确的是who(对手、受害者), what(基础设施、能力), when(时间), where(地点), why(意图), how(方法),通过聚焦于IOC的分析、包括对事件分析、样本类型的分析,IOC的提取、威胁情报产生是各大安全厂商有力的分析手段,为事件分析提供了坚实的数据来源。而对反制攻击者基础设施获取数据对形成攻击者画像,完善攻击者链条起到了线索弥补和数据源扩充的作用。

信息收集

前文介绍了端口扫描、目录扫描的信息收集方式,Google hacking也是信息收集中的常用渠道,因为Google搜索引擎本身提供了各种搜索语法,搜索时配合这些语法可以获取到更加精确的结果,而利用语法加上特定关键字可以搜索到目标站点的目录、文件报错等重要信息。

以下是google搜索引擎自带的基础常用语法。:

intitle: 以网页标题中关键字搜索 
inurl: 从url中存在的关键字进行搜索匹配 
Iintext:以网页正文中的关键字进行搜索 
filetype:搜索指定的文件后缀
Site:指定域名
link:例如link:www.google.com表示搜索所有链接了google.com的url

常用的通配符:

+  :强制包含某个字符进行查询
-  :查询时忽略某个字符
"" :查询时精确匹配双引号内的字符
.  :匹配某单个字符进行查询

而对端口、目录扫描的信息收集方式,我写了个bash脚本,半自动化完成端口扫描,然后用NMAP对端口服务识别以及对每个端口做目录扫描。代码如下:

#!/bin/bash
if [ $# != 1 ] ; then
echo "USAGE: $0 TABNAME"
echo " e.g.: $0 111.222.333.444"
exit 1;
fi

## 传入参数
scanip=$1
# 设置dirsearch目录
dirsearch="/opt/dirsearch/"
# 保存的目录位置
resultSave=`pwd`"/result/"${scanip}
# 时间保存
dateStr=`date +"%Y-%m-%d"`

# 端口扫描
portscan(){
echo "result to "${resultSave}
## 判断目录是否存在,不存在就创建目录
if [ ! -d "$resultSave" ];then
  mkdir -p ${resultSave}
fi
echo "masscan scaning.............."
echo "masscan -p1-65535 ${scanip} --rate=10000 -oL ${resultSave}/${scanip}"
## 写死了masscan命令
masscan -p1-65535 "${scanip}" --rate=10000 -oL ${resultSave}"/"${scanip}
echo "masscan result.............."
cat ${resultSave}"/"${scanip}
## 读取masscan的扫描结果做处理只提取端口部分
for  line  in  `awk '{print $3}'  ${resultSave}/${scanip}`
do
portscan=${line}','
echo -n ${portscan} >> ${resultSave}/nmapTemp
done
## 写死了nmap命令
nmapStr="nmap -v -A -O  ${scanip} -p "
## 处理NMAP端口和导出文件格式
NmapPort=`sed '$s/.$//' ${resultSave}/nmapTemp`
NmapSave=" -oN ${resultSave}/portRes${dateStr}.txt"
echo "nmap scaning.............."
echo ${nmapStr}${NmapPort}${NmapSave}
## 执行nmap命令识别服务
${nmapStr}${NmapPort}${NmapSave}
## 删除端口扫描临存数据
rm -rf ${resultSave}/nmapTemp
}

## dirscan目录扫描
dirscan(){
for  line  in  `awk '{print $3}' ${resultSave}/${scanip}`
do
   echo "python3 ${dirsearch}${scanip}:${line} -e * -R 1"
   /usr/bin/python3 ${dirsearch}dirsearch.py -u http://${scanip}:${line} -e * -R 1
   /usr/bin/python3 ${dirsearch}dirsearch.py -u https://${scanip}:${line} -e * -R 1
   if [ ! -d ${resultSave}/dirRes${dateStr} ];then
      mkdir ${resultSave}/dirRes${dateStr}
   fi
   cp -R ${dirsearch}reports/${scanip}/* ${resultSave}/dirRes${dateStr}
done
## 删除端口扫描临存数据
rm -rf ${resultSave}"/"${scanip}
}
## 端口函数调用
echo "-----portscan staring-----"
portscan
echo "-----portscan end-----"

## 目录扫描函数调用
echo "-----dir staring-----"
dirscan
echo "-----dir end-----"

在用了端口扫描和目录扫描的方式后,找到了攻击者记录受害者的日志信息。log文件里记录了下载的文件、时间、IP和USER-Agent。对受害者的范围排查有一定作用。

跳板站点只开了80、443端口。 为了拓展收集信息,这里使用Google Hacking语法的识别语句对目标的URI搜集,语法如下:

site:XXX inurl:admin|php|login

在谷歌的结果里找到了一条记录疑似为登录后台,访问/do-login.secure后 在底部的版权信息可以确定CMS名称是I BMS 版本号是v4.3.5。管理员后台登录界面如下:

利用关键字在Github找到泄露的历史版本源码,版本并不完全一致,但是通过文件的对比发现确实是同一款CMS。

代码审计

得到源码后做代码审计就轻松很多了,对于渗透测试优先选择容易上传webshell或者拿到权限的漏洞。源码审计工具里其实已经内含了正则表达式,原理是对容易出现漏洞的函数做正则表达式匹配筛选文件。以下规则是从seay代码审计工具里提取出来的,只保留了高危漏洞的规则。

'可能存在代码执行漏洞,或者此处是后门' : r"""$w{1,20}(([["']|[)${0,1}[w[]"']{0,30}){0,1}s{0,5}(s{0,5}$_(POST|GET|REQUEST|SERVER)[.{1,20}]""",

'phpinfo()函数,可能存在敏感信息泄露漏洞' : r"""phpinfos{0,5}(s{0,5})""",

'命令执行函数中存在变量,可能存在任意命令执行漏洞' : r"""(system|passthru|pcntl_exec|shell_exec|escapeshellcmd|exec)s{0,10}(.{0,40}$w{1,20}(([["']|[)${0,1}[w[]"']{0,30}){0,1}""",

'eval或者assertc函数中存在变量,可能存在代码执行漏洞' : r"""(eval|assert)s{0,10}(.{0,60}$w{1,20}(([["']|[)${0,1}[w[]"']{0,30}){0,1}""",

'存在文件上传,注意上传类型是否可控' : r"""move_uploaded_files{0,5}(""",

'文件包含函数中存在变量,可能存在文件包含漏洞' : r"""(include|require)(_once){0,1}(s{1,5}|s{0,5}().{0,60}$(?!.*(this->))w{1,20}(([["']|[)${0,1}[w[]"']{0,30}){0,1}""",

'preg_replace的/e模式,且有可控变量,可能存在代码执行漏洞' : r"""preg_replace(s{0,5}.*/[is]{0,2}e[is]{0,2}["']s{0,5},(.*$.*,|.*,.*$)""",

'call_user_func函数参数包含变量,可能存在代码执行漏洞' : r"""call_user_func(_array){0,1}(s{0,5}$w{1,15}(([["']|[)${0,1}[w[]"']{0,30}){0,1}""",

'读取文件函数中存在变量,可能存在任意文件读取漏洞' : r"""(file_get_contents|fopen|readfile|fgets|fread|parse_ini_file|highlight_file|fgetss|show_source)s{0,5}(.{0,40}$w{1,15}(([["']|[)${0,1}[w[]"']{0,30}){0,1}""",

'parse_str函数中存在变量,可能存在变量覆盖漏洞' : r"""(mb_){0,1}parse_strs{0,10}(.{0,40}$w{1,20}(([["']|[)${0,1}[w[]"']{0,30}){0,1}""",

'双$$符号可能存在变量覆盖漏洞' : r"""${{0,1}$w{1,20}(([["']|[)${0,1}[w[]"']{0,30}){0,1}s{0,4}=s{0,4}.{0,20}$w{1,20}(([["']|[)${0,1}[w[]"']{0,30}){0,1}""",

'获取IP地址方式可伪造,HTTP_REFERER可伪造,常见引发SQL注入等漏洞' : r"""["'](HTTP_CLIENT_IP|HTTP_X_FORWARDED_FOR|HTTP_REFERER)["']""",

'文件操作函数中存在变量,可能存在任意文件读取/删除/修改/写入等漏洞' : r"""(unlink|copy|fwrite|file_put_contents|bzopen)s{0,10}(.{0,40}$w{1,20}(([["']|[)${0,1}[w[]"']{0,30}){0,1}""",

'extract函数中存在变量,可能存在变量覆盖漏洞' : r"""(extract)s{0,5}(.{0,30}$w{1,20}(([["']|[)${0,1}[w[]"']{0,30}){0,1}s{0,5},{0,1}s{0,5}(EXTR_OVERWRITE){0,1}s{0,5})""",

'urldecode绕过GPC,stripslashes会取消GPC转义字符' : r"""^(?!.*addslashes).{0,40}((raw){0,1}urldecode|stripslashes)s{0,5}(.{0,60}$w{1,20}(([["']|[)${0,1}[w[]"']{0,30}){0,1}""",

'``反引号中包含变量,变量可控会导致命令执行漏洞' : r"""`$w{1,20}(([["']|[)${0,1}[w[]"']{0,30}){0,1}`""",

'array_map参数包含变量,变量可控可能会导致代码执行漏洞' : r"""array_maps{0,4}(s{0,4}.{0,20}$w{1,20}(([["']|[)${0,1}[w[]"']{0,30}){0,1}s{0,4}.{0,20},""",

'SQL语句select中条件变量无单引号保护,可能存在SQL注入漏洞' : r"""selects{1,4}.{1,60}from.{1,50}wheres{1,3}.{1,50}=["s.]{0,10}$w{1,20}(([["']|[)${0,1}[w[]"']{0,30}){0,1}""",

'SQL语句delete中条件变量无单引号保护,可能存在SQL注入漏洞' : r"""deletes{1,4}from.{1,20}wheres{1,3}.{1,30}=["s.]{0,10}$w{1,20}(([["']|[)${0,1}[w[]"']{0,30}){0,1}""",

'SQL语句insert中插入变量无单引号保护,可能存在SQL注入漏洞' : r"""inserts{1,5}intos{1,5}.{1,60}$w{1,20}(([["']|[)${0,1}[w[]"']{0,30}){0,1}""",

'SQL语句update中条件变量无单引号保护,可能存在SQL注入漏洞' : r"""updates{1,4}.{1,30}s{1,3}sets{1,5}.{1,60}$w{1,20}(([["']|[)${0,1}[w[]"']{0,30}){0,1}""",

'echo等输出中存在可控变量,可能存在XSS漏洞' : r"""(echo|print|print_r)s{0,5}({0,1}.{0,60}$_(POST|GET|REQUEST|SERVER)""",

'header函数或者js location有可控参数,存在任意跳转或http头污染漏洞' : r"""(headers{0,5}(.{0,30}|window.location.hrefs{0,5}=s{0,5})$_(POST|GET|REQUEST|SERVER)"""

为什么要自写python代码呢,主要还是因为很多时候有些文件漏洞利用需要登录界面之后才能利用。但是往往企业版本CMS很少具备注册、登录、用户发帖功能。都是登录后台以后才能使用。所以我通常会做以下的判断:

  • 1)分析配置文件是否有某些代码层上的过滤
  • 2)分析会话验证文件,排除掉需要会话验证才能访问的文件
  • 3)利用漏洞规则扫描未登录状态下可以访问的页面

python代码最终扫描出以下文件可以做文件上传的测试,完整的python代码会贴到文章后面。:

分析了前面几个文件后,发现了/my Admin/email/excel/excel.php这个文件,似乎利用起来是最简单的。

因为打开的时候加上http://xxxxxx/my Admin/email/excel/excel.php?pageT=new 就有个html表单可以文件上传,感觉很开心,但是并不是这样。因为点开上传之后就是404。

上传漏洞利用分析

虽然文件上传漏洞利用没有想象中的顺利,回到漏洞文件仔细又分析了一遍源码。发现是POST的请求URI位置不存在,但是excel.php这个文件确实接收到了文件流数据。38行文件上传未改名。59行修改文件上传的临时文件名称为10~ 6000000的整数。例如2917320php.php

手动构造了一下form表单页面,然后抓包发送。webshell果然上传成功。

<form action="http://192.168.88.133/myadmin/email/excel/excel.php" class="form-horizontal" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="exampleInputFile"><?php echo $_e['Excel File']; ?> :</label>
<input type="file" name="file" />
<p class="help-block"><a href="<?php echo WEB_URL; ?>/uploads/files/emailImport.xls" target="_blank"><?php echo $_e['Example']; ?></a>. Create Excel File With 3 columns, 1 for Name, 2nd for Email, 3rd For group, Upload Excel File and submit</p>
</div>
<input type="submit" name="emailImport" value="Submit" class="btn btn-primary">
</form>

详细溯源取证内容可加入知识星球观看。

原文地址:https://www.cnblogs.com/17bdw/p/15265590.html