Cookie & Session
之前本来想给社团里大一的讲下PHP和前端、数据库的简单交互以及一些字符过滤或转义相关的安全问题,后来Boss说就简单讲讲Python的Socket和相应的TCP连接是如何工作的(中间因为部长理解有误又看了两天的CGI)。感觉这只够讲一个下午啊,这学期另外还有安排的一下午讲点啥呢?后来就想到了Cookie和Session。感觉这个其实挺常用的,而自己又不太熟悉,顺便逼自己学一把也好。
Cookie是指某网站为了方便与用户交互,需要储存在用户本地终端上的数据。这也就意味着,我们其实可以在本地访问、修改它们。我们是借由Browser访问网页的,所以Cookie管理和Browser密切相关。那么,我们就先从它的构建讲起:
当第一次访问页面的时候,Server方若想发送一个Cookie过来,可通过Set-Cookie来设置,将Cookie信息附加到HTTP Header中。比如,用CGI处理的话,可以参考http://blog.csdn.net/hawksoft/article/details/43449151 ,写作 ——
print “Set-Cookie: User-ID = XYZ;
”
print “Set-Cookie: Password = XYZ123;
”
若Browser接收并允许Cookie,则会按自己的管理方式,将Cookie信息储存到相应的地方。比如说,对于Chrome,则会储存在它的User Data文件夹里
其Cookie信息Chrome一般都有加密。当用txt打开Cookies是一堆乱码,只能看出域名;用sublime打开则不同。我想这是记录式文件吧。如果想正确查看里面的信息,可以在Chrome的设置里看到。而对于用户密码这些敏感信息,Chrome自己是会另外单独存放的,同样在设置上面可以看到。而其他浏览器对Cookie的管理则又会有所不同。
那么,Cookie一般都会存放哪些内容和属性?下面列举一些 ——
Expires: 有效期。若它为0,则表示关闭浏览器时即失效
Domain: Cookie对应的域名。一般就是发送Cookie的网页,但也可以是另外的网页。然而并没有什么用,所以不说这个了
Path: 有权限调用这个Cookie的路径。一般为/,即表示任意路径下的文件
至于存放内容,可以是Username, Password, SessionID等。当你访问一网页的时候,浏览器会自动检索你的Cookie,若内容可用(比如说Expires未到)则会附加到数据中。当然自己用Python构建数据包的话,也能用标准库检索/获取Cookie并附加到请求数据上去。
至于Session,先说下工作原理吧。当用户第一次访问网页的时候(准确来说是不持有有效的SessionID时),Server会在内存里建立一个Session与之对应,保存该用户的现有信息,以弥补Http的无状态性。然后,Server回复一个SessionID给用户,作为用户身份的凭证。Session的有效时间默认为20分钟,即,用户在20分钟内不发送信息给Server,那么Server将销毁这个Session,用户又得重新建立一个对应自己状态的Session了。至于在本地Cookie上Session的标识SessionID,在Cookie上可看到,一般都是在浏览会话结束时即失效。
当然,为了交互,你也可以选择Session持久化。
从上面可以看出,Session这个机制存在着Session劫持、Session伪造等问题,并且它在一整个服务器上,不管是哪个后台文件,都是共用的(因为Session是在内存上维持)。但要真正用起来,还是有个很重要的前提,即你在SessionID生效时,获取到别人的SessionID。所以Session其实还是比较安全的,要利用的话,需要配合其他手段,比如XSS、中间人或者注入代码留个后门(比如输入xxx时可返回Username为admin的SessionID)。那么为了防止这个Session劫持,我们也可以同时对其他进行检验,比如IP。当然,更彻底的避免replay那些,还是用安全证书等等比较好。
另外,有些网站为了避免浏览器禁用Cookie时使用不了Session,允许了一种URL重写的方法。即,获知客户端无法用Cookie后,即改用URL交流SessionID。
那么,接下来就通过学校的一个选课系统的验证码绕过的漏洞了解多一下这个机制。这是前两天傍晚闲着无聊折腾的,没有构建数据包去真正测试过,时间有限。最近还有好些东西搞,况且这个其实早就被师兄们玩了N次了(却仍然不改),没太大兴趣去玩。
关于选课系统绕过验证码漏洞说明
首先要搞明白它后台对验证码是怎么处理的。通过测试,可以发现其特点有
1、提交页面根本没有向登录后台entrance1.asp发送任何能判别验证码的数据,比如说,验证码图片的文件位置,src后面的那串random数据等
2、 自己构建一个本地的网站,当random数不变时,每刷新一次,图片都会不同,而且需要的验证码和图片上的数字是一致的
3、操作前后SessionID始终不变
4、验证码图片对应的src略神奇 /code.asp?id=!!!&random=0.8535697448533028 当你手动改random数时,图片变化,需要的验证码也随之变化。
5、当你进入上面那个网址时,它返回的不是一张图片,而是一长串乱七八糟的字符。这个我不确定,个人猜测,回复的是没有指定MIME类型的图片数据。
6、当你刷新那个网址时,random值不变,内容却发生变化了(实质和2相同)
所以可以判断这个网站验证码的运作机制 —— 进入网页,会先有JS代码强制生成随机数,生成对应的<img src=”…”>。然后,<img src=”xxx”>的src链接对应的根本不是文件,而是视为给code.asp那个后台处理的网站发送一个附带随机数的请求。在那个后台文件对这个请求进行处理的时候,会返回一个验证码图片给Browser,同时给登录后台发送正确的验证码数据。如果登录后台判定你不对,那么它会直接重新发回这个页面给你浏览器,逼迫浏览器重新刷一次验证码。
接着,有个问题出来了 —— 后台怎么知道验证码数据和图片是对应上的呢?这其中的中介就是SessionID(其实就这么看还可以有其他可能,不过后面会证明
那么,问题就来了。如果我在打开网页之后,获得验证码图片,而登录后台也有一个正确的验证码数据了。那我不用浏览器了,而是选择构建数据包,把SessionID和验证码写进去直接发给登录后台会怎样?我想这样就能成功绕过验证码,然后顺利实行爆破了。
证明 : 1、在Chrome下打开两次登录页面,前一个打开的必定验证码错误
2、在Chrome下打开登录界面,然后在Resource处清除SessionID的Cookie(或用其他浏览器打开),必定验证码错误