HTTP漏洞分析及基于JS的加密实现

桂林seo半杯酒博客

一、 文章简介

本文通过了解学习用Node.js构建HTTP服务器,学会使用Kali进行ARP欺骗,学会用Wireshark抓数据包,利用Java实现HTTP的加密传输。

二、 知识储备

1. 关于Node.js的一些基础知识

Node.js是一个基于Chrome Java运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞I/O 模型而得以轻量和高效,非常适合在分布式设备上运行的数据密集型的实时应用。Node.js提供一些特殊的API库,因此在编写Node.js的时候可以理解为,使用Java语言利用Node.js的API库进行服务器端的开发。

2. 关于Kali的一些基础知识

Kali Linux 前身是 BackTrack(基于ubuntu),是一个基于 Debian 的 Linux 发行版,包含很多安全和取证方面的相关工具。支持 ARM架构。Kali Linux是基于Debian的Linux发行版, 设计用于数字取证和渗透测试 和 黑客攻防。由Offensive Security Ltd维护和资助。最先由Offensive Security的Mati Aharoni和Devon Kearns通过重写BackTrack来完成,BackTrack是他们之前写的用于取证的Linux发行版 。Kali Linux预装了许多渗透测试软件,包括nmap (端口扫描器)、Wireshark (数据包分析器)、John the Ripper (密码破解器),以及Aircrack-ng (一套用于对无线局域网进行渗透测试的软件). 用户可通过硬盘、live CD或live USB运行Kali Linux。Metasploit的Metasploit Framework支持Kali Linux,Metasploit一套针对远程主机进行开发和执行Exploit代码的工具。.Kali Linux既有32位和64位的镜像。可用于x86 指令集。同时还有基于ARM架构的镜像,可用于树莓派和三星的ARMChromebook。这里使用Kali做中间人攻击。

3. 关于Wireshark的一些基础知识

Wireshark是一个网络封包分析软件。网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包资料。Wireshark使用WinPCAP作为接口,直接与网卡进行数据报文交换。

网络封包, 分析软件的功能, 可想像成 “电工技师使用电表来量测电流、电压、电阻” 的工作 – 只是将场景移植到网络上,并将电线替换成网络线。在过去,网络封包分析软件是非常昂贵,或是专门属于营利用的软件。Wireshark的出现改变了这一切。在GNUGPL通用许可证的保障范围底下,使用者可以以免费的代价取得软件与其源代码,并拥有针对其源代码修改及客制化的权利。Wireshark是目前全世界最广泛的网络封包分析软件之一。

4. 关于JS(Java)的一些基础知识

Java一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为Java引擎,为浏览器的一部分,广泛用于客户端的脚本语言,最早是在HTML(标准通用标记语言下的一个应用)网页上使用,用来给HTML网页增加动态功能。

三、 环境说明

Windows xp虚拟机用作客户端(IP:111.195.214.137)

Ubuntu(64位)虚拟机用作HTTP服务器(IP:111.195.214.136)

Kali用来做ARP欺骗及抓包(IP:111.195.214.130)

辅助工具:Node.js,Wireshark,火狐浏览器

四、 实战步骤

HTTP是一个客户端和服务器端请求和应答的标准(TCP)。客户端是终端用户,服务器端是网站。通过使用Web浏览器、网络爬虫或者其它的工具,客户端发起一个到服务器上指定端口(默认端口为80)的HTTP请求。但是通过中间人攻击,如ARP欺骗很容易就可以获取客户端与服务器之间传输的数据包,窃取其中的敏感信息如密码等。那么能不能将想传输的敏感信息加密后再传送给服务器,提高HTTP的安全性呢?

我们的任务分为3部分:

1. 在服务器上(Ubuntu)用Node.js搭建简单的HTTP服务器

2. 用ARP欺骗进行中间人攻击并用Wireshark抓取数据包得到敏感数据

3. 用JS实现HTTP的加密传输,并再次利用中间人攻击抓取数据包查看所抓到的数据

4.1 步骤一

描述:在服务器(Ubuntu)上下载并安装Node.js并用Node.js实现简单HTTP服务器

1.Node.js下载与安装与HTTP的创建

