CVE-2017-8464(stuxnet 3.0) 分析

0xFF 前言

​ 以前大一听网络安全宣讲会的时候,听他们讲那个震网事件,说插一个U盘就可以在用户不知情的情况下执行任意代码,之前一直都没有搞懂到底是怎么做到的,所以现在就来尝试来分析分析。这里要分析的cve-2017-8464是一个LNK文件漏洞,控制面板快捷方式加载CPL的时候存在缺陷导致可以加载指定DLL,从而执行任意代码。

0x00 分析工具

  • IDA
  • WinHex
  • WINDBG
  • windows 7 sp1 x86 (no patch)

0x01 漏洞复现

1)、生成一个DLL用于测试

编写一个测试DLL,为了看到效果,就弹一个MessageBox吧。

#include<Windows.h>
BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
{
if(dwReason == DLL_PROCESS_ATTACH)
MessageBox(0, TEXT("Called me!"), TEXT("Cap"), 0);
return TRUE;
}

将生成的DLL名字改为a.dll,并将其放在漏洞机中的C盘根目录下。

2)、构造一个恶意的lnk二进制文件

使用winhex创建并编辑一个如下图数据的LNK文件(后缀为.lnk)。并将其放在任意的地方(我放的是桌面)

3)、RUA!

​ ok,现在刷新一下桌面,wow!,会弹超多次的对话框。

0x02 POC细节

建议去看看微软官方资料:

https://msdn.microsoft.com/en-us/library/dd871305.aspx

红色: HeaderSize ,必须为0x4c

蓝色: LinkCLSID ,必须为00021401-0000-0000-C000

黄色: LinkFlags , 为1 表示HasLinkTargetIDList

橙色:ItemID[0]

蓝色:ItemID[1]

红色:ItemID[2]

绿色:TerminalID,A 16-bits unsigned integer,this value must be zero

黑色:IDListSize , 0x6E = sizeof(IDListSize)+sizeof(ItemID[0])+sizeof(Item[1])+sizeof(Item[2])

ps: ItemID[0]和ItemID[1]的具体含义可以去看看参考2那篇分析文章

红色:BlockSize

黄色:BlockSignature,这里是0xA0000005的话表面这块是SpecialFolderDataBlock

蓝色:SpecialFolderID,3 代表的是CSIDL_CONTROLS

绿色:Offset,Specifies the location of the ItemID of the first child segment of the IDList specified by SpecialFolderID. This value is the offset, in bytes, into the link target IDList(从IDListSize后面开始的偏移)

紫色:TERMINAL_BLOCK,This value must be less than 0x00000004

0x03 分析

1)、bp LoadLibraryW

​ 大概率是explorer.exe解析的,所以用windbg双机调试,下条件断点。(为了便于调试,请先将那个a.dll中调用MessageBox那行注释掉,重新编译生成新的a.dll放于漏洞机的C盘根目录)。

  • 先使用!process 0 0 找到 explorer.exe 的EPROCESS 假设为 8781f510

  • 断到指定进程环境下.process -i -r -p 8781f510

  • 使用条件断点:bp Kernel32!LoadLibraryW "$<C:\\windbgScript\\sp.txt"

sp.txt文件内容(绝对路径:C:\windbgScript\sp.txt)

as /mu ${/v:dllname} poi(esp+4)
.if ($sicmp( "${dllname}", "C:\a.dll")=0) {.echo ${dllname}} .else {gc}

如果下不了断点请先使用这个命令再加载下符号: !sym noisy;.reload /user *,再检查下绝对路径是否是使用的\\(双斜线),windbg符号路径是否已经设置。

  • 下好断点后,键入g命令运行,漏洞机中刷新桌面.windbg 断下:

    显示如下内容:

    kd> .if ($sicmp( "${dllname}", "C:\a.dll")=0) {.echo ${dllname}} .else {gc}

    C:\a.dll

    kernel32!LoadLibraryW:

    001b:76653c01 8bff mov edi,edi

  • 好,查看栈回溯

    kd> k

    ChildEBP RetAddr

    07edccc8 767b73ed kernel32!LoadLibraryW

    07edcf24 769d259f SHELL32!CPL_LoadCPLModule+0x169

    07edd5c8 769d26e6 SHELL32!CControlPanelFolder::_GetPidlFromAppletId+0x19c

    07edd5f4 76767b0b SHELL32!CControlPanelFolder::ParseDisplayName+0x49

    07edd678 7676f21f SHELL32!CRegFolder::ParseDisplayName+0x93

    07edd6ec 7677083d SHELL32!ReparseRelativeIDList+0x137

    07edd730 76770885 SHELL32!TranslateAliasWithEvent+0xa6

    07edd748 7673e916 SHELL32!TranslateAlias+0x15

    07edd774 7673e6ab SHELL32!CShellLink::_DecodeSpecialFolder+0xf9

    07edea38 766fca50 SHELL32!CShellLink::_LoadFromStream+0x39f

    07edec68 766fc9bf SHELL32!CShellLink::_LoadFromFile+0x90

    07edec78 766fc914 SHELL32!CShellLink::Load+0x32

    .....

    看到SHELL32!CShellLink::_LoadFromFile,猜测是从这个函数开始解析lnk文件的。使用lm v m shell32

    命令查看得到shell32.dll的在漏洞机中的路径:

    kd> lm v m shell32

    start end module name

    ....

    Image path: C:\Windows\system32\SHELL32.dll

    ....

    ok,找到shell32.dll 并把它拖进IDA pro中,开始我们的F5"逆向分析"

