想了解下Mysql客戶端在登陸時的交互過程,想看看能不能在獲取到Mysql表數據的情況下,直接使用加密的密碼(兩層sha1)進行登陸,下載最新版本看了下發現行不通,因爲登錄時缺少密碼的單層sha1值,不過之前的老版本貌似在驗證時存在問題,看來新版的已經改掉了,下面是模擬客戶端登陸的過程。
import sys
from socket import *
import hashlib
SEED_LEN=20
Succflag='\x07\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00'
def EncryptPass(pwd,seed):
EncryptPwd=''
a=pwd
b=hashlib.sha1(a).digest()
c=hashlib.sha1(b).digest()
m = hashlib.sha1()
m.update(seed)
m.update(c)
d=m.digest()
for i in range(SEED_LEN):
EncryptPwd=EncryptPwd+chr(ord(d[i])^ord(b[i]))
return EncryptPwd
def GetSeed(pack):
for i in range(len(pack)):
if ord(pack[i])==0x00:
pack=pack[5+i:]
break
seed1=pack[:8] #seed1
pack=pack[17:]
for j in range(len(pack)):
if ord(pack[j])!=0x00:
pack=pack[j:]
break
seed2=pack[:12] #seed2
seed=seed1+seed2
return seed
if __name__=="__main__":
serverHost = '127.0.0.1'
serverPort = 3306
user='root'
password='123qwe'
sockobj = socket(AF_INET, SOCK_STREAM)
sockobj.connect((serverHost, serverPort))
pack=sockobj.recv(1024)[5:]
seed=GetSeed(pack)
EncryptPwd=EncryptPass(password,seed)
#print EncryptPwd
Head='\x00\x00\x01'
VerityHead='\x85\xA6\x03\x00\x00\x00\x00\x40\x21'
Padding='\x00'*23
VerityLen=len(VerityHead)+len(Padding)+len(user)+len(EncryptPwd)+2
print hex(VerityLen)
VerityPack=chr(VerityLen)+Head+VerityHead+Padding+user+chr(0)+chr(len(EncryptPwd))+EncryptPwd
sockobj.sendall(VerityPack)
rev= sockobj.recv(1024)
Logonflag=rev[:11]
if cmp(Logonflag,Succflag)==0 :
print 'The password is Right!'
else :
print 'The password is Error!'
#for i in Logonflag:
#print hex(ord(i))
sockobj.close()