(1)在官网(http://nodejs.org)下载适合自己操作系统的版本(如图1)。这里主要讲解Linux下的下载与安装,其余操作系统的安装可参考Node.js开发实战详解这本书。

(2)在这里选择Linux Binaries 64位的压缩包(可选择适应自己Linux的位数的安装包)。这个安装包是已经编译好的可执行文件,下载后直接解压就行。解压后进入相应文件夹目录下的node-v4.2.4-linux-x64文件夹下的bin文件夹,找到里面的node可执行文件。

(3)现在可以开始建立简单的HTTP服务器了,在bin文件夹中创建app.js的Node.js文件,用任意编辑器在app.js文件中输入2中的Node.js代码,保存并退出。

【代码说明】

require(‘http’):获取Node.js原生模块提供的HTTP模块对象

http.createServer():使用HTTP对象API方法createServer来创建服务器。

res.writeHead():通过res的HTTP响应对象,编写HTTP响应的头信息,并设定Content-Type指定返回数据类型为文本text,当然这里的数据类型也可以是其他格式,例如html,css和image等。

listen:是HTTP对象的一个方法,其主要是启动服务器监听的端口和IP,第二个参数为可选参数,默认为本地127.0.0.1。

console.log():是Node.js和Java共有的调试接口。

本段代码是应用require来调用HTTP模块中的方法和属性,该require模块成功返回的是Node.js中HTTP模块的方法和属性。如上代码中的listen接口的两个参数分别为运行端口号和服务器地址,其中端口号为一个Number类型,服务器地址为字符串,运行时如果端口号数据类型不正确会报错,只要不被其他应用程序占用,都可以作为Node.js的服务端口。

(4)在命令窗口中用cd命令进入app.js的路径,运行./node app.js的命令,运行成功后会显示Server running at http://127.0.0.1:1337 如3所示。

(5)打开任意浏览器(建议使用火狐浏览器),在浏览器中输入服务器地址http://127.0.0.1:1337,在web页面中我们将看到Hello World的字符串,如图4所示。

这样就简单的运用Node.js简单的创建了HTTP服务器。但这个服务器没有传输信息的功能。接下来在这个app.js文件中修改代码,使得客户端与服务器能够简单的传输信息。

(6)修改app.js的代码,实现客户端与服务器简单的信息传输,要求创建的HTTP服务器能够读取一个index.html页面,index.html页面中有一个form表单,该表单提交数据到http://127.0.0.1:1337/add,服务器端获取POST数据后打印显示当前的请求路径,POST字符串,POST的json参数对象。修改后的代码如图5。

【代码说明】

require(‘http’):获取Node.js原生模块提供的HTTP模块对象。

require(‘fs’):获取Node.js原生模块fs读取index.html页面信息。

require(‘url’):获取Node.js原生模块url解析请求资源路径。

require(‘querystring’):获取Node.js原生模块querystring解析POST数据。

var pathname = url.parse(req.url).pathname:获取客户端的HTTP请求路径,也就是请求模块。这里是利用“特定规则请求路径”的路由处理方法做简单的路由处理。

switch():判断请求资源类型分配,在这里根据不同的请求路径执行不同的函数资源。这里有两个不同的请求路径,有两个不同的函数。

resDefault(res):显示index.html页面函数逻辑,主要实现返回客户端一个index.html页面。

resAdd(res,req):打印POST请求数据函数逻辑。

var readPath = url.parse(‘index.html’).pathname:获取index.html文件的路径。

var indexPage = fs.readFileSync(readPath):读取相应的html页面。

res.writeHead(200, { ‘Content-type’: ‘text/html’ }):指定数据返回类型为html。

res.end(indexPage):响应相应的html页面。

var postData = ”:设置初始POST数据。

req.setEncoding(‘utf8′):设置数据接收编码格式为UTF-8。

req.addListener(‘data’, function(postDataChunk)):接收数据块并将其赋值给postData。

req.addListener(‘end’, function()):数据接收完毕执行回调函数。

var param = querystring.parse(postData):利用querystring模块解析POST数据。

res.end(‘success’):执行成功后,向客户端返回信息success。

(7)按(4)中的方法再次运行app.js如图6所示。

(8)打开火狐浏览器在浏览器中输入服务器地址http://111.195.214.136:1337,在web页面中我们将看到相应的html页面,如图7所示。

其中index.html的代码如图8所示。

(9)输入一串字符串并点击login如输入123456,则服务器端显示如图9所示。

同时客户端的浏览器显示如图10所示。

这样就创建了一个简单的HTTP服务器,并且能够与客户端进行信息传输。接下来可以开始用ARP欺骗的方法进行中间人攻击。通过中间人攻击获取客户端与服务器之间传输的信息。

做这部分时要注意:app.js文件,index.html文件都要放在解压后node.exe这个可执行文件的路径下。

4.2 步骤二

描述:在Kali上用ARP欺骗实现中间人攻击,并利用wireshark抓取数据包

1.ARP欺骗的原理

ARP欺骗,有时也被称为ARP下毒,是指攻击者在有线以太网或无线网络上发送伪造的ARP消息,对特定IP所对应的MAC地址进行假冒的欺骗,从而达到恶意目的的攻击技术。

ARP欺骗攻击的根源在于ARP攻击在设计时认为局域网内部所有用户都是可信的,但事实并非如此,局域网内可以存在内部攻击者或渗透到内部的外部攻击者或恶意代码。ARP协议在进行IP地址到MAC地址映射是存在安全缺陷,一方面采用广播请求包的方式在局域网中询问映射关系,但没有对相应结果进行真实性验证的流程和方法,而另一方面,为了提高查询的效率,设计了ARP缓存机制,以及会将主动的ARP应答视作有效信息进行接受,这使得ARP缓存非常容易被注入伪造的IP到MAC地址间的映射,从而进行ARP欺骗。

2.中间人攻击的实现

(1)中间人攻击需要三台虚拟机,一台作为服务器,一台作为客户端,还有一台作为中间人进行攻击,三台虚拟机应在同一个局域网段内。

这里使用Ubuntu作为服务器运行Node.js及相应的程序实现4.1步骤中的服务器,将IP地址设为111.195.214.136。使用win xp作为客户端(建议使用火狐浏览器),IP地址设为111.195.214.137。使用Kali作为中间人,IP地址设为111.195.214.130。。

(2)首先分别在三台虚拟机上ping另两台虚拟机,看是否连通,连通后通过arp –a的命令查看未进行arp欺骗时IP与MAC地址间的映射。

在Ubuntu上操作后结果如图11所示:

在win xp上操作后结果如图12所示:

这里没有把ping的结果截图接下来,只把执行了arp –a命令后的结果截图。

在Kal上操作后如图13所示:

通过上面的对比可以看到没进行ARP欺骗之前,IP与MAC地址中间的映射是正常的,不同的IP地址对应不同的MAC地址。

(3)在没进行ARP欺骗之前先用Kali抓包看是否能够抓到数据包。这里用wireshark来抓包。

首先打开wireshark,在Kali中已经安装好了这个软件,路径如图14所示:

这里由于空间关系截图中没有显示出来,但就在Network Sniffers下,下拉就能看到wireshark。

打开wireshark后的界面显示如图15所示:

点击第二行最左边像摄像机一样的图标弹出对话框如图16所示:

在这里选择eth3(因为我在设置IP地址时是通过eth3这个局域网口设置的,所以选择eth3,大家可以用ifconfig的命令查看自己的局域网网口,选择相应的局域网网口即可)即抓捕经过这个局域网网口的数据包。然后点击Options,弹出对话框如图17所示:

在这里要注意,弹出这个对话框后,如果Capture on all interfaces和Capture all in promiscuous mode这两个模块已经默认选择上了即前面的小方框已经打上对勾了,那么要将这两个对勾去掉(再点击一次即可),不能选择这两个模块。这是因为整个实验是在虚拟机上进行的,所有的数据实际都是通过一个网卡传输,如果选择这两个模块,那么不用任何操做,都可以捕捉到所有的数据包。然后双击eth3出现对话框如图18所示:

然后点击Capture Filter,在里面设置一些过滤条件,以方便所需的数据包,弹出对话框如图19所示:

单击IP address,在里面填上服务器的IP地址即只抓目的IP地址是到服务器的数据包。然后点击OK,设置完毕,这时wireshark就可以工作了,开始抓包了。

(4)回到Ubuntu虚拟机上,按4.1中所讲的方法,运行修改后的app.js这个文件,创建有简单传输功能的HTTP服务器,然后回到xp系统,在这个系统上运行火狐浏览器,访问服务器IP地址,传输简单的字符串,如123456,成功后浏览器上返回success,服务器上显示123456的数据,一次简单的传输就完成了。这是再回到Kali的wireshark,查看是否抓到数据包,结果如图20所示:

可以看到这是只能抓到广播询问ARP映射的数据包,并不能抓到传输数据的数据包。

(5)现在开始进行ARP欺骗,Kali上已经提前集成的ARPSPOOF的包,因此直接打开命令行窗口,输入相应的指令即可开始ARP欺骗。

首先在Kali上打开路由功能,使得其能够接收和转发数据包。相应的指令为echo 1 > /proc/sys/net/ipv4/ip_forward。指令输入完成后回车即开启了路由功能。

接下来进行ARP欺骗,ARP欺骗的指令格式非常简单,指令格式如下:

arpspoof –i 局域网网口 –t IP地址1 IP地址2

上面的局域网网口即Kali的局域网网口,这条指令的意思是欺骗IP地址1,Kali的MAC地址即为IP地址2的MAC地址。实际操作结果如图21所示:

从图21中可以看出,执行的是欺骗111.15.214.137,这里是111.195.214.136的MAC地址,即欺骗客户端Kali是服务器。可以看到,执行命令后,Kali不断地想客户端发送数据包,毒化客户端的ARP映射,使得服务器的MAC地址映射成为Kali的MAC地址。下面欺骗服务器Kali是客户端,用同样的指令格式,只是把两个IP地址的位置换换。再打开一个命令行窗口,输入图22中的指令,运行结果如图22所示:

这样ARP欺骗就完成了,可以通过下面这个步骤来简单检查ARP欺骗后的结果。

(6)回到服务器重新ping一下客户端,然后运行指令arp –a查看相应的MAC地址,结果如图23所示:

从图23可以看出此时服务器中ARP的映射里客户端的MAC地址已经成为了Kali的MAC地址了。在客户端中执行同样的操作,结果如图24所示:

同样可以看到在客户端中ARP的映射里服务器的MAC地址已经成为了Kali的MAC地址了。

(7)现在可以用上面讲过的方法再用wireshark抓包看看抓包的结果,结果如图25所示:

从图25可以看出,这时就可以抓到相应的tcp数据包了。选择其中一个tcp数据包,右键如图26所示:

右键后出现一个菜单栏,选择其中的Follow TCP Stream,就可以查看所捕获的TCP数据包,如图27所示为其中的一部分:

从图中可以看到已经捕获到了所传输的信息123456。并且此时观察服务器与客户端可以发现服务器仍然正常显示123456,客户端正常显示success。即完成了服务器与客户端不知情的情况下,得到所传输的数据,即完成了中间人攻击。

到这里我们可以看到,HTTP协议是不安全的,是容易泄露敏感信息的。一个简单的解决办法是在html文件中引入Java语言,将敏感信息加密后再进行传输。

4.3 步骤三

描述:用JS实现HTTP的加密传输,然后再次抓包查看抓到的数据

1.加密传输的实现

基本的思路是在开始的index.html文件中加入JS语言,使其实现在传输之前将相应的信息加密,这样传输的就是密文,提高安全性能。首先要选择合适的加密解密的算法,比较安全的有公钥加密算法,如RSA算法,这里为了简化实验,使较简单的md5算法,并且在服务器端不进行解密,直接接收密文。

在index.html文件的路径下新生成一个md5index.html文件,可以先将index.html文件的内容复制到md5index.html文件中,然后在此基础上进行修改。修改后的代码这里就不详细讲解了,感兴趣的同学可以直接查看md5index.html这个文件。

同时在app.js文件的路径下新生成一个md5test.js文件,可以先将app.js文件的内容复制到md5test.js文件中,然后在此基础上进行修改。只需要修改resDefault(res)函数中的var readPath = url.parse(‘md5index.html’).pathname;这一句话即可,将app.js中的index.html改为md5index.html即可。

然后按照前面4.1的方法用Node.js执行md5test.js文件创建HTTP服务器,在到客户端访问服务器网址即可,同样在客户端发送123456后服务器的显示如图28所示。

可以看到接收的是密文,正常情况下服务器端应当还有相应的解密流程,这里为了简化实验就将这步去掉了。另外,在客户端使用浏览器访问服务器时,建议使用火狐浏览器。因为这里在调试JS代码时实在火狐浏览器下调试的,并没有使用兼容的JS格式,用其它浏览器访问可能会有问题。

现在再用4.2中的方法进行ARP欺骗,然后用wireshark抓包并分析结果如图29所示:

从图中可以看到即使现在能够抓到数据包,得到的也只有加密后的结果,并不知道客户端传输的内容是什么。这样能够提高HTTP传输的安全性。

五、思考与总结

即使加密后HTTP传输仍然防不住中间人攻击,虽然抓到的包是加密的数据,但对于简单的加密算法可以分析数据包以解密,对于公钥加密的方法,可以在抓到数据包后篡改数据包中的公钥再用自己的私钥进行解密。甚至还可以直接对数据包中的JS部分进行篡改重发。所以若对传输的安全性的要求高的话,建议使用HTTPS即安全HTTP协议进行信息的传输。

本文中Node.js的部分主要参考《Node.js开发实战详解》这本书的内容,Node.js的功能不止这些,感兴趣的同学可以自己学习。读者切记不要使用这些技术做违法的事情。如读者因此做出危害网络安全的行为后果自负,与合天智汇及作者无关,特此声明。