2)、Parse 恶意lnk文件的过程

CShellLink::_LoadFromStream

在CShellLink::_LoadFromStream中,首先会读取恶意lnk文件头4个字节,判断是不是等于0x4C。接着读取恶意lnk文件头+0x4处(读取文件流会造成文件指针移动,刚刚已经读了4个了,所以下一次开始读取时文件指针偏移加4)继续读取恶意lnk文件ShellLinkHeader结构的剩下0x48个字节的数据并放到this->offset_0n244处(这个this就是CShellLink这个对象的实例),接着判断LinkCLSID(16 bytes)是否等于00021401-0000-0000-C000-000000000046.

​ 之后取LinkFlags 检查有哪些结构在ShellLinkHeader后面存在,首先检查的是HasLinkTargetIDList ,在我们构造这个POC中,是成立的。(pCShellLink+244+16 就是LinkFlags,因为this->offset_0n244处存的是ShellLinkHeader结构剩下的的0x48字节,LinkCLSID后面紧跟着的就是LinkFlags字段,16是LinkCLSID的大小)。下图中的v6会等于0,所以会调用CShellLink::_LoadIDList,通过逆向(F5)这个函数得知做的功能是分配一块内存加载lnk文件的LINKTARGET_IDLIST段(去掉这个段的前2个字节,即ItemID[0]+ItemID[1]+ItemID[2])到this->0n188处。这个函数执行后,当前文件流指针就指向了LINKTARGET_IDLIST的后面,对于我们这个POC来说也就是EXTRA_DATA段了。

​ 接着从文件流读取EXTRA_DATA到this->offset_0n228处。

​ 下面那个是DWORD*的this+47,所以要乘以4即this->offset_0n188,即判断是不是存在LinkTargetIDList.IDList,我们这个POC是存在的,所以调用CShellLink::_DecodeSpecialFolder(this);

CShellLink::_DecodeSpecialFolder(CShellLink *this)

首先调用SHFindDataBlock查找this->offset_0n228处(EXTRA_DATA)是否有KnownFolderDataBlock(它的BlockSignature 是0xA000000B),显然我们的POC中没有构造这个Block。所以27行的v2会返回0,接着会执行第41行,调用SHFindDataBlock查找this->offset_0n228处(EXTRA_DATA)是否有SpecialFolderDataBlock(它的BlockSignature是0xA0000005),而我们的POC中的确存在这个Block,所以SHFindDataBlock返回指向SpecialFolderDataBlock的指针。

接着取pSpecialFolderDataBlock->SpecialFolderID(偏移为8)作为SHCloneSpecialIDList函数的第二个参数,根据MSDN上关于SHCloneSpecialIDList的介绍,它是用来获取一个KnownFolder的ITEMIDLIST结构,我们poc中构造的是3,

Retrieves a pointer to the ITEMIDLIST structure that specifies a special folder.

在vs中查看得知3对应的是Control Panel,所以这个函数返回的是一个指向Control Panel的ITEMIDList结构的指针(这个是个关键,详细的请看后面我单独会写)。

接着会调用TranslateAlias函数,传入的参数分别是:

  • this->offset_0n188,即ItemID[0],ItemID[1],ItemID[2]
  • v11 是指向一块存放 ItemID[0]和ItemID[1]的内存
  • 控制面板的ITEMIDLIST,用于之后绑定

TranslateAlias

TranslateAliasWithEvent

SHBindToObject函数MSDN上是有介绍的:

Retrieves and binds to a specified object by using the Shell namespace IShellFolder::BindToObject method.

所以要触发到后面调用CControlPanelFolder::的例程,那么一定要获取到ControlPanel的IDList

ReparseRelativeIDList

58行的调用也是个关键,是调用这个将poc中IDList[2]中的"C:\a.dll" 加载到CControlPanelFolder:

