Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2371998
  • 博文数量: 473
  • 博客积分: 12252
  • 博客等级: 上将
  • 技术积分: 4307
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-12 10:02
文章分类

全部博文(473)

文章存档

2012年(8)

2011年(63)

2010年(73)

2009年(231)

2008年(98)

分类: LINUX

2009-01-20 11:08:39


是个异常强大的网络包抓取和分析工具,最近又把它翻出来了。因为在写一个相关的程序,嫌原来的脚本性能太差,准备用重写一遍。这台服务器是需要身份验证的,可是服务器应答我身份验证成功后,RPC调用依然失败,怀疑是否包的结构有错误呢。因为不清楚具体原因,所以想抓包看看。

我们知道一般使用tcpdump可以这样,这会打印出你所要抓取的包的详细内容:

$ tcpdump -X -s0 host 192.168.0.1

而soap其实是架设在http之上的,tcpdump有专门打印出数据包ASCII形式的参数,所以我们过滤所有包含endpoint的ip地址如192.168.1.111的数据包,然后打印出来,我们就能直观的看出soap交互的详细内容。

$tcpdump -A -s0 host 192.168.1.111


比如对这次身份验证调用Login打印出了如下内容,相当直观吧,也有助于理解http协议的具体工作流程。

[lancer@Poseidon ~]$ tcpdump -A -s0 host 192.168.1.111
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 65535 bytes
13:03:51.220047 IP 192.168.0.21.57595 > 192.168.1.111.8016: S 1229105945:1229105945(0) win 5840
E..<..@.@..c.=.........PIB..........h{.........
..
.........
13:03:51.232748 IP 192.168.1.111.8016 > 192.168.0.21.57595: S 476571269:476571269(0) ack 1229105946 win 16384
E..@E...z..'.....=...P...g..IB....@........d.......
............
13:03:51.232764 IP 192.168.0.21.57595 > 192.168.1.111.8016: . ack 1 win 46
E..4..@.@..j.=.........PIB...g.............
..
.....
13:03:51.232819 IP 192.168.0.21.57595 > 192.168.1.111.8016: P 1:676(675) ack 1 win 46
E.....@.@.|..=.........PIB...g.......\.....
..
.....POST /esms/WebService/EsmsService.asmx HTTP/1.1
Host: 192.168.1.111:8016
User-Agent: gSOAP/2.7
Content-Type: text/xml; charset=utf-8
Content-Length: 451
Connection: keep-alive
SOAPAction: ""


BJYTXY123456
13:03:51.250921 IP 192.168.1.111.8016 > 192.168.0.21.57595: P 1:627(626) ack 676 win 64860
E...F.@.z........=...P...g..IB.....\.......
......
.HTTP/1.1 200 OK
Date: Wed, 12 Nov 2008 05:06:46 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 1.1.4322
Set-Cookie: ASP.NET_SessionId=rphtdr550eung2ulhucyydao; path=/
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Content-Length: 333

0

具体分析一下这些数据包

首先,http是可靠的tcp协议,所以开头要三次握手。仔细看一下封包头:

13:03:51.220047 IP 192.168.0.21.57595 > 192.168.1.111.8016: S 1229105945:1229105945(0) win 5840
  • 13:03:51.220047 抓取时间
  • IP 数据包的类型
  • 192.168.0.21.57595 发送方地址和端口,如send() sendto()
  • 192.168.1.111.8016 接收方地址和端口,如recv() recvfrom()
  • S 发送SYN同步信号
  • 1229105945:1229105945(0) 数据量大小为0
  • win 5840 滑动窗口的大小

不过这些包头内容对分析soap包关系不大,我们只关注数据包的内容,一段Web Service调用只有两部分,一问一答。先请求了一个soap包过去,远端服务器再回应一个soap包过来,这段会话结束。仔细一看HTTP头,发觉远 端原来是用的IIS,估计是台Windows 2003 server :)

剩下的内容就很简单了,你可以对照的格式,确认一下你的soap包构造,或者参数请求之类,然后调整你的代码。

本文的问题

比如本文的问题在于Cookie设置,gSoap默认在client端是不支持Cookie的。可是这台服务器却需要借助客户端的Cookie来完成身份验证,所以就出错了。首先服务器会给你一个Session ID要求客户端放到Cookie里,例如最后一段:

Set-Cookie: ASP.NET_SessionId=rphtdr550eung2ulhucyydao; path=/

可是由于客户端程序不支持Cookie,在接下来被我省略掉的封包里,其实就和第一个客户端请求的封包内容一样,请求的soap包头里没有包含这个Session ID,所以即使你上一次Login请求成功了,服务器依然不认识你,认为你是个陌生人。于是发现问题了,代码写的并没错,只需要把gSoap重新编译一把就OK了。

查询,发觉如果要客户端支持Cookies,只需要修改头文件 stdsoap2.h,在开头加一个定义 #define WITH_COOKIES,重新编译,生成链接库文件。再使用-DWITH_COOKIES重新链接自己写的程序就可以了。再使用tcpdump抓包,发觉已经成功验证身份了,在Login后续请求的调用里都能正确提供Session ID了,服务器也就认为你是个熟客了,因为在后续请求soap包头里多了一项:

Cookie: ASP.NET_SessionId=r2hwo055nsupd54514l3bvbp;$Domain="192.168.1.111"

结语

如果你要分析的请求流程过长,你也可以用-w把数据包写入文件再慢慢分析。tcpdump是个异常强大的网络分析工具,有很多细致的规则可以定义,抓包对它来说只是小菜一碟了。比如你还可以方便的用它嗅探局域网中的FTP、MSN消息之类的,因为它们都是明文传输的 :P 或者如果发现网络延迟,用来分析一下数据包流量,看看是否有蠕虫或者木马在活动,都很好玩。


阅读(2716) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~