• HTTP抓包实战


    HTTP:超文本传输协议

      允许将HTTP文档从Web服务器传送到客户端的浏览器。HTTP请求报文分为3部分。第一部分叫做起始行(Request line)。第二部分叫首部(Request Header)。第三部分叫主题(Body)。

      Response一样,响应行(Response line),首部,主体。

      Fiddle本质是一个代理服务器,代理地址127.0.0.1,端口;8888

    GET  /dongye95/home?wvr=5  HTTP/1.1

    HTTP/1.1  200 OK

    代理服务器

    1. 共享网络
    2. 提高访问速度,大部分代理服务器有缓冲功能
    3. 突破访问限制
    4. 隐藏身份

    Web通信安全

    1.浏览器和Web服务器之间的内容应该只有浏览器和Web服务器能够看到通信的真正内容。

    2.HTTP请求的内容和HTTP请求的响应不会被第三方篡改。

    Web服务器与每个客户端使用不同的对称加密算法。

    HTTPS = HTTP + TLS 安全传输层协议或 SSL(Secure Sockets Layer 安全套接层)

    HTTPS firefox 证书

    包括IE、Chrome 和safari在内的大部分应用都使用Windows证书库来验证证书。firefox浏览器是自己维护证书列表,所以需要单独安装fiddle证书。

    Tunnel to

      HTTP Tunnel(也叫HTTP隧道,HTTP穿梭)是这样一种技术。它用HTTP协议在要通信的 client 和 server 建立起一条 “Tunnel”。然后client 和server之间的通信都是在这条Tunnel的基础上实现的。简单来说,当Fiddle当做代理转发HTTPS请求的时候,就会产生“CONNECT Tunnels”。

      Fiddle可隐藏,Rules-》Hide CONNECTS

    HTTP协议请求方法和状态码

    HTTP 请求方法

    GET 请求指定的页面信息并返回实体主体
    HEAD 类似于GET请求,只不过返回的响应中没有具体的内容,用于获取报头
    POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中,post请求可能会导致新的资源的建立和/或对已有资源的修改
    PUT 从客户端向服务端传送的数据取代指定文档的内容
    DELETE 请求服务器删除指定的页面
    OPTIONS 询问支持的方法,用来查询针对请求 URI 指定的资源支持的方法
    TRACE 追踪路径,让 Web 服务器端将之前的请求通信环回给客户端的方法
    CONNECT 要求用隧道协议连接代理,要求在与代理服务器通信时建立隧道,实现用隧道协议进行 TCP通信。

    GET

      用于获取资源,常用于向服务器查询某些信息。打开网页一般都是用GET方法,因为要以Web服务器获取信息。

    参数

      浏览器也可以在GET方法中把数据传给服务器,数据放在URL的问号(?)后面,叫查询字符串,也叫做Query String。查询字符串以“名=值”这样的形式出现,多个之间用“&”隔开

    POST

      通常用来把表单中填好的数据发送给服务器

    GET和POST区别

    1. GET提交的数据会放在URL之后。POST放在Body中。
    2. GET提交的数据大小是有限制的(URL长度有限制)。POST没有限制。
    3. GET方式提交数据会带来安全问题,比如用户名和密码出现在URL中。页面被缓存或其他人访问这台机器,可从历史记录中获得该用户的账号和密码。

    HTTP/1.1 状态码

    状态码 已定义范围 分类
    1XX 100 - 101 信息提示表示请求已被成功接收,继续处理
    2XX 200 - 206 成功表示请求已被成功接收、理解、接收
    3XX 300 - 302 重定向,要完成请求,必须进行更进一步的处理
    4XX 400 - 415 客户端错误,请求有语法错误或请求无法实现
    5XX 500 - 505 服务器错误,服务器未能实现合法的请求

    常见的状态码

    名称 释义
    200 OK:服务器成功处理了请求(这个是我们见到最多的)
    301/302 Moved Permanently(重定向):请求的URL已移走。Response中应该包含一个Location URL,说明资源现在所处的位置
    304 Not Modified(未修改):客户的缓存资源是最新的,需要客户端使用缓存
    404 Not Found:未找到资源
    401 禁止访问
    501 Internal Server Error:服务器遇到一个错误,使其无法对请求提供服务

    200(OK)

      表示该请求被成功地完成,所请求的资源成功地发送回客户端。

    204(No Content,没有内容

      返回的HTTP响应中只有一些Header和一个状态行,没有实体的主体内容(没有响应Body)

    204 状态码作用如下:

    1. 在不获取资源的情况下了解资源的情况(比如判断其类型)、
    2. 通过查看HTTP响应中的状态码看某个对象是否存在
    3. 通过常看Header测试资源是否被修改

    206(Partial Content,部分内容)

      表示服务器已经成功处理了部分GET请求(只有发送GET方法的HTTP请求,Web服务器才可能返回206)

    1. FlashGet、迅雷或者HTTP下载工具都是使用206状态码来实现断点续传
    2. 将一个大文档分解为多个下载段同时下载,比如在线看视频。

    http://tv.sohu.com/20121011/n354681393.shtml

    301(Moved Permanently)

      表示请求的网页已经永久性地转移到另一个地址

    如下情况需要用到301:

    1. 防止用户输错域名。
    2. 网站更换域名。比如www.360buy.com改为www.jd.com
    3. 有多个权重不错的域名,需要把所有的权重都传递到新域名上,这就需要301重定向了。如果不设置301,多个域名绑定在一个主机头上,会被搜索引擎认为是两个相同的站点,不利于网站的排名。绑定的域名越多,内容重复度也就越高,排名越低。

    302(Found)

      当我们访问一个URL的时候,服务器要我们访问另一个资源,这回收浏览器会继续发一个HTTP,请求访问新的资源。

      比如为登陆状态下,直接访问需要登陆才能访问的页面,会被服务器返回302,跳转到登陆页面。

    301和302区别

    1. 301表示旧地址的资源已经被永久的移除了(这个资源不可访问了),搜索引擎会把权重算到新地址。
    2. 302表示旧地址的资源还在(仍然可以访问),这个重定向只是临时地从旧地址跳转到新地址,搜索引擎会把权重算到旧地址。

    304(Not Modified)

      304状态码代表上次的文档已经被缓存了,还可以继续使用

    如果不想使用本地缓存,用【Ctrl + F5】强制刷新

    400(Bad Request)

      表示客户端请求有语法错误

    401(Unauthorized)

      状态码401是指未授权错误,有些网页采用的是HTTP基本认证(Basic Authentication),需要在HTTP请求中带上 Authentication Header,否则服务器会返回状态码401

    403(Forbidden)

      表示Web客户端发送的请求被Web服务器拒绝了。如果想说明原因,可以在body中说明,但是这个状态码通常表示服务器不想说明拒绝原因

    404(Not Found)

      资源不存在。本来就不存在,或者被删了,或者被墙了。

    500(Internal Server Error)

      服务器内部错误。比如代码错误,数据库连接语句出错,空指针等。

    503(Server Unavailable)

      服务器暂不可用。由于服务器维护或者过载,服务器当前无法处理请求;这个状况是临时的,并且将在一段时间以后恢复。

    HTTP协议Header介绍

      Header翻译成中文,叫“首部”或者“头域”。

      Header语法格式是:“key:value”,一行一个Header

    Cache:缓存相关。如果本地有“已缓存的”副本,就可以从本地存储设备而不是从原始服务器中提取这个文档。
    Accept:表示浏览器客户端可以接受的媒体类型。

    Accept:text/html,*/*;q=0.8 代表浏览器可以处理所有的类型。一般浏览器客户端给Web服务器发送的都是这个。

    Accept-Encoding:跟压缩有关。Accept-Encoding: gzip, deflate, br   

    Accept-Language:浏览器声明自己接受的语言。

    User-Agent:浏览器用来告诉服务器,客户端使用的操作系统及版本、CPU类型、浏览器及版本,浏览器渲染引擎、浏览器语言、浏览器插件等。

    Referer:用来让服务器判断来源页面,即用户是从哪个页面来的。网站通常用其来统计用户来源,看用户是从搜索页面来的,还是从其他网站链接来的,或是从书签等访问的,以便合理定义网站。

    Referer有时也被用作防盗链,即下载时判断来源地址是不是在网站域名之内,否则就不能下载或显示。

    Connection:从HTTP/1.1起,系统默认都开启了Connection:Keep-Alive,保持连接特性

    HTTP协议是基于TCP协议的。当一个网页完全打开后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭;如果客户端再次访问这个服务器上的网页,将会连续使用这一条已经建立的连接。

    Keep-Alive不会永久保持连接,它有一个保持时间。

    Host:这个Header是必需的,它的作用是指定被请求的主机和端口号。

    Web网页抓包和Fiddler修改包

    打开一个网页,浏览器需要发送很多个请求。

    1. 在浏览器输入http://www.cnblogs.com
    2. 浏览器会发送第一个HTTP请求去获取页面布局的HTML,这个请求叫做“父请求”。然后服务器把HTTP响应发回给浏览器。
    3. 浏览器会分析HTTP响应中的HTML,然后发现HTML中引用了其他文件:比如图片,CSS,JS,JSON。浏览器会自动再次发送很多HTTP请求,去获取图片,CSS文件或者JS文件。这些HTTP请求叫做“子请求”。
    4. 当所有自请求的响应都返回后,浏览器会把1个父请求加上多个子请求渲染出来。这样就形成了一个页面。

    用Fiddler选择子请求

    先找到父请求,鼠标右键选择Select -> Child Requests

    用Fiddler选择父请求

    先找到子请求,鼠标右键选择Select -> Parent Requests

    用Fiddler选择相同请求

    选择一个请求,鼠标右键选择Select -> Duplicate Requests

    简单性能测试

    1. 子请求出现了404或者500之类的错误,会严重影响整个网页的加载速度。
    2. 子请求的响应速度慢也会影响网页加载的速度。

    可以清楚看到每个HTTP请求的响应时间

    修改HTTP请求单个断点:bpu www.baidu.com。取消:bpu

    修改HTTP响应单个断点:bpafter www.baidu.com。取消 bpafter

    HTTP协议中的缓存

    HTTP中具有缓存功能的是浏览器缓存和代理服务器缓存。

    HTTP缓存是指当Web请求抵达缓存时,如果本地有“已缓存的”副本,就可以从本地存储设备而不是从原始服务器中提取这个文档。

    缓存优点

    • 减少了冗余的数据传输,节省了传输时间
    • 减少了服务器的负担,大大提高了网站性能
    • 加快了客户端加载网页的速度

    Web服务器通过以下2种方式来判断浏览器缓存是否最新

    1. 浏览器把缓存文件的最后修改时间通过Header“If-Modified-Since”告诉Web浏览器
    2. 浏览器把缓存文件的ETag通过Header“If-None-Match”告诉服务器

    通过最后修改时间来判断缓存新鲜度

    浏览器可以通过缓存文件的修改时间来判断缓存的新鲜度,具体的步骤如下:

    1. 如果浏览器客户端想请求一个文档,它首先检查本地缓存,发现存在这个文档的缓存,获取缓存中文档的最后修改时间,通过“If-Modified-Since”发送HTTP请求给Web服务器。
    2. Web服务器收到HTTP请求,将服务器的文档修改时间(Last-Modified)跟HTTP请求Header中的If-Modified-Since相比较。如果时间是一样的,说明缓存还是最新的。Web服务器将发送状态码304(Not Modified)给浏览器客户端,告诉客户端直接使用缓存里的版本。

    HTTP请求中跟缓存相关的Header

    名称 释义
    Cache-Control:max-age=0 以秒为单位
    If-Modified-Since:Mon,19 Nov 2012 08:38:01 GMT 缓存文件的最后修改时间
    If-None-Match:"0693f67a67cc1:0" 缓存文件的ETag
    Cache-Control:no-cache 不使用缓存
    Pragma:no-cache 不使用缓存

    HTTP响应中跟缓存相关的Header

    名称 释义

    Cache-Control:public

    响应被缓存,并且在多用户间共享
    Cache-Control:private 响应只能作为私有缓存,不能再用户之间共享
    Cache-Control:no-cache 提醒浏览器要从服务器提取文档进行验证
    Cache-Control:no-store 绝对禁止缓存(用于机密、敏感文件)
    Cache-control:max-age=60 60s之后缓存过期(相对时间)

    Date:Mon,19 Nov 2012 08:39:00 GMT

    当前响应发送的时间
    Expires:Mon,19 Nov 2012 08:40:01 GMT 缓存过期的时间(绝对时间)
    Last-Modified:Mon,19 Nov 2012 08:38:01 GMT 服务器端文件的最后修改时间

    ETag:"20b1add7ec1sd1:0"

    服务器端文件的ETag值

    如果同时存在cache-control和Expires怎么办?浏览器总是优先使用cache-control。

    ETag

    是Entity Tag(实体标签)的缩写,是根据实体内容生成的一段hash字符串(类似于MD5或者SHA1之后的结果)

    使用ETag主要是为了解决一些Last-Modified无法解决的问题。

    1. 某些服务器不能精确得到文件的最后修改时间,这样就无法通过最后修改时间来判断文件是否更新了。
    2. 某些文件的修改非常频繁,在以秒为单位以下的时间内进行修改,而Last-Modified只能精确到秒
    3. 一些文件的最后修改时间改变了,但是内容并非改变,我们不希望客户端认为这个文件修改了。

    使用【Ctrl + F5】可以强制刷新浏览器,可以让浏览器不使用缓存。

    Pragma:no-cache的作用和“Cache-Control:no-cache”一模一样,都是不使用缓存。Pragma:no-cache是HTTP1.0中定义的,所以为了兼容HTTP1.0会同时使用Pragma:no-cache和Cache-Control:no-cache

    HTTP协议压缩和URL Encode

    HTTP采用通用的压缩算法,比如用gzip来压缩HTML、JavaScript、CSS文件,能大大减少网络传输的数据量,提高了用户显示网页的速度。当然,这同时也会增加一点点服务器的开销。

    HTTP压缩的过程

    1. 浏览器发送HTTP请求给Web服务器,请求中的Header能Accept-Encoding:gzip,deflate(告诉服务器,浏览器支持gzip压缩)
    2. Web服务器接到HTTP请求后,生成原始的HTTP响应,其中有原始的 Content-TypeContent-Length
    3. Web服务器通过gzip来对HTTP响应进行编码,编码后Header中有 Content-Type 和 Content-Length(压缩后的大小),并且增加了Content-Encoding:gzip,然后把HTTP响应发送给浏览器。
    4. 浏览器接到HTTP响应后,根据Content-Encoding:gzip来对HTTP响应进行解码,获取到原始HTTP响应后显示出网页。

    内容编码类型:

    Content-Encoding header 就是用这些标准化的代号来说明编码时使用的算法

    1. gzip 表明实体采用 GNU zip 编码
    2. compress 表明实体采用 UNIX的文件压缩程序
    3. deflate 表明实体是用 zlib 的格式压缩的
    4. identity 表明没有对实体进行编码;当没有 Contetn-Encoding header 时,就默认为这种情况。

    gzip、compress以及deflate编码都是无损压缩算法,用于减少传输报文的大小,不会导致信息损失。其中 gzip 通常效率最高,使用最为广泛。

    gzip是如何压缩的

    简单来说,gzip压缩实在一个文本文件中找出类似的字符串,并临时替换它们,从而使整个文件变小。这种形式的压缩对Web来说非常适合,因为HTML和CSS文件通常包含大量重复的字符串,例如空格、标签等。也正是因为这样,gzip对JPEG这类文件压缩效果不好。

    HTTP内容编码和HTTP压缩的区别

    用其他编码方式把内容搅乱或者加密,以此来防止未被授权的第三方开到文档的内容。所以,我们说HTTP压缩其实就是HTTP内容编码的一种。

    URL Encode介绍

    URL只能用英文字母、数字或者某些标点符号,不能使用其他文字和符号。

    URL Encode(URL编码)就是把所有非英文字母、数字字符都替换成百分号(%)后加两位十六进制数。

    比如在搜狗搜索里输入中文,点击查找

    中文对应为%E4%B8%AD%E6%96%87

    在Fiddler中可以使用TextWizard工具来进行转换

    Fiddler使用技巧

    1.【Ctrl + X】清空列表

    2.Fiddler异常退出后无法上网,重新启动Fiddler然后再关闭。

    3.Fiddler中查询对话,【Ctrl + F】就可以了。

    4.Fiddler中保存抓到的包

      先选中session,然后右键 -> Save -> Selected Sessions。保存后的文件后缀名是.saz。文件会保存完整的HTTP请求和HTTP响应

      双击.saz文件,或者单机Fiddler菜单栏中的File -> Load Archive,就能打开.saz文件。

    Fiddler常用快捷键

    快捷键 用途
    Ctrl + X 删除所有的Session
    Ctrl + A 选择所有的Session
    ESC 不选择任何的Session
    Ctrl + I 反选Session
    Delete 删除选择的Session
    Shift + Delete 删除未选择的Session
    R 重放选择的Session(可以重放多个Session)
    Shift + R 多次重放选择的Session(随后会提示你输入,重放几次)
    U

    无条件的重放选择的Session(不会发送If-Modified-Since 和 If-None-Match-Headers)

    Shift + U

    无条件的重放选择的Session(随后会提示你输入,重放几次)
    P 选择“当前Session”的“父Session”(这个功能取决于Referer Header)
    C 选择“当前Session”的“子Session”
    D 选择“重复的Session”(有相同的URL和相同的method)
    BackSpace或鼠标上的“Back” 选择“上次选择的Session”
    Insert  

    Ctrl + 1

    Ctrl + 2

    Ctrl + 3

    Ctrl + 4

    Ctrl + 5

    Ctrl + 6

    用粗体和颜色标记选择的Session
    M 给选择的Session添加注释

    Fiddler插件

    Fiddler插件下载地址:www.telerik.com/fiddler/add-ons

    比较会话的不同:Windiff

    格式化JS代码:JavaScript Formatter

    图片缩略图:Gallery

    Fiddler的Script用法

    Fiddler Script是一个可以自动修改HTTP请求和HTTP响应的脚本文件,使你不用手动地去下“断点”来修改。

    Fiddler Script的本质其实是用JScript.NET语言写的一个脚本文件CustomRules.js,其语法类似于C#。

    Fiddler Script Editor

    或者

    CustomRules.js中的主要方法

    static function OnBeforeRequest(oSession:Session)

    OnBeforeRequest函数在每次请求之前调用。在这个方法中修改Request的内容,我们用的最多

    static function OnBeforeResponse(oSession:Session)

    OnBeforeResponse函数在每次响应之前调用,在这个方法中修改Response的内容。

    static function OnExexAction(sParams:String[])

    这个方法中包含Fiddler命令。命令是在Fiddler界面中左下方的QuickExec中执行的。

    Fiddler定制菜单

    Rules -> User-Agents菜单中好像没有Iphone-4S safari,我们现在可以定制一个。上网查询user-Agents,添加代码:

    RulesStringValue(23,"Iphone 4S safari","Mozilla/5.0(iPhone;U;CPU iPhone OS 4_0 like Mac OS X;en-us)AppleWebKit/532.9(KHTML,like Gecko) Version/4.0.5 Mobile/8A293Safari/6531.22.7")

    重启Fiddler就行

    修改Session在Fiddler的显示样式

    把以下脚本放在OnBeforeRequest(oSession:Session)方法下,并且单机“Save script”,这样所有的cnblogs会话都会显示为红色

    if (oSession.HostnameIs("www.cnblogs.com")) {
      oSession["ui-color"] = "red"
    }

    修改HTTP请求

    如果要修改HTTP请求,代码应该放在OnBeforeRequest(oSession:Session)方法下面。

    我们可以修改HTTP请求中的任何数据,如HOST、Header、Cookie等

    修改HTTP请求中的Cookie

    if(oSession.uriContains("cnblogs.com")
    {
        //1.删除所有的cookie
        oSession.oRequest.headers.Remove("Cookie");
        
        //2.新建cookie
        oSession.oRequest.headers.Add("Cookie","username=testname;testpassword=P@ssword1");
    
        //修改Cookie,不能删除或者编辑单独的一个Cookie,需要替换Cookie字符串
        var oldCookie = oSession.oRequest["Cookie"];
        oldCookie = oldCookie.Replace("cookieName=","ignoreme=")
        oSession.oRequest["Cookie"] = oldCookie;
    
        //4.全新的Cookie
        var newCookie = "your cookie String";
        oSession.oRequest["Cookie"] = newCookie;  
    }

    替换HTTP请求的Host地址

    我们最初发送给A站点的HTTP请求,都被Fiddler转发到B站点,而在浏览器中毫无感觉。测试或者debug过程中经常会有这种需求。

    例如用 www.sina.com 代替 www.baidu.com

    if (oSession.HostnameIs("www.sina.com"))
    {
        oSession.hostname = "www.baidu.com";
    }

    修改HTTP请求中的Header

    if (oSession.uriContains("cnblogs.com"))
    {
        // 添加Header
        oSession.oRequest.headers.Add("headerName1","headerValue1");
    
        // 删除Header
    oSession.oRequest.headers.Remove("headerName2");
    
        // 修改Header
    oSession.oRequest["Referer"] = "www.baidu.com/TestReferer";
    }

    修改HTTP请求中发的Body

    方法一:先把Body的字符串读取出来,修改后再塞回去。

    static function OnBeforeRequest(oSession:Session)
    {
        if (oSession.uriContains("http://www.cnblogs.com/TankXiao/"))
        {
            oSession.utilDecodeRequest();
            // 获取Request中的body字符串
            var strBody=oSession.GetRequestBodyAsString();
            // 用正则表达式或者 replace 方法修改string
            strBody=strBody.replace("1111","2222");
            // 弹个对话框检查下修改后的body
            FiddlerObject.alert(strBody);
            // 将修改后的body,重新写会Request中
           oSession.utilSeRequestBody(strBody);
        }
    }

     第二种方法:也可以采用非常简单地方法,即直接替换body中的数据

    if (oSession.uriContains("cnblogs.com"))
    {
        oSession.utilReplaceInRequest("1111","2222");
    }

    修改HTTP响应

    在Script中修改HTTP响应的方法,代码应该放在OnBefroeResponse(oSession:Session)方法下面。

    修改HTTP响应的方法和修改HTTP请求的方法差不多。

    实例:使用如下代码,修改博客园网页中的数据

    if (oSession.uriContains("cnblogs.com"))
    {
        oSession.utiReplaceInResponse("小坦克","大坦克 肖佳");  
    }

    打开浏览器,输入 www.cnblogs.com/tankxiao/

    读写txt文件

    先引用命名空间

    import System。IO;
        // Read
        var txtPath = "c:\tank.txt"
        var allNumbers = File.ReadAllLines(txtPath);
        var exist = 0;
        for(var i = 0; i<allNumbers.length;i++)
        {
            FiddlerObject.alert(allNumbers[i]);
        }
    
        // write
        var txtPath = "c:\tank.txt"
        var txtWrite = File.AppendText(textPath);
        txtWriteLine("www.cnblogs.com/tankxiao");
        txtWrite.Close();

    使用正则表达式

    先引用命名空间

    import System.Text.RegularExpressions;
    
    var resBody = "<String>tankxiao.cnblogs.com</string>";
    var r = new Regex("<string>(.*?)</string>");
    var mc = r.Match(resBody);
    FiddlerObject.alert(mc.Groups[1].Value);

    保存Session

    var sazFile = "c:\aff\"+number;
    var sessionList : Session[] = [oSession];
    Utilities.WriteSessionArchive(sazFile,sessionList,null,true)

    读取Session,并且使用Fiddler来发送

    var sazFile="c:\aff\"+number;
    var sessionList : Session[] = Utilities.ReadSessionArchive(sazFile,true);
    FiddlerApplication.oProxy.SendRequest(sessionList[0].oRequest.headers,sessionList[0].requestBodyBytes,null);

    深入理解Cookie机制

    HTTP协议是无状态的

    对于浏览器的每一次请求,服务器都会独立处理。不与之前或之后的请求发生关联。即使同一个浏览器发送了3个请求,服务器也会独立处理这3个请求,服务器并不知道这3个请求是来自同一个浏览器。

    服务器需要识别浏览器请求,就必须弄清楚浏览器的请求状态。既然HTTP协议是无状态的,那就让服务器和浏览器共同维护一个状态,这就是会话机制。

    会话机制

    浏览器第一次请求服务器时,服务器创建一个会话,并将会话的id作为响应的一部分发送给浏览器。

    浏览器存储会话id,并在后续第二次和第三次请求中带上会话id。服务器取得请求中的会话id就知道是不是同一个用户了。

    Cookie机制

    服务器在内存中保存会话对象。浏览器可以使用Cookie机制保存会话id。

    Cookie机制是一种会话机制。Cookie是浏览器用来存储少量数据的一种机制,数据以“key=value”形式存储,浏览器发送HTTP请求时,自动附带cookie信息。

    Cookie是什么

    Cookie是一小段文本信息,伴随着用户请求和页面在浏览器和Web服务器之间传递。

    Cookie是一种HTTP Header,以“key=value”的形式组成,比如ip_country=CN

    两个Cookie之间用分号隔开,比如ip_country=CN;mbox=check#true#1499311989

    浏览器把Cookie通过HTTP请求中的Header,比如“Cookie:ip_country=CN”发送给Web服务器。Web服务器通过HTTP响应中的Header,比如“Set-Cookie:ip_country=CN”,把Cookie发送给浏览器。

    Cookie的作用

    Cookie最主要的作用是用来做用户认证,还可以用于保存用户的一些其他信息。

    Cookie也可以用于互联网精确广告定向技术,比如用户浏览了某些商品,就可以用Cookie将其记录下来。

    Cookie的属性

    从Fiddler的抓包中,我们可以看到Web服务器返回了下面这一段数据给浏览器。

    Set-Cookie:cookie_user_token=C5CBD6FBDJO5HGH324OV452;Expires=Thu,06-Jul-2017 09:17:46 GMT;Path=/;HttpOnly

    Expires属性:Expires的值是一个时间,代表过期时间。过了这个时间,该Cookie就失效了。如果不指定Expire time,表示关闭浏览器/页面的时候,此Cookie就应该被浏览器删除了。

    Path属性:表示Cookie所属的路径,asp.net默认为“/”,就是根目录。在同一个服务器上的目录如下:/test/、/test/cd/、/test/dd/。现假设一个Cookie1的path为/test/,Cookie2的path为/test/cd/,那么test下的所有页面都可以访问到Cookie1,而/test/cd/的子页面不能访问Cookie2。

    HttpOnly属性:这是个关于安全方面的属性,将一个Cookie设置为HttpOnly后,通过JavaScript脚本将无法读取到Cookie信息,这能有效地防止黑客用XSS发起攻击。一般来说,跟登陆相关的Cookie必须设置为HttpOnly。

    Cookie的分类

    会话Cooike:临时地Cookie,它记录了用户访问站点时的设置和偏好;关闭浏览器,会话Cookie就被删除了

    持久Cookie:存储在硬盘上,不管浏览器退出或者计算机重启,持久cookie都继续存在,持久Cookie有过期时间。

    网站自动登录的原理

    在登录页面输入用户名、密码,选择保存密码单机登录(这时候,其实在你的机器上已保存好了登录的Cookie),下次访问的时候。

    1. 用户打开IE浏览器,在地址栏输入www.cnblogs.com
    2. IE首先会在硬盘中查找关于cnblogs.comde Cookie,然后把Cookie放到HTTP Request中,再把Request发给Web服务器。
    3. Web服务器返回博客园首页,这时你会看到自己已经登录了。

    Fiddler实现Cookie劫持攻击

    通常有两种方法可以截获他人的Cookie

    1. 通过跨站脚本攻击(XSS)获取他人的Cookie。
    2. 想办法获取别人电脑上保存的Cookie文件。

    找到登录的Cookie

      首先,我们需要使用 Fiddler 找到跟登录相关的 Cookie,具体的操作步骤如下。

    打开豆瓣网 www.douban.com,用账号和密码登录。

    启动Fiddler,在豆瓣网中单击右上角的用户名,在菜单栏中单机“账号管理”,就跳转到了这个页面:https://www.douban.com/accounts/。

    在Fiddler中选择https://www.douban.com/accounts/这个Session,然后用鼠标右键选择Replay -> Reissue and Edit。在Raw选项卡下,找到一个名叫dbcl2的Cookie,比如我这里的是:dbcl2=“163572032:csUO41kxRDg”;删除这个 dbcl2 的Cookie,然后单机“Run to Completion”放行。

    我们可以发现跳转到了登录页面。这说明dbcl2这个Cookie是跟登录相关的,将其删除后就处于未登录状态,Web服务器会返回302状态码,会自动重定向到登录界面。

    网站退出的作用

    网站退出是明确地告诉服务器立即删除服务器端的Session对象,这样客户端登录的Cookie就失效了。如果用户登录某个网站,然后离开的时候直接关闭浏览器,那么登录的Cookie还在,存在被冒用的风险。保险的办法是单击退出而不是直接关闭浏览器。

    HTTP基本认证

      HTTP协议是无状态的,浏览器和Web服务器之间可以通过Cookie来识别身份。一些桌面应用程序(比如新浪桌面客户端)跟Web服务器之间是如何识别身份呢?

      HTTP协议中还有两种认证方式,分别是基本认证摘要认证。认证就是客户端要给服务器出示一些自己的身份证明,来证明自己是谁,一旦服务器知道了客户端的身份,就可以判定客户端可以进行访问了。通常是通过提供用户名和密码来进行认证的。

    什么是HTTP基本认证

      一些网站和Web服务使用的是HTTP基本认证。有些桌面应用程序也通过HTTP协议跟Web服务器交互,桌面应用程序一般不会使用Cookie,而是把“用户名+冒号+密码”用Base64编码放在HTTP请求中的 Header Authorization 中发送给服务器,这种方式叫HTTP基本认证(Basic Authentication)

      在基本认证中,Web服务器可以拒绝一个事物,要求客户端提供有效地用户名和密码。服务器会返回401状态码来初始化认证质询,并用WWW-Authenticate响应首部指定要访问的安全域。浏览器收到质询时,会打开一个对话框,请求用户输入用户名和密码,然后将用户名和密码用Base64编码,再用 Authorization 请求首部发送给服务器。

    在Fiddler中可以在Inspectors中的Auth选项卡中查看实际用户名和密码。

    HTTP基本认证的缺点

    把“用户名+冒号+密码”用Base64编码,可逆,所以不能用HTTP在网络上传输,一定要用HTTPS传输,因为HTTPS是加密的,稍微安全一点。

    1. HTTP协议是无状态的,同一个客户端对服务器的每个请求都要求认证。
    2. 基本认证会通过网络发送用户名和密码,这些用户名和密码以Base64编码。Base64编码是一种可逆编码,容易被第三方拦截。
    3. 使用基本认证登录后,除非关闭浏览器或者清楚历史记录,否则将无法登出。
    4. 无法防止重放攻击。即使基本认证的密码是经过加密传输的,第三方仍然可以捕获被修改过的用户名和密码,并将修改过的用户名和密码反复多次地重放给原始服务器,以获得对服务器的访问权,基本认证没有什么措施可以防止这些重放攻击。

    摘要认证

    摘要认证是针对基本认证存在的诸多问题而进行改良的方案。摘要认证是另外一种HTTP认证协议,它试图修复基本认证的严重缺陷,进行如下改进。

    1. 通过传递用户名、密码等计算出来的摘要来解决以明文方式在网络上发送密码的问题。
    2. 通过服务器产生随机数 nonce 的方式防止恶意用户捕获并重放认证的握手过程。
    3. 通过客户端产生随机数 cnonce 的方式支持客户端对服务器的认证。
    4. 通过对内容也加入摘要计算的方式,可以有选择地防止对报文内容的篡改。

    Fiddler发送HTTP请求

    Fiddler可以使用重放功能或者Fiddler Composer来发送HTTP请求。

    Fiddler Composer发送HTTP请求

    Fiddler有个功能组件叫Composer,可以用来发送HTTP请求。Fiddler的作者把HTTP Request发送器取名为Composer,中文意思是乐曲的创造者,很有诗意。

    Composer发送Get请求

    Composer的编辑模式

    Composer有两种编辑模式

    1. Parsed模式。这个模式比较常用,把HTTP请求分为3个部分:请求起始行,请求Header和请求Body。通过该模式,创建一个HTTP请求变得很容易。
    2. Raw模式。该模式需要一行一行地写一个HTTP请求。

    Composer发送Post请求

    禅道的演示网站 http://demo.zendao.net,用户名是demo,密码是123456。手动登录抓包如下:

    用Fiddler发送一个登录的Post请求

    Composer编辑之前捕获的HTTP请求

      在Web会话列表中,可以将捕获到的HTTP请求拖拽到Composer中,编辑后再发送出去。

    Fiddler重新发送HTTP请求

      Fiddler可以将捕获的HTTP请求重新发送出去。Fiddler工具栏上有一个Replay按钮,单击该按钮可以向Web服务器重新发送选中的HTTP请求。当选中多个Session,并且按下Replay按钮后,Fiddler会用多线程同时发送请求。此功能可以用来做并发性能测试。

    Replay菜单

      按下Shift键的同时单击该按钮,会弹出提示框,要求指定每个请求被重新发送的次数。

      按下Ctrl键的同时单击该按钮,在HTTP请求中不会包含IF-Modified-Since和If-None-Match。

      在会话列表中,选中一个或者多个Session,右键菜单我们可以看到一个Replay菜单。

    Reissue Requests 重新发送请求,和菜单栏上Replay按钮是一样的功能
    Reissue Unconditionally 无条件反复发送选中的请求
    Reissue and Edit 把选中的请求以原来的形式重新发送,在每个新的Session中设置断点,在请求发送给服务器之前,可以修改请求
    Reissue and Verify 重新发送请求,检查响应,如果响应和上一个请求一样,就会变成绿色
    Reissue Sequentially 选中多个Session会按顺序一个一个重新发送请求,是单线程模式
    Reissue from Composer 在Composer中编辑该请求 
    Revisit in IE 在IE浏览器中用Get方法访问这个请求 

    简单地性能测试

      在Web Sessions列表中,选中一个或者多个Session,然后按下Shift键的同时单击“Replay”按钮,会弹出提示框,要求指定每个请求被重新发送的次数。Fiddler会用多线程同时发送该请求,相当于模拟了很多用户同时访问该请求。

    先编辑再发送

      在Web Sessions列表中,选中一个Session,单击鼠标右键选择Replay - Reissue and Edit。该功能可以把一个HTTP请求重新发送出去,并且拦截住,将其进行编辑,然后再发出去。

    安全测试之重放攻击

      重放攻击(Replay Attacks)又称重播攻击、回放攻击。

      攻击者发送一个目的主机已接收过的包,特别是在认证的过程中,用于认证用户身份所接收的包,来达到欺骗系统的目的。该包主要用于身份认证过程,破坏认证的安全性。

    重放攻击是怎么发生的

      重放攻击是指黑客通过抓包的方式,得到客户端的请求数据及请求连接,重复地向服务器发送请求的行为。

    重放攻击的危害

      比如APP中有一个“下单”的操作,当你单击购买按钮时,APP向服务器发送购买的请求。而这时黑客对你的请求进行了抓包,得到了你的传输数据,黑客把数据再往服务器提交一次。这就导致了你可能只想购买一个产品,结果由于黑客重放攻击,你就购买了多次。

      很多网站的投票或者点赞功能也要防止重放。黑客会对投票或者点赞进行抓包,然后重复发送来进行刷票。

    重放攻击的解决方案

      在HTTP请求中添加时间戳(stamp)数字签名(sign),可以防止重放攻击。

      数字签名是为了确保请求的有效性。因为签名是经过加密的,只有客户端和服务器知道加密方式及Key,第三方模拟不了。

      时间戳是为了确保请求的时效性。我们将上一次请求的时间戳进行存储。

    Fiddler实现弱网测试

      网速慢和网络中断的情况,我们称之为弱网。

      使用Fiddler能让弱网测试变得非常简单,Fiddler是通过延迟发送或接收数据的时间来模拟限速的。

    什么是弱网

      验证在弱网的情况下软件的处理机制,从而避免因用户体验不友好造成用户的流失。弱网测试属于健壮性测试。在弱网测试条件下,要测试产品的运行状态、处理机制、提示信息,以及网络恢复后的重连等。

    弱网环境带来的问题

      1、操作时间慢。用户在地铁里操作手机APP,由于网络慢,页面加载不出来。原因可能是API在网络慢的情况下性能很差。用户在公交车上用手机APP看新闻,当公交车进入隧道的时候,网络变得很慢,APP上的新闻一直没法加载出来。我们需要测试每个API消耗的时间,这个指标可以衡量APP性能的好坏。

      2、用户体验不好。一个安卓手机用户使用一款看小说的APP在地铁里看小说,当地铁进入隧道的时候,手机信号中断了。用户单击翻页,想看下一页的时候,因为网络中断,APP的界面卡死并且闪退。原因是APP不稳定,没有处理好网络中断的情况。

      3、非正常情况下,出现Bug的可能性会增加。如一个电商的手机APP有秒杀优惠券的功能。一些APP用户在乘坐电梯的时候,使用APP来秒杀优惠券。单击秒杀优惠券的按钮后,APP响应缓慢。于是,用户重复单击秒杀优惠券按钮。这就造成了几乎同一时间,同一个用户有多个HTTP请求发送服务器,形成了并发,结果用户抢到了多张优惠券。

    弱网测试的目的

      弱网测试的目的是让APP在任何网络下都能表现自如,让开发人员能够预知APP在较差网络环境下的表现,提前发现问题,进行有针对性的优化

    弱网的场景

      1、网络慢或者延迟,导致加载时间长。

      2、网络中断,Web服务器返回500等状态码。

      3、网络超时,HTTP请求发出去后,很久都没有响应。

    Fiddler模拟网络延迟

      1、启动Fiddler,选择Rules - Performances - Simulate Modem Speeds

      2、打开浏览器,访问网站。

    精确控制网速

    可参考:https://www.jianshu.com/p/b9e349b8f411

      1、启动Fiddler,选择Rules - Performances - Simulate Modem Speeds

      2、在FiddlerScript中找到如下一段代码

            if (m_SimulateModem) {
                // Delay sends by 300ms per KB uploaded.  每上传1KB数据,延时0.3秒
                oSession["request-trickle-delay"] = "300"; 
                // Delay receives by 150ms per KB downloaded.  每下载1KB数据,延时0.15秒
                oSession["response-trickle-delay"] = "150"; 
            }

      改动数值,保存Script即可。

      3、保存完之后,原本已经勾选的Simulate Modem Speeds会被取消勾选:再次选中 Rules - Performances - Simulate Modem Speeds

      4、再次打开浏览器,访问网页

    如果你习惯用kbps 去算的话,那么我们的算法就是 1KB/下载速度 = 需要delay的时间(毫秒),比如50KBps 需要delay20毫秒来接收数据。

    request-trickle-delay中的值代表每KB的数据被上传时会被延时多少毫秒;response-trickle-delay则对应下载时每KB的数据会被延时多少毫秒。
    比如你要模拟上传速度100KBps的网络,那上传延迟就是1KB/100KBps=0.01s=10ms,就改成10。

    比如默认设置下上传延时为300ms下载延时为150ms,可以推算出大致的模拟带宽为:
    上传带宽 = 1KB/300ms = (1 * 8/1000) /0.300 ≈ 0.027Mbps
    下载带宽 = 1KB/150ms = (1 * 8/1000) /0.150 ≈ 0.053Mbps
    (1MB = 1024 KB ≈ 1000 KB 这里为了运算简便就用了1000的倍数,忽略误差)

    方法二,下面的脚本实现了一个随机延时量设置,使得网络带宽不是恒定为一个低速的值,而是会在一定范围内随机抖动:

    if (m_SimulateModem) {
        // Delay sends by 300ms per KB uploaded.
        oSession["request-trickle-delay"] = ""+randInt(1,50);
        // Delay receives by 150ms per KB downloaded.
        oSession["response-trickle-delay"] = ""+randInt(1,50);
    }

    方法三:

    点击fiddlerScript 在代码里找到onBeforeRequest,这里定义了在发送请求前做什么。加入如下代码可以实现延迟:

    oSession["request-trickle-delay"]="3000";  //请求阶段延迟3秒
    oSession["response-trickle-delay"]="3000";  //响应阶段延迟3秒

    Fiddler模拟网络中断

      用Fiddler可以下断点,伪造HTTP响应。移动端发出的HTTP请求根本没有到达服务器,而是被Fiddler直接返回了一个伪造的HTTP响应。

      具体做法是用Fiddler拦截住移动端发出来的HTTP请求,然后在“Choose Response”选中需要返回的状态码并返回给移动客户端。

    或者可以在桌面新建一个txt文档:

    HTTP/1.1 500 Internal Server Error
    Date: Fri, 11 Aug 2019 07:25:35 GMT
    Content-Type: text/html; charset=utf-8
    Connection: keep-alive
    Vary: Accept-Encoding
    
    this is 500 internal Server Error by Fiddler! tank

    Fiddler模拟网络超时

      利用Fiddler下断点的功能拦截移动客户端发出的HTTP请求,这样就相当于网络超时了,然后再检查客户端有没有重发或者超时的机制。

  • 相关阅读:
    剑指offer23-二叉搜索树的后序遍历序列
    剑指offer24-二叉树中和为某一值的路径
    剑指offer-复杂链表的复制
    剑指offer-二叉搜索树与双向链表
    剑指offer-字符串的排序
    剑指offer-数组中出现次数超过一半的数字
    剑指offer-最小的k个数
    c++中参数加&与不加的区别
    第九届蓝桥杯(A组填空题)
    基于优先级的多道程序系统作业调度——基于优先级
  • 原文地址:https://www.cnblogs.com/dongye95/p/10819201.html
Copyright © 2020-2023  润新知