CVE-2017-8464 分析的更多相关文章

  1. ICCV 2017论文分析(文本分析)标题词频分析 这算不算大数据 第一步:数据清洗(删除作者和无用的页码)

    IEEE International Conference on Computer Vision, ICCV 2017, Venice, Italy, October 22-29, 2017. IEE ...

  2. Visual Studio 2017 and Swagger: Building and Documenting Web APIs

    Swagger是一种与技术无关的标准,允许发现REST API,为任何软件提供了一种识别REST API功能的方法. 这比看起来更重要:这是一个改变游戏技术的方式,就像Web服务描述语言一样WSDL( ...

  3. CDR 2017版本LiveSketch工具是什么,怎么用?

    LiveSketch 工具在提供手绘草图的简便性和速度的同时,结合了智能笔触调整和向量绘图.在您绘制草图时,CorelDRAW 2017会分析您输入笔触的属性.时序和空间接近度,对其进行调整并将其转换 ...

  4. android CVE

    本文收集网上android cve的一些分析供后续学习: Android uncovers master-key:android1.6-4.0 由于ZIP格式允许存在两个或以上完全相同的路径,而安卓系 ...

  5. Android安全研究经验谈

    安全研究做什么 从攻击角度举例,可以是:对某个模块进行漏洞挖掘的方法,对某个漏洞进行利用的技术,通过逆向工程破解程序.解密数据,对系统或应用进行感染.劫持等破坏安全性的攻击技术等. 而防御上则是:查杀 ...

  6. Debian Security Advisory(Debian安全报告) DSA-4405-1 openjpeg2

    package :openjpeg2 相关CVE ID: CVE-2017-17480 CVE-2018-5785 CVE-2018-6616 CVE-2018-14423 CVE-2018-1808 ...

  7. 2018-2019-2 网络对抗技术 20165322 Exp5 MSF基础应用

    2018-2019-2 网络对抗技术 20165322 Exp5 MSF基础应用 目录 实验内容与步骤 一个主动攻击实践 MS08-067(失败) ms17_010_psexec(成功且唯一) 一个针 ...

  8. ORA-00600: internal error code, arguments: [kdBlkCheckError]

    ORA-00600: internal error code, arguments: [kdBlkCheckError] Table of Contents 1. 现象 2. 分析 3. 故障处理 1 ...

  9. NOIP提高组初赛难题总结

    NOIP提高组初赛难题总结 注:笔者开始写本文章时noip初赛新题型还未公布,故会含有一些比较老的内容,敬请谅解. 约定: 若无特殊说明,本文中未知数均为整数 [表达式] 表示:在表达式成立时它的值为 ...

  10. weblogic-CVE-2020-2551-IIOP反序列化学习记录

    CORBA: 具体的对CORBA的介绍安全客这篇文章https://www.anquanke.com/post/id/199227说的很详细,但是完全记住是不可能的,我觉得读完它要弄清以下几个点: 1 ...

随机推荐

  1. JavaScript中常见的十五种设计模式

    在程序设计中有很多实用的设计模式,而其中大部分语言的实现都是基于“类”. 在JavaScript中并没有类这种概念,JS中的函数属于一等对象,在JS中定义一个对象非常简单(var obj = {}), ...

  2. 第1章 Linux文件类基础命令

    1. 关于路径和通配符 Linux中分绝对路径和相对路径,绝对路径一定是从/开始写的,相对路径不从根开始写,还可能使用路径符号. 路径展开符号: . :(一个点)表示当前目录 .. :(两个点)表示上 ...

  3. 南大算法设计与分析课程复习笔记(1) L1 - Model of computation

    一.计算模型 1.1 定义: 我们在思考和处理算法的时候是机器无关.实现语言无关的.所有的算法运行在一种“抽象的机器”之上,这就是计算模型. 1.2 种类 图灵机是最有名的计算模型,本课使用更简单更合 ...

  4. Tomcat服务器为java项目配置顶级域名

    修改端口, Tomcat服务器下conf/server.xml文件      把端口号更改为80 解释:输入域名时默认进入80端口,如果没修改则需要输入端口号才能进入. Eg:www.xxx.com: ...

  5. Java高并发--缓存

    Java高并发--缓存 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 在下图中每一个部分都可以使用缓存的技术. 缓存的特征 缓存命中:直接通过缓存获取到数据 命中率: ...

  6. Redis的数据结构

    Redis的数据结构 redis是一种高级的key-value的存储系统,其中value支持五种数据类型. 字符串(String) 哈希(hash) 字符串列表(list) 字符串集合(set) 有序 ...

  7. sourcetree Authentication failed

    sourcetree 的 git 密码存在 mac 的 钥匙串里面, 需要在钥匙串里删除掉对应信息,再次打开就会让你重新输入密码, 问题就解决了。 参看: https://stackoverflow. ...

  8. matlab rank

    k =rank(A)    %a is matrix s = svd(A); tol = max(size(A))*eps(max(s)); r = sum(s > tol);

  9. 使用EF保存数据时 提示: 其他信息: 对一个或多个实体的验证失败。有关详细信息,请参阅“EntityValidationErrors”属性。

    错误提示: 解决方法: →使用try...catch捕获→在catch所在行打上断点,运行,对ex添加监视或者运行到ex的时候  按Shift+f9天假快速监视→在EntityValidationEr ...

  10. crontab架构和格式

    crontab架构图 分时日月周*****my command(可以是一个linux命令,也可以是一个脚本文件,可以是shell格式也可以是python格式,也可是java格式.....) 按照格式编 ...