想抓取TP-Link等路由器的页面源码发现返回[HTTP 401 Unauthorized]错误,经过对HTTP协议文档[RFC-2616]的查找在10.4.2节发现了相关描述,意思就是说如果返回了401错误就表明链接WEB服务器需要HTTP简单认证,而且在服务器的Response中一定[MUST]有WWW-Authenticate头域,客户端应该[SHOULD]重新链接WEB服务器,但在Request的头域中要有HTTP
access authentication(描述于[RFC-2617]中)
access authentication(描述于[RFC-2617]中)
HTTP access authentication描述
其中的描述是这样的:如果收到401错误,客户端必须将用户名密码以如下格式(basic-credentials)放在 Authorization头域中
basic-credentials = base64-user-pass base64-user-pass = <base64 [4] encoding of user-pass, except not limited to 76 char/line> user-pass = userid ":" password userid = *<TEXT excluding ":"> password = *TEXT
比如想将用户名为"Aladdin"密码为"open sesame"作为验证发送的WEB服务器,HTTP HEADER中应该是这样的:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
其中Basic后面的字符串就是"Aladdin:open sesame"经过base64算法产生的字符,综合起来你应该这样发送HPPT Request:
GET / HTTP/1.1[\r\n] Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==[\r\n] [Other Header Field]
用Python实现的HTTP
Request
import socket, sys, base64 host = sys.argv[1] port = int(sys.argv[2]) user = 'admin' password = 'admin' s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) credent = base64.b64encode('%s:%s' % (user, password)) s.sendall("GET / HTTP/1.1\r\nAuthorization: Basic %s\r\n\r\n" % credent) while True: data = s.recv(2048) sys.stdout.write(data)
需要说明的是,许多路由器的认证都是用户名admin密码admin,在python中有base64算法库只需要调用base64.b64encode(str)就可以得到base64算法处理过的字符串了