fixed potential attack vector (attaching a bad version message as message ack data)
This commit is contained in:
parent
090af50b04
commit
2b4c6b67a8
|
@ -647,7 +647,7 @@ class receiveDataThread(QThread):
|
||||||
sqlReturnQueue.get()
|
sqlReturnQueue.get()
|
||||||
sqlLock.release()
|
sqlLock.release()
|
||||||
|
|
||||||
blockMessage = False #Set to True if the user shouldn't see the message according to black or white lists.
|
blockMessage = False #Gets set to True if the user shouldn't see the message according to black or white lists.
|
||||||
fromAddress = encodeAddress(sendersAddressVersionNumber,sendersStreamNumber,ripe.digest())
|
fromAddress = encodeAddress(sendersAddressVersionNumber,sendersStreamNumber,ripe.digest())
|
||||||
if config.get('bitmessagesettings', 'blackwhitelist') == 'black':
|
if config.get('bitmessagesettings', 'blackwhitelist') == 'black':
|
||||||
t = (fromAddress,)
|
t = (fromAddress,)
|
||||||
|
@ -790,15 +790,6 @@ class receiveDataThread(QThread):
|
||||||
return
|
return
|
||||||
|
|
||||||
#We must check to make sure the proof of work is sufficient.
|
#We must check to make sure the proof of work is sufficient.
|
||||||
#POW, = unpack('>Q',hashlib.sha512(hashlib.sha512(self.data[24:24+self.payloadLength]).digest()).digest()[4:12])
|
|
||||||
#print 'POW:', POW
|
|
||||||
#if POW > 2**64 / ((self.payloadLength+payloadLengthExtraBytes) * averageProofOfWorkNonceTrialsPerByte):
|
|
||||||
# printLock.acquire()
|
|
||||||
# print 'The Proof of Work in the pubkey message is insufficient. Ignoring it.'
|
|
||||||
# print 'pubkey payload length:', len(self.data[24:self.payloadLength+24])
|
|
||||||
# print repr(self.data[24:self.payloadLength+24])
|
|
||||||
# printLock.release()
|
|
||||||
# return
|
|
||||||
if not self.isProofOfWorkSufficient():
|
if not self.isProofOfWorkSufficient():
|
||||||
print 'Proof of work in pubkey message insufficient.'
|
print 'Proof of work in pubkey message insufficient.'
|
||||||
return
|
return
|
||||||
|
@ -1022,7 +1013,6 @@ class receiveDataThread(QThread):
|
||||||
if queryreturn <> []:
|
if queryreturn <> []:
|
||||||
for row in queryreturn:
|
for row in queryreturn:
|
||||||
objectType, payload = row
|
objectType, payload = row
|
||||||
print 'Sending data out of inventory that came from sql.' #todo: remove line
|
|
||||||
self.sendData(objectType,payload)
|
self.sendData(objectType,payload)
|
||||||
else:
|
else:
|
||||||
print 'Someone asked for an object with a getdata which is not in either our memory inventory or our SQL inventory. That shouldn\'t have happened.'
|
print 'Someone asked for an object with a getdata which is not in either our memory inventory or our SQL inventory. That shouldn\'t have happened.'
|
||||||
|
@ -1256,9 +1246,9 @@ class receiveDataThread(QThread):
|
||||||
#We have received a version message
|
#We have received a version message
|
||||||
def recversion(self):
|
def recversion(self):
|
||||||
if self.payloadLength < 83:
|
if self.payloadLength < 83:
|
||||||
self.data = ''
|
#This version message is unreasonably short. Forget it.
|
||||||
return
|
return
|
||||||
else:
|
elif not self.verackSent: #There is a potential exploit if we don't check to make sure that we have not already received and accepted a version message: An attacker could connect directly to us, send a msg message with the ackdata set to an invalid version message which would cause us to close the connection to the attacker thus proving that we were able to decode the message. Checking the connectionIsOrWasFullyEstablished variable would also suffice.
|
||||||
self.remoteProtocolVersion, = unpack('>L',self.data[24:28])
|
self.remoteProtocolVersion, = unpack('>L',self.data[24:28])
|
||||||
#print 'remoteProtocolVersion', self.remoteProtocolVersion
|
#print 'remoteProtocolVersion', self.remoteProtocolVersion
|
||||||
self.myExternalIP = socket.inet_ntoa(self.data[64:68])
|
self.myExternalIP = socket.inet_ntoa(self.data[64:68])
|
||||||
|
@ -1308,18 +1298,6 @@ class receiveDataThread(QThread):
|
||||||
self.sendverack()
|
self.sendverack()
|
||||||
if self.initiatedConnection == False:
|
if self.initiatedConnection == False:
|
||||||
self.sendversion()
|
self.sendversion()
|
||||||
'''#Now that we have a friendly connection with this peer, we should advertise it to our other peers
|
|
||||||
payload = '\x01'
|
|
||||||
payload += pack('>I',int(time.time()))
|
|
||||||
payload += pack('>I',self.streamNumber)
|
|
||||||
payload += pack('>q',1) #service bit flags offered by this node
|
|
||||||
payload += '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF' + socket.inet_aton(self.HOST)
|
|
||||||
payload += pack('>H',self.remoteNodeIncomingPort)#remote port
|
|
||||||
datatosend = '\xE9\xBE\xB4\xD9addr\x00\x00\x00\x00\x00\x00\x00\x00'
|
|
||||||
datatosend += pack('>L',len(payload)) #payload length
|
|
||||||
datatosend += hashlib.sha512(payload).digest()[0:4]
|
|
||||||
datatosend += payload
|
|
||||||
broadcastToSendDataQueues((self.streamNumber, 'send', datatosend))'''
|
|
||||||
|
|
||||||
#Sends a version message
|
#Sends a version message
|
||||||
def sendversion(self):
|
def sendversion(self):
|
||||||
|
@ -1449,9 +1427,9 @@ class sendDataThread(QThread):
|
||||||
self.streamNumber = specifiedStreamNumber
|
self.streamNumber = specifiedStreamNumber
|
||||||
elif command == 'send':
|
elif command == 'send':
|
||||||
try:
|
try:
|
||||||
#To prevent some network analysis, 'leak' the data out to our peer after waiting a sort random amount of time.
|
#To prevent some network analysis, 'leak' the data out to our peer after waiting a random amount of time.
|
||||||
random.seed()
|
random.seed()
|
||||||
#time.sleep(random.randrange(0, 5)) todo: uncomment this line.
|
time.sleep(random.randrange(0, 5))
|
||||||
self.sock.sendall(data)
|
self.sock.sendall(data)
|
||||||
self.lastTimeISentData = int(time.time())
|
self.lastTimeISentData = int(time.time())
|
||||||
except:
|
except:
|
||||||
|
@ -1845,7 +1823,7 @@ class singleWorker(QThread):
|
||||||
payload += messageToTransmit
|
payload += messageToTransmit
|
||||||
|
|
||||||
#Later, if anyone impliments clients that don't send the ack_data, then we should probably check here to make sure that the receiver will make use of this ack_data and not attach it if not.
|
#Later, if anyone impliments clients that don't send the ack_data, then we should probably check here to make sure that the receiver will make use of this ack_data and not attach it if not.
|
||||||
fullAckPayload = self.generateFullAckMessage(ackdata,fromStreamNumber)
|
fullAckPayload = self.generateFullAckMessage(ackdata,toStreamNumber)
|
||||||
payload += encodeVarint(len(fullAckPayload))
|
payload += encodeVarint(len(fullAckPayload))
|
||||||
payload += fullAckPayload
|
payload += fullAckPayload
|
||||||
sendersPrivKey = rsa.PrivateKey(config.getint(fromaddress, 'n'),config.getint(fromaddress, 'e'),config.getint(fromaddress, 'd'),config.getint(fromaddress, 'p'),config.getint(fromaddress, 'q'))
|
sendersPrivKey = rsa.PrivateKey(config.getint(fromaddress, 'n'),config.getint(fromaddress, 'e'),config.getint(fromaddress, 'd'),config.getint(fromaddress, 'p'),config.getint(fromaddress, 'q'))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user