├── .gitignore
├── log
├── deadlock_check.sh
├── freebsd_monitor.sh
└── linux_monitor.sh
├── usb_ids
├── usb.ids
└── class.ids
├── test_generation
├── location.conf
├── __init__.py
├── execution.xml
├── TestcaseLoader.py
├── testcase.xml
├── Testcase.py
├── test.xml
├── Sequence.py
└── XMLParser.py
├── payload
├── udlfb.info
├── panic_1.info
├── panic_2.info
├── old_payload
│ ├── udlfb.info
│ ├── panic_1.info
│ ├── panic_2.info
│ ├── i2400m_usb_bug.info
│ ├── keyspan_null_ptr.info
│ ├── usbserial_bug.info
│ ├── smsusb_null_ptr.info
│ ├── usbserial_null_ptr.info
│ ├── mal_payload.obj
│ ├── smsusb_null_ptr.obj
│ ├── usbserial_bug.obj
│ ├── keyspan_null_ptr.obj
│ ├── panic_3.obj
│ ├── usbserial_null_ptr.obj
│ ├── i2400m_usb_bug.obj
│ ├── windows_bod.obj
│ ├── udlfb.obj
│ ├── panic_1.obj
│ └── panic_2.obj
├── i2400m_usb_bug.info
├── keyspan_null_ptr.info
├── usbserial_bug.info
├── smsusb_null_ptr.info
├── usbserial_null_ptr.info
├── mal_payload2.obj
├── smsusb_null_ptr.obj
├── usbserial_bug.obj
├── usbserial_null_ptr.obj
├── keyspan_null_ptr.obj
├── mal_payload.obj
├── windows_bos.obj
├── panic_3.obj
├── i2400m_usb_bug.obj
├── windows_bos2.obj
├── tests
│ ├── test3.obj
│ ├── test.obj
│ └── test2.obj
├── udlfb.obj
├── panic_1.obj
└── panic_2.obj
├── clustering
├── __init__.py
├── protocol.py
├── network_task_requester.py
└── network_task_distributor.py
├── emulator
├── __init__.py
├── enumeration_abortion.py
├── emulator.py
├── hid.py
└── enumeration.py
├── monitor
├── __init__.py
├── freebsd_monitor.py
├── monitor.py
└── linux_monitor.py
├── process
├── __init__.py
├── execute_object.py
├── only_payload.py
├── print_performance_process.py
├── client_process.py
├── distributor_process.py
├── process.py
└── multi_process.py
├── tools
├── __init__.py
├── output_information.txt
├── extract_class_ids.py
├── gen_reproduce_key.py
├── extract_vp_ids.py
└── port_old_payload.py
├── changelog
├── configurations
├── centos6.config
├── debian7.config
├── ubuntu1404.config
├── freebsd10_1.config
├── ubuntu1404_updated.config
├── debian7_3.config
└── debian7_2.config
├── qemu-2.1.1.patch
├── report_desc_reader.py
├── dev_desc
├── desc4.txt
├── desc1.txt
├── desc2.txt
├── desc.txt
├── desc6.txt
├── desc5.txt
├── desc3.txt
└── desc3.txt_tmp
├── help.txt
├── fuzzer.py
├── config.py
├── README.md
├── descFuzzer.py
├── usbparser.py
├── qemu.py
└── usbEmulator.py
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
2 |
--------------------------------------------------------------------------------
/log/deadlock_check.sh:
--------------------------------------------------------------------------------
1 | watch -n 30 "find -cmin +2 -cmin -100000"
2 |
--------------------------------------------------------------------------------
/usb_ids/usb.ids:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/schumilo/vUSBf/HEAD/usb_ids/usb.ids
--------------------------------------------------------------------------------
/test_generation/location.conf:
--------------------------------------------------------------------------------
1 | testfile: test.xml
2 | testcasefile: testcase.xml
3 | executionfile: execution.xml
4 |
--------------------------------------------------------------------------------
/payload/udlfb.info:
--------------------------------------------------------------------------------
1 | Abort transmission of the 3th payload to cause a kernel panic.
2 | @ Linux debian-7 3.15.0-rc5 #2 SMP Mon May 19 15:57:11 CEST 2014 x86_64 GNU/Linux
3 |
--------------------------------------------------------------------------------
/usb_ids/class.ids:
--------------------------------------------------------------------------------
1 | 00
2 | 01
3 | 02
4 | 03
5 | 05
6 | 06
7 | 07
8 | 08
9 | 09
10 | 0a
11 | 0b
12 | 0d
13 | 0e
14 | 58
15 | dc
16 | e0
17 | ef
18 | fe
19 | ff
20 |
--------------------------------------------------------------------------------
/payload/panic_1.info:
--------------------------------------------------------------------------------
1 | This payload cause a kernel panic.
2 | @ Linux ubuntu-victim 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
3 |
--------------------------------------------------------------------------------
/payload/panic_2.info:
--------------------------------------------------------------------------------
1 | This payload cause a kernel panic.
2 | @ Linux ubuntu-victim 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
3 |
--------------------------------------------------------------------------------
/payload/old_payload/udlfb.info:
--------------------------------------------------------------------------------
1 | Abort transmission of the 3th payload to cause a kernel panic.
2 | @ Linux debian-7 3.15.0-rc5 #2 SMP Mon May 19 15:57:11 CEST 2014 x86_64 GNU/Linux
3 |
--------------------------------------------------------------------------------
/payload/old_payload/panic_1.info:
--------------------------------------------------------------------------------
1 | This payload cause a kernel panic.
2 | @ Linux ubuntu-victim 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
3 |
--------------------------------------------------------------------------------
/payload/old_payload/panic_2.info:
--------------------------------------------------------------------------------
1 | This payload cause a kernel panic.
2 | @ Linux ubuntu-victim 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
3 |
--------------------------------------------------------------------------------
/payload/i2400m_usb_bug.info:
--------------------------------------------------------------------------------
1 | This payload results in an endless printk loop.
2 | @ Linux ubuntu-victim 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
3 |
--------------------------------------------------------------------------------
/payload/old_payload/i2400m_usb_bug.info:
--------------------------------------------------------------------------------
1 | This payload results in an endless printk loop.
2 | @ Linux ubuntu-victim 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
3 |
--------------------------------------------------------------------------------
/payload/keyspan_null_ptr.info:
--------------------------------------------------------------------------------
1 | This payload results in a NULL pointer dereference (NULL) @ keyspan_open.
2 | @ Linux ubuntu-victim 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
3 |
--------------------------------------------------------------------------------
/payload/usbserial_bug.info:
--------------------------------------------------------------------------------
1 | This payload results in an endless printk loop.
2 | @ Handspring Visor / Palm OS
3 | @ Linux ubuntu-victim 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
4 |
--------------------------------------------------------------------------------
/payload/old_payload/keyspan_null_ptr.info:
--------------------------------------------------------------------------------
1 | This payload results in a NULL pointer dereference (NULL) @ keyspan_open.
2 | @ Linux ubuntu-victim 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
3 |
--------------------------------------------------------------------------------
/payload/smsusb_null_ptr.info:
--------------------------------------------------------------------------------
1 | This payload results in a NULL pointer dereference (0000000000000004) @ smsusb_probe.
2 | @ Linux ubuntu-victim 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
3 |
--------------------------------------------------------------------------------
/payload/old_payload/usbserial_bug.info:
--------------------------------------------------------------------------------
1 | This payload results in an endless printk loop.
2 | @ Handspring Visor / Palm OS
3 | @ Linux ubuntu-victim 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
4 |
--------------------------------------------------------------------------------
/payload/usbserial_null_ptr.info:
--------------------------------------------------------------------------------
1 | This payload results in a NULL pointer dereference (0000000000000260) @ usb_serial_probe.
2 | @ Linux ubuntu-victim 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
3 |
--------------------------------------------------------------------------------
/payload/old_payload/smsusb_null_ptr.info:
--------------------------------------------------------------------------------
1 | This payload results in a NULL pointer dereference (0000000000000004) @ smsusb_probe.
2 | @ Linux ubuntu-victim 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
3 |
--------------------------------------------------------------------------------
/payload/old_payload/usbserial_null_ptr.info:
--------------------------------------------------------------------------------
1 | This payload results in a NULL pointer dereference (0000000000000260) @ usb_serial_probe.
2 | @ Linux ubuntu-victim 3.13.0-24-generic #46-Ubuntu SMP Thu Apr 10 19:11:08 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
3 |
--------------------------------------------------------------------------------
/clustering/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
--------------------------------------------------------------------------------
/emulator/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
--------------------------------------------------------------------------------
/monitor/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
--------------------------------------------------------------------------------
/process/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
--------------------------------------------------------------------------------
/test_generation/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
--------------------------------------------------------------------------------
/tools/__init__.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 |
--------------------------------------------------------------------------------
/payload/mal_payload2.obj:
--------------------------------------------------------------------------------
1 | NDQ5MTUKCjg0NTf/aWRQcm9kdWN0/0FMTAoxMDAz/2lzVmVuZG9y/0FMTAoxMf9iRGV2aWNlQ2xhc3P/dXNiX2RldmljZV9kZXNjcmlwdG9yCjEx/2JJbnRlcmZhY2VDbGFzc/91c2JfaW50ZXJmYWNlX2Rlc2NyaXB0b3IKMP9iTnVtRW5kcG9pbnRz/3VzYl9pbnRlcmZhY2VfZGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMi50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24KcmVsb2FkLXZt/25vCg==
2 |
3 |
--------------------------------------------------------------------------------
/payload/smsusb_null_ptr.obj:
--------------------------------------------------------------------------------
1 | REPRODUCE_KEY:
2 | MQoKNjI3Mf9pc1ZlbmRvcv9BTEwKNzY5/2lkUHJvZHVjdP9BTEwKMv9iRGV2aWNlQ2xhc3P/QUxMCjL/YkludGVyZmFjZUNsYXNz/0FMTAoyM/9iTnVtRW5kcG9pbnRz/1VTQl9JbnRlcmZhY2VfRGVzY3JpcHRvcgo1/2JOdW1JbnRlcmZhY2Vz/1VTQl9Db25maWd1cmF0aW9uX0Rlc2NyaXB0b3IKCmRlc2NyaXB0b3L/ZGVzYzMudHh0CmVtdWxhdG9y/2VudW1lcmF0aW9uCg==
3 |
--------------------------------------------------------------------------------
/payload/usbserial_bug.obj:
--------------------------------------------------------------------------------
1 | REPRODUCE_KEY:
2 | MQoKMjA5M/9pc1ZlbmRvcv9BTEwKMjU2/2lkUHJvZHVjdP9BTEwKMf9iRGV2aWNlQ2xhc3P/QUxMCjH/YkludGVyZmFjZUNsYXNz/0FMTAoyN/9iTnVtRW5kcG9pbnRz/1VTQl9JbnRlcmZhY2VfRGVzY3JpcHRvcgoxMDD/Yk51bUludGVyZmFjZXP/VVNCX0NvbmZpZ3VyYXRpb25fRGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMy50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24K
3 |
4 |
5 |
--------------------------------------------------------------------------------
/payload/usbserial_null_ptr.obj:
--------------------------------------------------------------------------------
1 | REPRODUCE_KEY:
2 | MQoKMTgwOP9pc1ZlbmRvcv9BTEwKMzI3Njn/aWRQcm9kdWN0/0FMTAoyNTX/YkRldmljZUNsYXNz/0FMTAoyNTX/YkludGVyZmFjZUNsYXNz/0FMTAo0/2JOdW1FbmRwb2ludHP/VVNCX0ludGVyZmFjZV9EZXNjcmlwdG9yCjX/Yk51bUludGVyZmFjZXP/VVNCX0NvbmZpZ3VyYXRpb25fRGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMy50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24K
3 |
4 |
--------------------------------------------------------------------------------
/payload/keyspan_null_ptr.obj:
--------------------------------------------------------------------------------
1 | REPRODUCE_KEY:
2 | MQoKMTc0Mf9pc1ZlbmRvcv9BTEwKMjY4/2lkUHJvZHVjdP9BTEwKMjU1/2JEZXZpY2VDbGFzc/9BTEwKMjU1/2JJbnRlcmZhY2VDbGFzc/9BTEwKMTj/Yk51bUVuZHBvaW50c/9VU0JfSW50ZXJmYWNlX0Rlc2NyaXB0b3IKMTAw/2JOdW1JbnRlcmZhY2Vz/1VTQl9Db25maWd1cmF0aW9uX0Rlc2NyaXB0b3IKCmRlc2NyaXB0b3L/ZGVzYzMudHh0CmVtdWxhdG9y/2VudW1lcmF0aW9uCg==
3 |
4 |
--------------------------------------------------------------------------------
/log/freebsd_monitor.sh:
--------------------------------------------------------------------------------
1 | cat vusbf_log_* | egrep 'Fatal trap|panic:|#1 |#2 |#3 |#4 |#5 |#6 |#7 |#8 ' | grep -v " savecore: reboot after panic:" | sort -u;
2 | echo "";
3 | printf 'TEST:\t' ;
4 | cat vusbf_log_* | grep -i 'TEST #' | wc -l ;
5 | printf 'Fatal trap:\t' ;
6 | cat vusbf_log_* | grep 'Fatal trap' | wc -l;
7 | printf 'Kernel Panics:\t' ;
8 | cat vusbf_log_* | grep -i 'panic' | wc -l
9 |
--------------------------------------------------------------------------------
/payload/mal_payload.obj:
--------------------------------------------------------------------------------
1 | REPRODUCE_KEY:
2 | MQoKMf9pc1ZlbmRvcv9BTEwKNTE2M/9pZFByb2R1Y3T/QUxMCjH/YkRldmljZUNsYXNz/0FMTAox/2JJbnRlcmZhY2VDbGFzc/9BTEwKCmRlc2NyaXB0b3L/ZGVzYzMudHh0CmVtdWxhdG9y/2VudW1lcmF0aW9uCg==
3 |
4 | REPRODUCE_KEY:
5 | MgoKMf9pc1ZlbmRvcv9BTEwKNTE2M/9pZFByb2R1Y3T/QUxMCjL/YkRldmljZUNsYXNz/0FMTAoy/2JJbnRlcmZhY2VDbGFzc/9BTEwKCmRlc2NyaXB0b3L/ZGVzYzMudHh0CmVtdWxhdG9y/2VudW1lcmF0aW9uCg==
6 |
7 |
--------------------------------------------------------------------------------
/log/linux_monitor.sh:
--------------------------------------------------------------------------------
1 | cat vusbf_log_* | egrep 'BUG|segfault|panic|recursive|Segmentation' | cut -c 16- | sort -u;
2 | echo "";
3 | printf 'TEST:\t' ;
4 | cat vusbf_log_* | grep -i 'TEST #' | wc -l ;
5 | printf 'Bugs:\t' ;
6 | cat vusbf_log_* | grep 'BUG' | wc -l;
7 | printf 'Kernel Panics:\t' ;
8 | cat vusbf_log_* | grep -i 'panic' | wc -l
9 | printf 'Reboot needed:\t' ;
10 | cat vusbf_log_* | grep -i 'recursive' | wc -l
11 | printf 'Segfault:\t'
12 | cat vusbf_log_* | grep -i 'seg' | wc -l
13 |
--------------------------------------------------------------------------------
/changelog:
--------------------------------------------------------------------------------
1 | Version 0.2:
2 |
3 | - code clean up
4 | - complete rewrite of testcase generation related code (generation works now on the fly, less memory usage)
5 | - add configuration file which includes all "tweakable" variables
6 | - deadlocks during long runtimes fixed
7 | - change payload format (base64 strings)
8 | - add tools for porting old payloads to new payload format
9 | - add pdb interface for certain processes
10 | - optimise performance
11 | - add execute payload without external QEMU process
12 | - add nightly windows support
13 |
14 | Version 0.1:
15 |
16 | - initial commit
--------------------------------------------------------------------------------
/payload/windows_bos.obj:
--------------------------------------------------------------------------------
1 | REPRODUCE_KEY:
2 | MQoKMTEzM/9pc1ZlbmRvcv9BTEwKNTA5NTn/aWRQcm9kdWN0/0FMTAoz/2JEZXZpY2VDbGFzc/9BTEwKM/9iSW50ZXJmYWNlQ2xhc3P/QUxMCgpkZXNjcmlwdG9y/2Rlc2MyLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgo=
3 |
4 | REPRODUCE_KEY:
5 | MgoKMTI3M/9pc1ZlbmRvcv9BTEwKNDgy/2lkUHJvZHVjdP9BTEwKNf9iRGV2aWNlQ2xhc3P/QUxMCjX/YkludGVyZmFjZUNsYXNz/0FMTAoKZGVzY3JpcHRvcv9kZXNjMi50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24K
6 |
7 | REPRODUCE_KEY:
8 | MwoKMzExMP9pc1ZlbmRvcv9BTEwKMjT/aWRQcm9kdWN0/0FMTAoxMf9iRGV2aWNlQ2xhc3P/QUxMCjEx/2JJbnRlcmZhY2VDbGFzc/9BTEwKCmRlc2NyaXB0b3L/ZGVzYzIudHh0CmVtdWxhdG9y/2VudW1lcmF0aW9uCg==
9 |
10 |
--------------------------------------------------------------------------------
/payload/panic_3.obj:
--------------------------------------------------------------------------------
1 | REPRODUCE_KEY:
2 | MQoKMTg5Mf9pc1ZlbmRvcv9BTEwKNDExN/9pZFByb2R1Y3T/QUxMCjI1Nf9iRGV2aWNlQ2xhc3P/QUxMCjI1Nf9iSW50ZXJmYWNlQ2xhc3P/QUxMCjH/Yk51bUVuZHBvaW50c/9VU0JfSW50ZXJmYWNlX0Rlc2NyaXB0b3IKMTD/Yk51bUludGVyZmFjZXP/VVNCX0NvbmZpZ3VyYXRpb25fRGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMy50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24K
3 |
4 | REPRODUCE_KEY:
5 | MgoKMTg5Mf9pc1ZlbmRvcv9BTEwKNDExN/9pZFByb2R1Y3T/QUxMCjI1Nf9iRGV2aWNlQ2xhc3P/QUxMCjI1Nf9iSW50ZXJmYWNlQ2xhc3P/QUxMCjH/Yk51bUVuZHBvaW50c/9VU0JfSW50ZXJmYWNlX0Rlc2NyaXB0b3IKMTD/Yk51bUludGVyZmFjZXP/VVNCX0NvbmZpZ3VyYXRpb25fRGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMy50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24K
6 |
7 |
--------------------------------------------------------------------------------
/configurations/centos6.config:
--------------------------------------------------------------------------------
1 | # vusbf qemu-config file
2 | #
3 |
4 |
5 | # QEMU BINARAY
6 | qemu_bin: /home/sergej/qemu/x86_64-softmmu/qemu-system-x86_64
7 |
8 | # KVM SUPPORT
9 | kvm: yes
10 |
11 | # MEMORY SIZE (MB)
12 | memory: 150
13 |
14 | # RAM FILE
15 | ram_file: /home/sergej/final/testkernel/ram.qcow2
16 |
17 | # OVERLAY FILE
18 | overlay_file: /home/sergej/final/testkernel/overlay.qcow2
19 |
20 | # OVERLAY FOLDER
21 | overlay_folder: /home/sergej/final/testkernel/
22 |
23 | # USB DEVICE TYPE
24 | device_type: nec-usb-xhci
25 |
26 | # EXTRA QEMU PARAMETER
27 | qemu_extra: ""
28 |
29 | # SNAPSHOT
30 | snapshot: replay
31 |
--------------------------------------------------------------------------------
/configurations/debian7.config:
--------------------------------------------------------------------------------
1 | # vusbf qemu-config file
2 | #
3 |
4 |
5 | # QEMU BINARAY
6 | qemu_bin: /home/sergej/qemu/x86_64-softmmu/qemu-system-x86_64
7 |
8 | # KVM SUPPORT
9 | kvm: yes
10 |
11 | # MEMORY SIZE (MB)
12 | memory: 150
13 |
14 | # RAM FILE
15 | ram_file: /home/sergej/workspace/Debian7/ram.qcow2
16 |
17 | # OVERLAY FILE
18 | overlay_file: /home/sergej/workspace/Debian7/overlay.qcow2
19 |
20 | # OVERLAY FOLDER
21 | overlay_folder: /home/sergej/workspace/Debian7
22 |
23 | # USB DEVICE TYPE
24 | device_type: nec-usb-xhci
25 |
26 | # EXTRA QEMU PARAMETER
27 | qemu_extra: ""
28 |
29 | # SNAPSHOT
30 | snapshot: replay
31 |
--------------------------------------------------------------------------------
/payload/i2400m_usb_bug.obj:
--------------------------------------------------------------------------------
1 | REPRODUCE_KEY:
2 | MQoKMzI5MDL/aXNWZW5kb3L/QUxMCjUxMjb/aWRQcm9kdWN0/0FMTAoy/2JEZXZpY2VDbGFzc/9BTEwKMv9iSW50ZXJmYWNlQ2xhc3P/QUxMCjEw/2JOdW1FbmRwb2ludHP/VVNCX0ludGVyZmFjZV9EZXNjcmlwdG9yCjEwMP9iTnVtSW50ZXJmYWNlc/9VU0JfQ29uZmlndXJhdGlvbl9EZXNjcmlwdG9yCgpkZXNjcmlwdG9y/2Rlc2MzLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgo=
3 |
4 | REPRODUCE_KEY:
5 | MgoKMzI5MDL/aXNWZW5kb3L/QUxMCjUxMjb/aWRQcm9kdWN0/0FMTAoy/2JEZXZpY2VDbGFzc/9BTEwKMv9iSW50ZXJmYWNlQ2xhc3P/QUxMCjEw/2JOdW1FbmRwb2ludHP/VVNCX0ludGVyZmFjZV9EZXNjcmlwdG9yCjEwMP9iTnVtSW50ZXJmYWNlc/9VU0JfQ29uZmlndXJhdGlvbl9EZXNjcmlwdG9yCgpkZXNjcmlwdG9y/2Rlc2MzLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgo=
6 |
7 |
--------------------------------------------------------------------------------
/configurations/ubuntu1404.config:
--------------------------------------------------------------------------------
1 | # vusbf qemu-config file
2 | #
3 |
4 |
5 | # QEMU BINARAY
6 | qemu_bin: /home/sergej/qemu/x86_64-softmmu/qemu-system-x86_64
7 |
8 | # KVM SUPPORT
9 | kvm: yes
10 |
11 | # MEMORY SIZE (MB)
12 | memory: 150
13 |
14 | # RAM FILE
15 | ram_file: /home/sergej/workspace/ubuntu14042/ram.qcow2
16 |
17 | # OVERLAY FILE
18 | overlay_file: /home/sergej/workspace/ubuntu14042/overlay.qcow2
19 |
20 | # OVERLAY FOLDER
21 | overlay_folder: /home/sergej/workspace/ubuntu14042/
22 |
23 | # USB DEVICE TYPE
24 | device_type: nec-usb-xhci
25 |
26 | # EXTRA QEMU PARAMETER
27 | qemu_extra: ""
28 |
29 | # SNAPSHOT
30 | snapshot: replay
31 |
--------------------------------------------------------------------------------
/configurations/freebsd10_1.config:
--------------------------------------------------------------------------------
1 | # vusbf qemu-config file
2 | #
3 |
4 |
5 | # QEMU BINARAY
6 | qemu_bin: /home/sergej/qemu/x86_64-softmmu/qemu-system-x86_64
7 |
8 | # KVM SUPPORT
9 | kvm: yes
10 |
11 | # MEMORY SIZE (MB)
12 | memory: 120
13 |
14 | # RAM FILE
15 | ram_file: /home/sergej/workspace/FreeBSD-10.1/ram.qcow2
16 |
17 | # OVERLAY FILE
18 | overlay_file: /home/sergej/workspace/FreeBSD-10.1/overlay.qcow2
19 |
20 | # OVERLAY FOLDER
21 | overlay_folder: /home/sergej/workspace/FreeBSD-10.1
22 |
23 | # USB DEVICE TYPE
24 | device_type: ich9-usb-ehci1
25 |
26 |
27 | # EXTRA QEMU PARAMETER
28 | qemu_extra: ""
29 |
30 | # SNAPSHOT
31 | snapshot: replay
32 |
--------------------------------------------------------------------------------
/configurations/ubuntu1404_updated.config:
--------------------------------------------------------------------------------
1 | # vusbf qemu-config file
2 | #
3 |
4 |
5 | # QEMU BINARAY
6 | qemu_bin: /home/sergej/qemu/x86_64-softmmu/qemu-system-x86_64
7 |
8 | # KVM SUPPORT
9 | kvm: yes
10 |
11 | # MEMORY SIZE (MB)
12 | memory: 400
13 |
14 | # RAM FILE
15 | ram_file: /home/sergej/workspace/ubuntu1404_2/ram.qcow2
16 |
17 | # OVERLAY FILE
18 | overlay_file: /home/sergej/workspace/ubuntu1404_2/overlay.qcow2
19 |
20 | # OVERLAY FOLDER
21 | overlay_folder: /home/sergej/workspace/ubuntu1404_2
22 |
23 | # USB DEVICE TYPE
24 | device_type: nec-usb-xhci
25 |
26 |
27 | # EXTRA QEMU PARAMETER
28 | qemu_extra: ""
29 |
30 | # SNAPSHOT
31 | snapshot: replay
32 |
--------------------------------------------------------------------------------
/qemu-2.1.1.patch:
--------------------------------------------------------------------------------
1 | --- redirect.c 2014-09-18 21:23:12.252000000 +0200
2 | +++ redirect_old.c 2014-09-18 21:26:28.624000000 +0200
3 | @@ -1218,7 +1218,7 @@
4 | usbredirparser_caps_set_cap(caps, usb_redir_cap_connect_device_version);
5 | usbredirparser_caps_set_cap(caps, usb_redir_cap_filter);
6 | usbredirparser_caps_set_cap(caps, usb_redir_cap_ep_info_max_packet_size);
7 | - //usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids);
8 | + usbredirparser_caps_set_cap(caps, usb_redir_cap_64bits_ids);
9 | usbredirparser_caps_set_cap(caps, usb_redir_cap_32bits_bulk_length);
10 | usbredirparser_caps_set_cap(caps, usb_redir_cap_bulk_receiving);
11 | #if USBREDIR_VERSION >= 0x000700
12 |
--------------------------------------------------------------------------------
/configurations/debian7_3.config:
--------------------------------------------------------------------------------
1 | # vusbf qemu-config file
2 | #
3 |
4 |
5 | # QEMU BINARAY
6 | qemu_bin: /home/sergej/Dokumente/vUSBf/Testing/qemu-2.2.0/qemu-2.2.0/x86_64-softmmu/qemu-system-x86_64
7 |
8 | # KVM SUPPORT
9 | kvm: yes
10 |
11 | # MEMORY SIZE (MB)
12 | memory: 150
13 |
14 | # RAM FILE
15 | ram_file: /home/sergej/Dokumente/vUSBf/18.02.15/kernel-3.15/ram.qcow2
16 |
17 | # OVERLAY FILE
18 | overlay_file: /home/sergej/Dokumente/vUSBf/18.02.15/kernel-3.15/overlay.qcow2
19 |
20 | # OVERLAY FOLDER
21 | overlay_folder: /home/sergej/Dokumente/vUSBf/18.02.15/kernel-3.15
22 |
23 | # USB DEVICE TYPE
24 | device_type: nec-usb-xhci
25 |
26 | # EXTRA QEMU PARAMETER
27 | qemu_extra: ""
28 |
29 | # SNAPSHOT
30 | snapshot: replay
31 |
32 |
--------------------------------------------------------------------------------
/configurations/debian7_2.config:
--------------------------------------------------------------------------------
1 | # vusbf qemu-config file
2 | #
3 |
4 |
5 | # QEMU BINARAY
6 | qemu_bin: /home/sergej/Dokumente/vUSBf/Testing/qemu-2.1.2/qemu-2.0.2/x86_64-softmmu/qemu-system-x86_64
7 |
8 | # KVM SUPPORT
9 | kvm: yes
10 |
11 | # MEMORY SIZE (MB)
12 | memory: 150
13 |
14 | # RAM FILE
15 | ram_file: /home/sergej/Dokumente/vUSBf/18.02.15/kernel-3.15_new_qemu/ram.qcow2
16 |
17 | # OVERLAY FILE
18 | overlay_file: /home/sergej/Dokumente/vUSBf/18.02.15/kernel-3.15_new_qemu/overlay.qcow2
19 |
20 | # OVERLAY FOLDER
21 | overlay_folder: /home/sergej/Dokumente/vUSBf/18.02.15/kernel-3.15_new_qemu
22 |
23 | # USB DEVICE TYPE
24 | device_type: nec-usb-xhci
25 |
26 | # EXTRA QEMU PARAMETER
27 | qemu_extra: ""
28 |
29 | # SNAPSHOT
30 | snapshot: replay
31 |
32 |
--------------------------------------------------------------------------------
/monitor/freebsd_monitor.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | from monitor import linux_monitor
11 |
12 | # TODO include me :-)
13 | class freebsd_monitor(linux_monitor):
14 | def __init__(self, qemu, filename):
15 | self.qemu = qemu
16 | super(linux_monitor, self).__init__(qemu, filename)
17 |
18 | def monitor(self, title):
19 | _tmp = super(linux_monitor, self).__monitor(title)
20 | if "Automatic reboot in " in _tmp[1]:
21 | self.qemu.repair_image()
22 | return _tmp[0]
--------------------------------------------------------------------------------
/tools/output_information.txt:
--------------------------------------------------------------------------------
1 | +---------------------------------------------------------+
2 | Test #1:
3 | FT: 5163 idProduct: ALL
4 | FT: 1 isVendor: ALL
5 | FT: 0 bDeviceClass: usb_device_descriptor
6 | FT: 0 bInterfaceClass: usb_interface_descriptor
7 | FT: 0 bNumEndpoints: usb_interface_descriptor
8 | {'descriptor': 'desc2.txt', 'emulator': 'enumeration', 'reload-vm': 'no'}
9 | KEY:
10 | MQoKNTE2M/9pZFByb2R1Y3T/QUxMCjH/aXNWZW5kb3L/QUxMCjD/YkRldmljZUNsYXNz/3VzYl9kZXZpY2VfZGVzY3JpcHRvcgow/2JJbnRlcmZhY2VDbGFzc/91c2JfaW50ZXJmYWNlX2Rlc2NyaXB0b3IKMP9iTnVtRW5kcG9pbnRz/3VzYl9pbnRlcmZhY2VfZGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMi50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24KcmVsb2FkLXZt/25vCg==
11 | +---------------------------------------------------------+
12 |
--------------------------------------------------------------------------------
/payload/windows_bos2.obj:
--------------------------------------------------------------------------------
1 | REPRODUCE_KEY:
2 | MQoKMTEzM/9pc1ZlbmRvcv9BTEwKNTA5NTn/aWRQcm9kdWN0/0FMTAoz/2JEZXZpY2VDbGFzc/9BTEwKM/9iSW50ZXJmYWNlQ2xhc3P/QUxMCgpkZXNjcmlwdG9y/2Rlc2MyLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgo=
3 |
4 | REPRODUCE_KEY:
5 | MQoKMTEzM/9pc1ZlbmRvcv9BTEwKNTA5NTn/aWRQcm9kdWN0/0FMTAoz/2JEZXZpY2VDbGFzc/9BTEwKM/9iSW50ZXJmYWNlQ2xhc3P/QUxMCgpkZXNjcmlwdG9y/2Rlc2MyLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgo=
6 |
7 | REPRODUCE_KEY:
8 | MQoKMTEzM/9pc1ZlbmRvcv9BTEwKNTA5NTn/aWRQcm9kdWN0/0FMTAoz/2JEZXZpY2VDbGFzc/9BTEwKM/9iSW50ZXJmYWNlQ2xhc3P/QUxMCgpkZXNjcmlwdG9y/2Rlc2MyLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgo=
9 |
10 | REPRODUCE_KEY:
11 | MQoKMTEzM/9pc1ZlbmRvcv9BTEwKNTA5NTn/aWRQcm9kdWN0/0FMTAoz/2JEZXZpY2VDbGFzc/9BTEwKM/9iSW50ZXJmYWNlQ2xhc3P/QUxMCgpkZXNjcmlwdG9y/2Rlc2MyLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgo=
12 |
13 |
--------------------------------------------------------------------------------
/test_generation/execution.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/tools/extract_class_ids.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | import sys
11 |
12 | start = "# List of known"
13 | end = "# List of Audio Class Terminal Types"
14 | start_flag = False
15 |
16 | vid = ""
17 | count = -1
18 |
19 | f = open(sys.argv[1])
20 |
21 | try:
22 | for line in f:
23 | if not start_flag:
24 | if line.startswith(start):
25 | start_flag = True
26 | else:
27 | if line.startswith(end):
28 | sys.exit(0)
29 | elif line.startswith("C "):
30 | print line.split(" ")[1]
31 | else:
32 | pass
33 | finally:
34 | f.close()
35 |
--------------------------------------------------------------------------------
/tools/gen_reproduce_key.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | import sys
11 | #sys.path.append(os.path.abspath('../'))
12 | #from test_generation.Testcase import Testcase, Fuzzing_instruction
13 |
14 | if len(sys.argv) != 2:
15 | print "Usage: python " + sys.argv[0] + " "
16 | sys.exit(1)
17 |
18 |
19 | filehandler = open(sys.argv[1], 'r')
20 | lock = True
21 | for line in filehandler:
22 | if not lock and not line.startswith("+--------------------------"):
23 | print line
24 |
25 | if line.startswith("+--------------------------"):
26 | if not lock:
27 | lock = True
28 | else:
29 | lock = False
30 |
--------------------------------------------------------------------------------
/emulator/enumeration_abortion.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | import os.path, sys
11 |
12 | from enumeration import enumeration
13 |
14 | lib_path = os.path.abspath('../')
15 | sys.path.append(lib_path)
16 |
17 |
18 | class abortion_enumeration(enumeration):
19 | max_number_of_packets = 13
20 |
21 | def __init__(self, fuzzer):
22 | super(abortion_enumeration, self).__init__(fuzzer)
23 | self.count = 0
24 |
25 | def _calc_response(self, data):
26 | if self.count == self.max_number_of_packets:
27 | return ""
28 | else:
29 | self.count += 1
30 | return super(abortion_enumeration, self)._calc_response(data)
31 |
32 |
--------------------------------------------------------------------------------
/monitor/monitor.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | import sys
11 | import os
12 | sys.path.append(os.path.abspath('../'))
13 | import config
14 |
15 |
16 | class monitor(object):
17 | def __init__(self, qemu, filename):
18 | if qemu == None:
19 | raise Exception("qemu null pointer")
20 | self.qemu = qemu
21 | if filename == None:
22 | raise Exception("filename null pointer")
23 | self.filename = filename
24 |
25 | def log_reload(self):
26 | if self.filename != "":
27 | f = open(self.filename, "a")
28 | f.write(config.MESSAGE_VM_RELOAD)
29 | f.close()
30 |
31 | def monitor(self, title):
32 | pass
33 |
--------------------------------------------------------------------------------
/payload/tests/test3.obj:
--------------------------------------------------------------------------------
1 | REPRODUCE_KEY:
2 | ODk5Njc5CgoxNTUy/2lkUHJvZHVjdP9BTEwKMTA1N/9pc1ZlbmRvcv9BTEwKODj/YkRldmljZUNsYXNz/3VzYl9kZXZpY2VfZGVzY3JpcHRvcgo4OP9iSW50ZXJmYWNlQ2xhc3P/dXNiX2ludGVyZmFjZV9kZXNjcmlwdG9yCjI1Nf9iTnVtRW5kcG9pbnRz/3VzYl9pbnRlcmZhY2VfZGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMi50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24KcmVsb2FkLXZt/25vCg==
3 | REPRODUCE_KEY:
4 | ODk5Njc5CgoxNTUy/2lkUHJvZHVjdP9BTEwKMTA1N/9pc1ZlbmRvcv9BTEwKODj/YkRldmljZUNsYXNz/3VzYl9kZXZpY2VfZGVzY3JpcHRvcgo4OP9iSW50ZXJmYWNlQ2xhc3P/dXNiX2ludGVyZmFjZV9kZXNjcmlwdG9yCjI1Nf9iTnVtRW5kcG9pbnRz/3VzYl9pbnRlcmZhY2VfZGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMi50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24KcmVsb2FkLXZt/25vCg==
5 | REPRODUCE_KEY:
6 | ODk5Njc5CgoxNTUy/2lkUHJvZHVjdP9BTEwKMTA1N/9pc1ZlbmRvcv9BTEwKODj/YkRldmljZUNsYXNz/3VzYl9kZXZpY2VfZGVzY3JpcHRvcgo4OP9iSW50ZXJmYWNlQ2xhc3P/dXNiX2ludGVyZmFjZV9kZXNjcmlwdG9yCjI1Nf9iTnVtRW5kcG9pbnRz/3VzYl9pbnRlcmZhY2VfZGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMi50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24KcmVsb2FkLXZt/25vCg==
7 |
--------------------------------------------------------------------------------
/report_desc_reader.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | from usbscapy import *
11 | import sys
12 |
13 | class report_desc_reader:
14 | def __init__(self, file):
15 | f = open(file)
16 | self.data = ""
17 | try:
18 | for line in f:
19 | self.data += line
20 | finally:
21 | f.close()
22 |
23 |
24 | def get_raw_data(self):
25 | data = self.data.replace("\n", "").replace(" ", "\\x")
26 | if data.endswith("\\x"):
27 | data = data[:-2]
28 | data = data.decode('string-escape')
29 | Raw(data).show()
30 | print len(data)
31 | return data
32 |
33 |
34 | print report_desc_reader(sys.argv[1]).get_raw_data()
35 |
--------------------------------------------------------------------------------
/payload/old_payload/mal_payload.obj:
--------------------------------------------------------------------------------
1 | (lp0
2 | (lp1
3 | I1
4 | a(lp2
5 | (lp3
6 | S'name'
7 | p4
8 | aS'enumeration'
9 | p5
10 | aa(lp6
11 | S'descriptor'
12 | p7
13 | aS'desc3.txt'
14 | p8
15 | aa(lp9
16 | S'reload'
17 | p10
18 | aI01
19 | aaa(ifuzz_configuration.test
20 | test_package
21 | p11
22 | (dp12
23 | S'raw_data'
24 | p13
25 | (I1
26 | I5163
27 | I1
28 | I1
29 | tp14
30 | sS'operation_list'
31 | p15
32 | (lp16
33 | (lp17
34 | I0
35 | aS'fuzz'
36 | p18
37 | aS'isVendor'
38 | p19
39 | aS'ALL'
40 | p20
41 | aa(lp21
42 | I0
43 | ag18
44 | aS'idProduct'
45 | p22
46 | aS'ALL'
47 | p23
48 | aa(lp24
49 | I1
50 | ag18
51 | aS'bDeviceClass'
52 | p25
53 | aS'ALL'
54 | p26
55 | aa(lp27
56 | I1
57 | ag18
58 | aS'bInterfaceClass'
59 | p28
60 | aS'ALL'
61 | p29
62 | aasS'name_list'
63 | p30
64 | (lp31
65 | S'all_vender_product_ids'
66 | p32
67 | aS'all_class_ids'
68 | p33
69 | asS'emulator'
70 | p34
71 | Nsbaa(lp35
72 | I2
73 | ag2
74 | a(ifuzz_configuration.test
75 | test_package
76 | p36
77 | (dp37
78 | g13
79 | (I1
80 | I5163
81 | I2
82 | I2
83 | tp38
84 | sg15
85 | g16
86 | sg30
87 | g31
88 | sg34
89 | Nsbaa.
--------------------------------------------------------------------------------
/emulator/emulator.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | import config
11 |
12 | class emulator(object):
13 |
14 | def __init__(self, fuzzer):
15 | if fuzzer == None:
16 | raise Exception("fuzzer object null pointer")
17 | # TODO type check fuzzer object
18 | self.fuzzer = fuzzer
19 |
20 | # fuzz data and return data as string
21 | def _fuzz_data(self, scapy_data):
22 | if scapy_data == None:
23 | return ""
24 | else:
25 | return self.fuzzer.post_fuzzing(scapy_data)
26 |
27 | def get_response(self, data):
28 | response = self._calc_response(data)
29 | response = self._fuzz_data(response)
30 | if config.PRINT_DEVICE_DESCRIPTORS:
31 | print config.DELIMITER
32 | response.show()
33 |
34 | return response
35 |
36 | def _calc_response(self, data):
37 | pass
38 |
--------------------------------------------------------------------------------
/payload/old_payload/smsusb_null_ptr.obj:
--------------------------------------------------------------------------------
1 | (lp0
2 | (lp1
3 | I10609166
4 | a(lp2
5 | (lp3
6 | S'name'
7 | p4
8 | aS'enumeration'
9 | p5
10 | aa(lp6
11 | S'descriptor'
12 | p7
13 | aS'desc3.txt'
14 | p8
15 | aa(lp9
16 | S'reload'
17 | p10
18 | aI01
19 | aaa(ifuzz_configuration.test
20 | test_package
21 | p11
22 | (dp12
23 | S'raw_data'
24 | p13
25 | (I6271
26 | I769
27 | I2
28 | I2
29 | I23
30 | I5
31 | tp14
32 | sS'operation_list'
33 | p15
34 | (lp16
35 | (lp17
36 | I0
37 | aS'fuzz'
38 | p18
39 | aS'isVendor'
40 | p19
41 | aS'ALL'
42 | p20
43 | aa(lp21
44 | I0
45 | ag18
46 | aS'idProduct'
47 | p22
48 | aS'ALL'
49 | p23
50 | aa(lp24
51 | I1
52 | ag18
53 | aS'bDeviceClass'
54 | p25
55 | aS'ALL'
56 | p26
57 | aa(lp27
58 | I1
59 | ag18
60 | aS'bInterfaceClass'
61 | p28
62 | aS'ALL'
63 | p29
64 | aa(lp30
65 | I2
66 | ag18
67 | aS'bNumEndpoints'
68 | p31
69 | aS'USB_Interface_Descriptor'
70 | p32
71 | aa(lp33
72 | I3
73 | ag18
74 | aS'bNumInterfaces'
75 | p34
76 | aS'USB_Configuration_Descriptor'
77 | p35
78 | aasS'name_list'
79 | p36
80 | (lp37
81 | S'all_vender_product_ids'
82 | p38
83 | aS'all_class_ids'
84 | p39
85 | aS'dev_desc_blength_invalid'
86 | p40
87 | aS'conf_bNum_Interface_invalid'
88 | p41
89 | asS'emulator'
90 | p42
91 | Nsbaa.
--------------------------------------------------------------------------------
/payload/old_payload/usbserial_bug.obj:
--------------------------------------------------------------------------------
1 | (lp0
2 | (lp1
3 | I6600289
4 | a(lp2
5 | (lp3
6 | S'name'
7 | p4
8 | aS'enumeration'
9 | p5
10 | aa(lp6
11 | S'descriptor'
12 | p7
13 | aS'desc3.txt'
14 | p8
15 | aa(lp9
16 | S'reload'
17 | p10
18 | aI01
19 | aaa(ifuzz_configuration.test
20 | test_package
21 | p11
22 | (dp12
23 | S'raw_data'
24 | p13
25 | (I2093
26 | I256
27 | I1
28 | I1
29 | I27
30 | I100
31 | tp14
32 | sS'operation_list'
33 | p15
34 | (lp16
35 | (lp17
36 | I0
37 | aS'fuzz'
38 | p18
39 | aS'isVendor'
40 | p19
41 | aS'ALL'
42 | p20
43 | aa(lp21
44 | I0
45 | ag18
46 | aS'idProduct'
47 | p22
48 | aS'ALL'
49 | p23
50 | aa(lp24
51 | I1
52 | ag18
53 | aS'bDeviceClass'
54 | p25
55 | aS'ALL'
56 | p26
57 | aa(lp27
58 | I1
59 | ag18
60 | aS'bInterfaceClass'
61 | p28
62 | aS'ALL'
63 | p29
64 | aa(lp30
65 | I2
66 | ag18
67 | aS'bNumEndpoints'
68 | p31
69 | aS'USB_Interface_Descriptor'
70 | p32
71 | aa(lp33
72 | I3
73 | ag18
74 | aS'bNumInterfaces'
75 | p34
76 | aS'USB_Configuration_Descriptor'
77 | p35
78 | aasS'name_list'
79 | p36
80 | (lp37
81 | S'all_vender_product_ids'
82 | p38
83 | aS'all_class_ids'
84 | p39
85 | aS'dev_desc_blength_invalid'
86 | p40
87 | aS'conf_bNum_Interface_invalid'
88 | p41
89 | asS'emulator'
90 | p42
91 | Nsbaa.
--------------------------------------------------------------------------------
/payload/old_payload/keyspan_null_ptr.obj:
--------------------------------------------------------------------------------
1 | (lp0
2 | (lp1
3 | I5773444
4 | a(lp2
5 | (lp3
6 | S'name'
7 | p4
8 | aS'enumeration'
9 | p5
10 | aa(lp6
11 | S'descriptor'
12 | p7
13 | aS'desc3.txt'
14 | p8
15 | aa(lp9
16 | S'reload'
17 | p10
18 | aI01
19 | aaa(ifuzz_configuration.test
20 | test_package
21 | p11
22 | (dp12
23 | S'raw_data'
24 | p13
25 | (I1741
26 | I268
27 | I255
28 | I255
29 | I18
30 | I100
31 | tp14
32 | sS'operation_list'
33 | p15
34 | (lp16
35 | (lp17
36 | I0
37 | aS'fuzz'
38 | p18
39 | aS'isVendor'
40 | p19
41 | aS'ALL'
42 | p20
43 | aa(lp21
44 | I0
45 | ag18
46 | aS'idProduct'
47 | p22
48 | aS'ALL'
49 | p23
50 | aa(lp24
51 | I1
52 | ag18
53 | aS'bDeviceClass'
54 | p25
55 | aS'ALL'
56 | p26
57 | aa(lp27
58 | I1
59 | ag18
60 | aS'bInterfaceClass'
61 | p28
62 | aS'ALL'
63 | p29
64 | aa(lp30
65 | I2
66 | ag18
67 | aS'bNumEndpoints'
68 | p31
69 | aS'USB_Interface_Descriptor'
70 | p32
71 | aa(lp33
72 | I3
73 | ag18
74 | aS'bNumInterfaces'
75 | p34
76 | aS'USB_Configuration_Descriptor'
77 | p35
78 | aasS'name_list'
79 | p36
80 | (lp37
81 | S'all_vender_product_ids'
82 | p38
83 | aS'all_class_ids'
84 | p39
85 | aS'dev_desc_blength_invalid'
86 | p40
87 | aS'conf_bNum_Interface_invalid'
88 | p41
89 | asS'emulator'
90 | p42
91 | Nsbaa.
--------------------------------------------------------------------------------
/payload/old_payload/panic_3.obj:
--------------------------------------------------------------------------------
1 | (lp0
2 | (lp1
3 | I6056107
4 | a(lp2
5 | (lp3
6 | S'name'
7 | p4
8 | aS'enumeration'
9 | p5
10 | aa(lp6
11 | S'descriptor'
12 | p7
13 | aS'desc3.txt'
14 | p8
15 | aa(lp9
16 | S'reload'
17 | p10
18 | aI01
19 | aaa(ifuzz_configuration.test
20 | test_package
21 | p11
22 | (dp12
23 | S'raw_data'
24 | p13
25 | (I1891
26 | I4117
27 | I255
28 | I255
29 | I1
30 | I10
31 | tp14
32 | sS'operation_list'
33 | p15
34 | (lp16
35 | (lp17
36 | I0
37 | aS'fuzz'
38 | p18
39 | aS'isVendor'
40 | p19
41 | aS'ALL'
42 | p20
43 | aa(lp21
44 | I0
45 | ag18
46 | aS'idProduct'
47 | p22
48 | aS'ALL'
49 | p23
50 | aa(lp24
51 | I1
52 | ag18
53 | aS'bDeviceClass'
54 | p25
55 | aS'ALL'
56 | p26
57 | aa(lp27
58 | I1
59 | ag18
60 | aS'bInterfaceClass'
61 | p28
62 | aS'ALL'
63 | p29
64 | aa(lp30
65 | I2
66 | ag18
67 | aS'bNumEndpoints'
68 | p31
69 | aS'USB_Interface_Descriptor'
70 | p32
71 | aa(lp33
72 | I3
73 | ag18
74 | aS'bNumInterfaces'
75 | p34
76 | aS'USB_Configuration_Descriptor'
77 | p35
78 | aasS'name_list'
79 | p36
80 | (lp37
81 | S'all_vender_product_ids'
82 | p38
83 | aS'all_class_ids'
84 | p39
85 | aS'dev_desc_blength_invalid'
86 | p40
87 | aS'conf_bNum_Interface_invalid'
88 | p41
89 | asS'emulator'
90 | p42
91 | Nsbaag1
92 | a.
--------------------------------------------------------------------------------
/payload/old_payload/usbserial_null_ptr.obj:
--------------------------------------------------------------------------------
1 | (lp0
2 | (lp1
3 | I5938371
4 | a(lp2
5 | (lp3
6 | S'name'
7 | p4
8 | aS'enumeration'
9 | p5
10 | aa(lp6
11 | S'descriptor'
12 | p7
13 | aS'desc3.txt'
14 | p8
15 | aa(lp9
16 | S'reload'
17 | p10
18 | aI01
19 | aaa(ifuzz_configuration.test
20 | test_package
21 | p11
22 | (dp12
23 | S'raw_data'
24 | p13
25 | (I1808
26 | I32769
27 | I255
28 | I255
29 | I4
30 | I5
31 | tp14
32 | sS'operation_list'
33 | p15
34 | (lp16
35 | (lp17
36 | I0
37 | aS'fuzz'
38 | p18
39 | aS'isVendor'
40 | p19
41 | aS'ALL'
42 | p20
43 | aa(lp21
44 | I0
45 | ag18
46 | aS'idProduct'
47 | p22
48 | aS'ALL'
49 | p23
50 | aa(lp24
51 | I1
52 | ag18
53 | aS'bDeviceClass'
54 | p25
55 | aS'ALL'
56 | p26
57 | aa(lp27
58 | I1
59 | ag18
60 | aS'bInterfaceClass'
61 | p28
62 | aS'ALL'
63 | p29
64 | aa(lp30
65 | I2
66 | ag18
67 | aS'bNumEndpoints'
68 | p31
69 | aS'USB_Interface_Descriptor'
70 | p32
71 | aa(lp33
72 | I3
73 | ag18
74 | aS'bNumInterfaces'
75 | p34
76 | aS'USB_Configuration_Descriptor'
77 | p35
78 | aasS'name_list'
79 | p36
80 | (lp37
81 | S'all_vender_product_ids'
82 | p38
83 | aS'all_class_ids'
84 | p39
85 | aS'dev_desc_blength_invalid'
86 | p40
87 | aS'conf_bNum_Interface_invalid'
88 | p41
89 | asS'emulator'
90 | p42
91 | Nsbaa.
--------------------------------------------------------------------------------
/payload/old_payload/i2400m_usb_bug.obj:
--------------------------------------------------------------------------------
1 | (lp0
2 | (lp1
3 | I11675604
4 | a(lp2
5 | (lp3
6 | S'name'
7 | p4
8 | aS'enumeration'
9 | p5
10 | aa(lp6
11 | S'descriptor'
12 | p7
13 | aS'desc3.txt'
14 | p8
15 | aa(lp9
16 | S'reload'
17 | p10
18 | aI01
19 | aaa(ifuzz_configuration.test
20 | test_package
21 | p11
22 | (dp12
23 | S'raw_data'
24 | p13
25 | (I32902
26 | I5126
27 | I2
28 | I2
29 | I10
30 | I100
31 | tp14
32 | sS'operation_list'
33 | p15
34 | (lp16
35 | (lp17
36 | I0
37 | aS'fuzz'
38 | p18
39 | aS'isVendor'
40 | p19
41 | aS'ALL'
42 | p20
43 | aa(lp21
44 | I0
45 | ag18
46 | aS'idProduct'
47 | p22
48 | aS'ALL'
49 | p23
50 | aa(lp24
51 | I1
52 | ag18
53 | aS'bDeviceClass'
54 | p25
55 | aS'ALL'
56 | p26
57 | aa(lp27
58 | I1
59 | ag18
60 | aS'bInterfaceClass'
61 | p28
62 | aS'ALL'
63 | p29
64 | aa(lp30
65 | I2
66 | ag18
67 | aS'bNumEndpoints'
68 | p31
69 | aS'USB_Interface_Descriptor'
70 | p32
71 | aa(lp33
72 | I3
73 | ag18
74 | aS'bNumInterfaces'
75 | p34
76 | aS'USB_Configuration_Descriptor'
77 | p35
78 | aasS'name_list'
79 | p36
80 | (lp37
81 | S'all_vender_product_ids'
82 | p38
83 | aS'all_class_ids'
84 | p39
85 | aS'dev_desc_blength_invalid'
86 | p40
87 | aS'conf_bNum_Interface_invalid'
88 | p41
89 | asS'emulator'
90 | p42
91 | Nsbaag1
92 | a.
--------------------------------------------------------------------------------
/tools/extract_vp_ids.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | import sys
11 |
12 | vid = ""
13 | count = -1
14 |
15 | f = open(sys.argv[1])
16 | try:
17 | for line in f:
18 | if line.startswith("# List of known"):
19 | sys.exit(1)
20 | elif line.startswith("#"):
21 | pass
22 | elif line == "\n":
23 | pass
24 | elif line == " \n":
25 | pass
26 | else:
27 | if line.startswith("\t"):
28 | print vid + "",
29 | print line.replace("\t", "").replace("\n", "").split(" ")[0]
30 | count += 1
31 | elif line.startswith("\t\t"):
32 | print "IF"
33 | print line
34 | elif not line.startswith(" "):
35 | if count == 0:
36 | print vid + " ????"
37 | vid = line.replace("\n", "").split(" ")[0]
38 | count = 0
39 | finally:
40 | f.close()
41 |
--------------------------------------------------------------------------------
/payload/udlfb.obj:
--------------------------------------------------------------------------------
1 | REPRODUCE_KEY:
2 | MQoKMjc2Mf9pc1ZlbmRvcv9BTEwKMTb/aWRQcm9kdWN0/0FMTAoyNTX/YkRldmljZUNsYXNz/0FMTAoyNTX/YkludGVyZmFjZUNsYXNz/0FMTAoyNP9iTnVtRW5kcG9pbnRz/1VTQl9JbnRlcmZhY2VfRGVzY3JpcHRvcgoyNf9iTnVtSW50ZXJmYWNlc/9VU0JfQ29uZmlndXJhdGlvbl9EZXNjcmlwdG9yCgpkZXNjcmlwdG9y/2Rlc2MzLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgo=
3 |
4 | REPRODUCE_KEY:
5 | MgoKMzY0Of9pc1ZlbmRvcv9BTEwKMTY5Nzb/aWRQcm9kdWN0/0FMTAox/2JEZXZpY2VDbGFzc/9BTEwKMf9iSW50ZXJmYWNlQ2xhc3P/QUxMCjE5/2JOdW1FbmRwb2ludHP/VVNCX0ludGVyZmFjZV9EZXNjcmlwdG9yCjX/Yk51bUludGVyZmFjZXP/VVNCX0NvbmZpZ3VyYXRpb25fRGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMy50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24K
6 |
7 | REPRODUCE_KEY:
8 | MwoKNjEyMf9pc1ZlbmRvcv9BTEwKMTcxNzD/aWRQcm9kdWN0/0FMTAoyNTX/YkRldmljZUNsYXNz/0FMTAoyNTX/YkludGVyZmFjZUNsYXNz/0FMTAoyOf9iTnVtRW5kcG9pbnRz/1VTQl9JbnRlcmZhY2VfRGVzY3JpcHRvcgo1/2JOdW1JbnRlcmZhY2Vz/1VTQl9Db25maWd1cmF0aW9uX0Rlc2NyaXB0b3IKCmRlc2NyaXB0b3L/ZGVzYzMudHh0CmVtdWxhdG9y/2VudW1lcmF0aW9uCg==
9 |
10 | REPRODUCE_KEY:
11 | MwoKNjEyMf9pc1ZlbmRvcv9BTEwKMTcxNzD/aWRQcm9kdWN0/0FMTAoyNTX/YkRldmljZUNsYXNz/0FMTAoyNTX/YkludGVyZmFjZUNsYXNz/0FMTAoyOf9iTnVtRW5kcG9pbnRz/1VTQl9JbnRlcmZhY2VfRGVzY3JpcHRvcgo1/2JOdW1JbnRlcmZhY2Vz/1VTQl9Db25maWd1cmF0aW9uX0Rlc2NyaXB0b3IKCmRlc2NyaXB0b3L/ZGVzYzMudHh0CmVtdWxhdG9y/2VudW1lcmF0aW9uCg==
12 |
13 |
--------------------------------------------------------------------------------
/test_generation/TestcaseLoader.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | from Testcase import Testcase
11 |
12 | class testcase_loader():
13 | def __init__(self, object_file):
14 | filehandler = open(object_file, 'r')
15 | self.payloads = []
16 | for line in filehandler:
17 | line = line.replace("+---------------------------------------------------------+", "")
18 | line = line.replace("REPRODUCE_KEY:", "")
19 | line = line.replace("\n", "")
20 | if line != "":
21 | _tmp = Testcase(0)
22 | _tmp.load_bas64_strings(line)
23 | self.payloads.append(_tmp)
24 |
25 | print "[*] " + str(len(self.payloads)) + " testcase in file \"" + object_file + "\""
26 |
27 | def get_number_of_elements(self):
28 | return len(self.payloads)
29 |
30 | def get_data_chunk(self, number_of_elements):
31 | if len(self.payloads) == 0:
32 | return None
33 | _tmp = self.payloads[:number_of_elements]
34 | self.payloads = self.payloads[number_of_elements:]
35 | return _tmp
--------------------------------------------------------------------------------
/payload/old_payload/windows_bod.obj:
--------------------------------------------------------------------------------
1 | (lp0
2 | (lp1
3 | I48814
4 | a(lp2
5 | (lp3
6 | S'name'
7 | p4
8 | aS'enumeration'
9 | p5
10 | aa(lp6
11 | S'descriptor'
12 | p7
13 | aS'desc2.txt'
14 | p8
15 | aa(lp9
16 | S'reload'
17 | p10
18 | aI01
19 | aaa(ifuzz_configuration.test
20 | test_package
21 | p11
22 | (dp12
23 | S'raw_data'
24 | p13
25 | (I1133
26 | I50959
27 | I3
28 | I3
29 | tp14
30 | sS'operation_list'
31 | p15
32 | (lp16
33 | (lp17
34 | I0
35 | aS'fuzz'
36 | p18
37 | aS'isVendor'
38 | p19
39 | aS'ALL'
40 | p20
41 | aa(lp21
42 | I0
43 | ag18
44 | aS'idProduct'
45 | p22
46 | aS'ALL'
47 | p23
48 | aa(lp24
49 | I1
50 | ag18
51 | aS'bDeviceClass'
52 | p25
53 | aS'ALL'
54 | p26
55 | aa(lp27
56 | I1
57 | ag18
58 | aS'bInterfaceClass'
59 | p28
60 | aS'ALL'
61 | p29
62 | aasS'name_list'
63 | p30
64 | (lp31
65 | S'all_vender_product_ids'
66 | p32
67 | aS'all_class_ids'
68 | p33
69 | asS'emulator'
70 | p34
71 | Nsbaa(lp35
72 | I93598
73 | ag2
74 | a(ifuzz_configuration.test
75 | test_package
76 | p36
77 | (dp37
78 | g13
79 | (I1273
80 | I482
81 | I5
82 | I5
83 | tp38
84 | sg15
85 | g16
86 | sg30
87 | g31
88 | sg34
89 | Nsbaa(lp39
90 | I206806
91 | ag2
92 | a(ifuzz_configuration.test
93 | test_package
94 | p40
95 | (dp41
96 | g13
97 | (I3110
98 | I24
99 | I11
100 | I11
101 | tp42
102 | sg15
103 | g16
104 | sg30
105 | g31
106 | sg34
107 | Nsbaa.
--------------------------------------------------------------------------------
/process/execute_object.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | from usbEmulator import usb_emulator
11 | from multi_process import multi_processing
12 | from test_generation.TestcaseLoader import testcase_loader
13 | import config
14 | import os
15 |
16 |
17 | def execute_object_process(object_file, host="", port=0, target=None):
18 | config.SERIAL_READ_RETRIES = config.SERIAL_READ_RETRIES_EXECUTE_MODE
19 | config.PROCESS_SLOW_START_THRESHOLD = config.PROCESS_SLOW_START_THRESHOLD_EXECUTE_MODE
20 | config.PROCESS_SLOW_START_THRESHOLD_FAIL_COUNTER = config.PROCESS_SLOW_START_THRESHOLD_FAIL_COUNTER_EXECUTE_MODE
21 | config.PROCESS_FAIL_REPAIR_COUNTER = config.PROCESS_FAIL_REPAIR_COUNTER_EXECUTE_MODE
22 |
23 | payloads = testcase_loader(object_file)
24 | if host == "" or port == 0:
25 | if target is not None:
26 | try:
27 | os.remove("log/vusbf_log_execute")
28 | except:
29 | pass
30 | multi_processing(1, target, "", "", "", "", "", False, None, payloads=payloads, file_name="execute")
31 | print "[*] Output:"
32 | print ""
33 | for line in open("log/vusbf_log_execute"):
34 | print line,
35 | else:
36 | for e in payloads.payloads:
37 | print e
38 | emu = usb_emulator([host, port], 0)
39 | emu.setup_payload(e)
40 | emu.execute()
--------------------------------------------------------------------------------
/process/only_payload.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | from usbEmulator import usb_emulator
11 | from test_generation.XMLParser import xml_parser
12 | import sys
13 | import os
14 | import time
15 | sys.path.append(os.path.abspath('../'))
16 | import config
17 | import random
18 |
19 | def only_payload_process(host, port, exec_name, exec_list, exec_path, testcase_path, test_path):
20 |
21 | path_prefix = "test_generation/"
22 | exec_path_value = path_prefix + "execution.xml"
23 | if exec_path != "":
24 | exec_path_value = exec_path
25 |
26 | testcase_path_value = path_prefix + "testcase.xml"
27 | if testcase_path != "":
28 | testcase_path_value = testcase_path
29 |
30 | test_path_value = path_prefix + "test.xml"
31 | if test_path != "":
32 | test_path_value = test_path
33 |
34 | xml_tree = xml_parser(test_path_value, testcase_path_value, exec_path_value)
35 | xml_tree.calc_tests(exec_name)
36 |
37 | print "[*] Number of tests: " + str(xml_tree.get_number_of_elements())
38 | xml_tree.print_tree()
39 | emu = usb_emulator([host, port], 0)
40 | payloads = xml_tree.get_data_chunk(config.NUMBER_OF_JOBS_PER_PROCESS_NM)
41 | random.shuffle(payloads)
42 | while payloads is not None:
43 | for e in payloads:
44 | print e
45 | emu.setup_payload(e)
46 | emu.execute()
47 | time.sleep(config.SLEEP_BETWEEN_TESTS)
48 | payloads = xml_tree.get_data_chunk(config.NUMBER_OF_JOBS_PER_PROCESS_NM)
49 | print "[*] Done..."
--------------------------------------------------------------------------------
/payload/old_payload/udlfb.obj:
--------------------------------------------------------------------------------
1 | (lp0
2 | (lp1
3 | I7624473
4 | a(lp2
5 | (lp3
6 | S'name'
7 | p4
8 | aS'enumeration'
9 | p5
10 | aa(lp6
11 | S'descriptor'
12 | p7
13 | aS'desc3.txt'
14 | p8
15 | aa(lp9
16 | S'reload'
17 | p10
18 | aI01
19 | aaa(ifuzz_configuration.test
20 | test_package
21 | p11
22 | (dp12
23 | S'raw_data'
24 | p13
25 | (I2761
26 | I16
27 | I255
28 | I255
29 | I24
30 | I25
31 | tp14
32 | sS'operation_list'
33 | p15
34 | (lp16
35 | (lp17
36 | I0
37 | aS'fuzz'
38 | p18
39 | aS'isVendor'
40 | p19
41 | aS'ALL'
42 | p20
43 | aa(lp21
44 | I0
45 | ag18
46 | aS'idProduct'
47 | p22
48 | aS'ALL'
49 | p23
50 | aa(lp24
51 | I1
52 | ag18
53 | aS'bDeviceClass'
54 | p25
55 | aS'ALL'
56 | p26
57 | aa(lp27
58 | I1
59 | ag18
60 | aS'bInterfaceClass'
61 | p28
62 | aS'ALL'
63 | p29
64 | aa(lp30
65 | I2
66 | ag18
67 | aS'bNumEndpoints'
68 | p31
69 | aS'USB_Interface_Descriptor'
70 | p32
71 | aa(lp33
72 | I3
73 | ag18
74 | aS'bNumInterfaces'
75 | p34
76 | aS'USB_Configuration_Descriptor'
77 | p35
78 | aasS'name_list'
79 | p36
80 | (lp37
81 | S'all_vender_product_ids'
82 | p38
83 | aS'all_class_ids'
84 | p39
85 | aS'dev_desc_blength_invalid'
86 | p40
87 | aS'conf_bNum_Interface_invalid'
88 | p41
89 | asS'emulator'
90 | p42
91 | Nsbaa(lp43
92 | I8853246
93 | ag2
94 | a(ifuzz_configuration.test
95 | test_package
96 | p44
97 | (dp45
98 | g13
99 | (I3649
100 | I16976
101 | I1
102 | I1
103 | I19
104 | I5
105 | tp46
106 | sg15
107 | g16
108 | sg36
109 | g37
110 | sg42
111 | Nsbaa(lp47
112 | I10557746
113 | ag2
114 | a(ifuzz_configuration.test
115 | test_package
116 | p48
117 | (dp49
118 | g13
119 | (I6121
120 | I17170
121 | I255
122 | I255
123 | I29
124 | I5
125 | tp50
126 | sg15
127 | g16
128 | sg36
129 | g37
130 | sg42
131 | Nsbaa.
--------------------------------------------------------------------------------
/payload/tests/test.obj:
--------------------------------------------------------------------------------
1 | REPRODUCE_KEY:
2 | Mzg3NDE5OQoKMzA0/2lkUHJvZHVjdP9BTEwKMTQxMP9pc1ZlbmRvcv9BTEwKNf9iRGV2aWNlQ2xhc3P/dXNiX2RldmljZV9kZXNjcmlwdG9yCjX/YkludGVyZmFjZUNsYXNz/3VzYl9pbnRlcmZhY2VfZGVzY3JpcHRvcgow/2JOdW1FbmRwb2ludHP/dXNiX2ludGVyZmFjZV9kZXNjcmlwdG9yCgpkZXNjcmlwdG9y/2Rlc2MyLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgpyZWxvYWQtdm3/bm8K
3 |
4 | REPRODUCE_KEY:
5 | Mzg3NDA5NAoKMzA0/2lkUHJvZHVjdP9BTEwKMTQxMP9pc1ZlbmRvcv9BTEwKMP9iRGV2aWNlQ2xhc3P/dXNiX2RldmljZV9kZXNjcmlwdG9yCjD/YkludGVyZmFjZUNsYXNz/3VzYl9pbnRlcmZhY2VfZGVzY3JpcHRvcgow/2JMZW5ndGj/dXNiX2VuZHBvaW50X2Rlc2NyaXB0b3IKCmRlc2NyaXB0b3L/ZGVzYzIudHh0CmVtdWxhdG9y/2VudW1lcmF0aW9uCnJlbG9hZC12bf9ubwo=
6 |
7 | REPRODUCE_KEY:
8 | Mzg3NDA0NgoKMzAz/2lkUHJvZHVjdP9BTEwKMTQxMP9pc1ZlbmRvcv9BTEwKMjU1/2JEZXZpY2VDbGFzc/91c2JfZGV2aWNlX2Rlc2NyaXB0b3IKMjU1/2JJbnRlcmZhY2VDbGFzc/91c2JfaW50ZXJmYWNlX2Rlc2NyaXB0b3IKMTM3/2JtQXR0cmlidXRlc/91c2JfY29uZmlndXJhdGlvbl9kZXNjcmlwdG9yCgpkZXNjcmlwdG9y/2Rlc2MyLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgpyZWxvYWQtdm3/bm8K
9 |
10 | REPRODUCE_KEY:
11 | Mzg3NDE5OQoKMzA0/2lkUHJvZHVjdP9BTEwKMTQxMP9pc1ZlbmRvcv9BTEwKNf9iRGV2aWNlQ2xhc3P/dXNiX2RldmljZV9kZXNjcmlwdG9yCjX/YkludGVyZmFjZUNsYXNz/3VzYl9pbnRlcmZhY2VfZGVzY3JpcHRvcgow/2JOdW1FbmRwb2ludHP/dXNiX2ludGVyZmFjZV9kZXNjcmlwdG9yCgpkZXNjcmlwdG9y/2Rlc2MyLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgpyZWxvYWQtdm3/bm8K
12 |
13 | REPRODUCE_KEY:
14 | Mzg3NDE5OQoKMzA0/2lkUHJvZHVjdP9BTEwKMTQxMP9pc1ZlbmRvcv9BTEwKNf9iRGV2aWNlQ2xhc3P/dXNiX2RldmljZV9kZXNjcmlwdG9yCjX/YkludGVyZmFjZUNsYXNz/3VzYl9pbnRlcmZhY2VfZGVzY3JpcHRvcgow/2JOdW1FbmRwb2ludHP/dXNiX2ludGVyZmFjZV9kZXNjcmlwdG9yCgpkZXNjcmlwdG9y/2Rlc2MyLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgpyZWxvYWQtdm3/bm8K
15 |
16 | REPRODUCE_KEY:
17 | Mzg3NDE5OQoKMzA0/2lkUHJvZHVjdP9BTEwKMTQxMP9pc1ZlbmRvcv9BTEwKNf9iRGV2aWNlQ2xhc3P/dXNiX2RldmljZV9kZXNjcmlwdG9yCjX/YkludGVyZmFjZUNsYXNz/3VzYl9pbnRlcmZhY2VfZGVzY3JpcHRvcgow/2JOdW1FbmRwb2ludHP/dXNiX2ludGVyZmFjZV9kZXNjcmlwdG9yCgpkZXNjcmlwdG9y/2Rlc2MyLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgpyZWxvYWQtdm3/bm8K
18 |
19 |
20 |
--------------------------------------------------------------------------------
/payload/tests/test2.obj:
--------------------------------------------------------------------------------
1 | REPRODUCE_KEY:
2 | MTkxOTUyCgo4NDUy/2lkUHJvZHVjdP9BTEwKMTAwOP9pc1ZlbmRvcv9BTEwKMv9iRGV2aWNlQ2xhc3P/dXNiX2RldmljZV9kZXNjcmlwdG9yCjL/YkludGVyZmFjZUNsYXNz/3VzYl9pbnRlcmZhY2VfZGVzY3JpcHRvcgoyNTX/YkludGVyZmFjZU51bWJlcv9VU0JfSW50ZXJmYWNlX0Rlc2NyaXB0b3IKCmRlc2NyaXB0b3L/ZGVzYzIudHh0CmVtdWxhdG9y/2VudW1lcmF0aW9uCnJlbG9hZC12bf9ubwo=
3 |
4 | REPRODUCE_KEY:
5 | MTkxOTg3Cgo4NDUy/2lkUHJvZHVjdP9BTEwKMTAwOP9pc1ZlbmRvcv9BTEwKM/9iRGV2aWNlQ2xhc3P/dXNiX2RldmljZV9kZXNjcmlwdG9yCjP/YkludGVyZmFjZUNsYXNz/3VzYl9pbnRlcmZhY2VfZGVzY3JpcHRvcgow/2JBbHRlcm5hdGVTZXR0aW5n/1VTQl9JbnRlcmZhY2VfRGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMi50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24KcmVsb2FkLXZt/25vCg==
6 |
7 | REPRODUCE_KEY:
8 | MTkxODMyCgo4NDUw/2lkUHJvZHVjdP9BTEwKMTAwOP9pc1ZlbmRvcv9BTEwKMjU1/2JEZXZpY2VDbGFzc/91c2JfZGV2aWNlX2Rlc2NyaXB0b3IKMjU1/2JJbnRlcmZhY2VDbGFzc/91c2JfaW50ZXJmYWNlX2Rlc2NyaXB0b3IKMzH/Yk51bUVuZHBvaW50c/91c2JfaW50ZXJmYWNlX2Rlc2NyaXB0b3IKCmRlc2NyaXB0b3L/ZGVzYzIudHh0CmVtdWxhdG9y/2VudW1lcmF0aW9uCnJlbG9hZC12bf9ubwo=
9 |
10 | REPRODUCE_KEY:
11 | MTkxOTUyCgo4NDUy/2lkUHJvZHVjdP9BTEwKMTAwOP9pc1ZlbmRvcv9BTEwKMv9iRGV2aWNlQ2xhc3P/dXNiX2RldmljZV9kZXNjcmlwdG9yCjL/YkludGVyZmFjZUNsYXNz/3VzYl9pbnRlcmZhY2VfZGVzY3JpcHRvcgoyNTX/YkludGVyZmFjZU51bWJlcv9VU0JfSW50ZXJmYWNlX0Rlc2NyaXB0b3IKCmRlc2NyaXB0b3L/ZGVzYzIudHh0CmVtdWxhdG9y/2VudW1lcmF0aW9uCnJlbG9hZC12bf9ubwo=
12 |
13 | REPRODUCE_KEY:
14 | MTkxOTg3Cgo4NDUy/2lkUHJvZHVjdP9BTEwKMTAwOP9pc1ZlbmRvcv9BTEwKM/9iRGV2aWNlQ2xhc3P/dXNiX2RldmljZV9kZXNjcmlwdG9yCjP/YkludGVyZmFjZUNsYXNz/3VzYl9pbnRlcmZhY2VfZGVzY3JpcHRvcgow/2JBbHRlcm5hdGVTZXR0aW5n/1VTQl9JbnRlcmZhY2VfRGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMi50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24KcmVsb2FkLXZt/25vCg==
15 |
16 | REPRODUCE_KEY:
17 | MTkxODMyCgo4NDUw/2lkUHJvZHVjdP9BTEwKMTAwOP9pc1ZlbmRvcv9BTEwKMjU1/2JEZXZpY2VDbGFzc/91c2JfZGV2aWNlX2Rlc2NyaXB0b3IKMjU1/2JJbnRlcmZhY2VDbGFzc/91c2JfaW50ZXJmYWNlX2Rlc2NyaXB0b3IKMzH/Yk51bUVuZHBvaW50c/91c2JfaW50ZXJmYWNlX2Rlc2NyaXB0b3IKCmRlc2NyaXB0b3L/ZGVzYzIudHh0CmVtdWxhdG9y/2VudW1lcmF0aW9uCnJlbG9hZC12bf9ubwo=
18 |
19 |
20 |
--------------------------------------------------------------------------------
/tools/port_old_payload.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | import sys
11 | import os
12 | sys.path.append(os.path.abspath('../'))
13 | from test_generation.Testcase import Testcase, Fuzzing_instruction
14 |
15 |
16 | class test_package:
17 | def __init__(self, raw_data, name_list, operation_list):
18 | if raw_data is None or name_list is None or operation_list is None:
19 | raise Exception("test error")
20 | self.raw_data = raw_data
21 | self.name_list = name_list
22 | self.operation_list = operation_list
23 | self.emulator = None
24 |
25 | def get_raw_data(self):
26 | return self.raw_data
27 |
28 | def get_name_list(self):
29 | return self.name_list
30 |
31 | def get_operation_list(self):
32 | return self.operation_list
33 |
34 | def print_data(self):
35 | print self.raw_data
36 | print "\t",
37 | print self.name_list
38 | print "\t",
39 | print self.operation_list
40 |
41 | import pickle
42 | if len(sys.argv) != 2:
43 | print "Usage: python " + sys.argv[0] + " "
44 | sys.exit(1)
45 |
46 | filehandler = open(sys.argv[1], 'r')
47 | data = pickle.load(filehandler)
48 | j = 0
49 | for e in data:
50 | j += 1
51 | _tmp = Testcase(j)
52 | i = 0
53 | for o in e[2].operation_list:
54 | _tmp.add_testcase(Fuzzing_instruction(e[2].raw_data[i], o[2], o[3]))
55 | # print str(o[2]) + " " + str(o[3]) + " " + str(e[2].raw_data[i])
56 | i += 1
57 | for o in e[1]:
58 | if o[0] == 'name':
59 | _tmp.add_option('emulator', o[1])
60 | if o[0] == 'descriptor':
61 | _tmp.add_option('descriptor', o[1])
62 | print "REPRODUCE_KEY:"
63 | print _tmp.encode_base64()
64 | print ""
--------------------------------------------------------------------------------
/dev_desc/desc4.txt:
--------------------------------------------------------------------------------
1 | Speed High
2 | Bus 001 Device 004: ID 05e3:0745 Genesys Logic, Inc.
3 | Device Descriptor:
4 | bLength 18
5 | bDescriptorType 1
6 | bcdUSB 2.00
7 | bDeviceClass 0 (Defined at Interface level)
8 | bDeviceSubClass 0
9 | bDeviceProtocol 0
10 | bMaxPacketSize0 64
11 | idVendor 0x05e3 Genesys Logic, Inc.
12 | idProduct 0x0745
13 | bcdDevice 9.02
14 | iManufacturer 0
15 | iProduct 1
16 | iSerial 2
17 | bNumConfigurations 1
18 | Configuration Descriptor:
19 | bLength 9
20 | bDescriptorType 2
21 | wTotalLength 32
22 | bNumInterfaces 1
23 | bConfigurationValue 1
24 | iConfiguration 0
25 | bmAttributes 0x80
26 | (Bus Powered)
27 | MaxPower 500mA
28 | Interface Descriptor:
29 | bLength 9
30 | bDescriptorType 4
31 | bInterfaceNumber 0
32 | bAlternateSetting 0
33 | bNumEndpoints 2
34 | bInterfaceClass 8 Mass Storage
35 | bInterfaceSubClass 6 SCSI
36 | bInterfaceProtocol 80 Bulk-Only
37 | iInterface 0
38 | Endpoint Descriptor:
39 | bLength 7
40 | bDescriptorType 5
41 | bEndpointAddress 0x81 EP 1 IN
42 | bmAttributes 2
43 | Transfer Type Bulk
44 | Synch Type None
45 | Usage Type Data
46 | wMaxPacketSize 0x0200 1x 512 bytes
47 | bInterval 0
48 | Endpoint Descriptor:
49 | bLength 7
50 | bDescriptorType 5
51 | bEndpointAddress 0x02 EP 2 OUT
52 | bmAttributes 2
53 | Transfer Type Bulk
54 | Synch Type None
55 | Usage Type Data
56 | wMaxPacketSize 0x0200 1x 512 bytes
57 | bInterval 0
58 |
59 |
--------------------------------------------------------------------------------
/payload/panic_1.obj:
--------------------------------------------------------------------------------
1 | REPRODUCE_KEY:
2 | MQoKMTE5M/9pc1ZlbmRvcv9BTEwKMTI4ODn/aWRQcm9kdWN0/0FMTAoy/2JEZXZpY2VDbGFzc/9BTEwKMv9iSW50ZXJmYWNlQ2xhc3P/QUxMCjE3/2JOdW1FbmRwb2ludHP/VVNCX0ludGVyZmFjZV9EZXNjcmlwdG9yCjX/Yk51bUludGVyZmFjZXP/VVNCX0NvbmZpZ3VyYXRpb25fRGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMy50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24K
3 |
4 | REPRODUCE_KEY:
5 | MgoKNDE4NP9pc1ZlbmRvcv9BTEwKNDExMv9pZFByb2R1Y3T/QUxMCjH/YkRldmljZUNsYXNz/0FMTAox/2JJbnRlcmZhY2VDbGFzc/9BTEwKMjj/Yk51bUVuZHBvaW50c/9VU0JfSW50ZXJmYWNlX0Rlc2NyaXB0b3IKNf9iTnVtSW50ZXJmYWNlc/9VU0JfQ29uZmlndXJhdGlvbl9EZXNjcmlwdG9yCgpkZXNjcmlwdG9y/2Rlc2MzLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgo=
6 |
7 | REPRODUCE_KEY:
8 | MwoKMTE5M/9pc1ZlbmRvcv9BTEwKMTI2MDL/aWRQcm9kdWN0/0FMTAoy/2JEZXZpY2VDbGFzc/9BTEwKMv9iSW50ZXJmYWNlQ2xhc3P/QUxMCjX/Yk51bUVuZHBvaW50c/9VU0JfSW50ZXJmYWNlX0Rlc2NyaXB0b3IKMTD/Yk51bUludGVyZmFjZXP/VVNCX0NvbmZpZ3VyYXRpb25fRGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMy50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24K
9 |
10 | REPRODUCE_KEY:
11 | NAoKNDQ1NP9pc1ZlbmRvcv9BTEwKNDM5ODH/aWRQcm9kdWN0/0FMTAox/2JEZXZpY2VDbGFzc/9BTEwKMf9iSW50ZXJmYWNlQ2xhc3P/QUxMCjE4/2JOdW1FbmRwb2ludHP/VVNCX0ludGVyZmFjZV9EZXNjcmlwdG9yCjEwMP9iTnVtSW50ZXJmYWNlc/9VU0JfQ29uZmlndXJhdGlvbl9EZXNjcmlwdG9yCgpkZXNjcmlwdG9y/2Rlc2MzLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgo=
12 |
13 | REPRODUCE_KEY:
14 | NQoKMTg5Mf9pc1ZlbmRvcv9BTEwKNDE0N/9pZFByb2R1Y3T/QUxMCjI1Nf9iRGV2aWNlQ2xhc3P/QUxMCjI1Nf9iSW50ZXJmYWNlQ2xhc3P/QUxMCjIw/2JOdW1FbmRwb2ludHP/VVNCX0ludGVyZmFjZV9EZXNjcmlwdG9yCjEwMP9iTnVtSW50ZXJmYWNlc/9VU0JfQ29uZmlndXJhdGlvbl9EZXNjcmlwdG9yCgpkZXNjcmlwdG9y/2Rlc2MzLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgo=
15 |
16 | REPRODUCE_KEY:
17 | NgoKMzI5NP9pc1ZlbmRvcv9BTEwKMjb/aWRQcm9kdWN0/0FMTAox/2JEZXZpY2VDbGFzc/9BTEwKMf9iSW50ZXJmYWNlQ2xhc3P/QUxMCjIz/2JOdW1FbmRwb2ludHP/VVNCX0ludGVyZmFjZV9EZXNjcmlwdG9yCjX/Yk51bUludGVyZmFjZXP/VVNCX0NvbmZpZ3VyYXRpb25fRGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMy50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24K
18 |
19 | REPRODUCE_KEY:
20 | NwoKNDYxMf9pc1ZlbmRvcv9BTEwKMzIw/2lkUHJvZHVjdP9BTEwKM/9iRGV2aWNlQ2xhc3P/QUxMCjP/YkludGVyZmFjZUNsYXNz/0FMTAoyNP9iTnVtRW5kcG9pbnRz/1VTQl9JbnRlcmZhY2VfRGVzY3JpcHRvcgoyNf9iTnVtSW50ZXJmYWNlc/9VU0JfQ29uZmlndXJhdGlvbl9EZXNjcmlwdG9yCgpkZXNjcmlwdG9y/2Rlc2MzLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgo=
21 |
--------------------------------------------------------------------------------
/clustering/protocol.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | from scapy.all import *
11 |
12 | vusbf_type_enum = {
13 | 0: "hello", # This packet initialize the communication
14 | 1: "task_request", # This packet can be sent from the client to request new testcases
15 | 2: "task_response", # Response from the server, which contains testcases as pickle obj
16 | 3: "sync_request", # Heartbeat request from the server. It's needed for synchronization of the number of finished tasks
17 | 4: "sync_response", # Response from the client. Contains the number of finished tasks
18 | 5: "check_request", # Request to check the given environment (VM , Overlay etc.)
19 | 6: "check_response", # Response for check_request
20 | 7: "close_connection"} # as the name says :-)
21 |
22 |
23 | # Protocol header
24 | class vusbf_proto_header(Packet):
25 | name = "VUSBF_ProtoHeader"
26 | fields_desc = [IntEnumField("Type", None, vusbf_type_enum),
27 | IntField("Length", None)
28 | ]
29 |
30 | # Protocol subheader (for task_request and task_response)
31 | class vusbf_task(Packet):
32 | name = "VUSBF_Task"
33 | fields_desc = [IntField("Number_of_tasks", None)]
34 |
35 | # Protocol subheader (for sync_request and sync_response)
36 | class vusbf_sync(Packet):
37 | name = "VUSBF_Sync"
38 | fields_desc = [IntField("Number_of_fin_tasks", None)]
39 |
40 | # Protocol subheader (no usage at the moment)
41 | class vusbf_get(Packet):
42 | name = "VUSBF_Get"
43 | fields_desc = [XByteField("Drop_data", None)]
44 |
45 | # Protocol subheader (for check_request)
46 | class vusbf_check_request(Packet):
47 | name = "VUSBF_Check"
48 | fields_desc = [LongField("MD5_VM", None),
49 | LongField("MD5_Overlay", None)
50 | ]
51 |
52 | # Protocol subheader (for check_response)
53 | class vusbf_check_response(Packet):
54 | name = "VUSBF_Check"
55 | fields_desc = [XByteField("Test_passed", None)]
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/dev_desc/desc1.txt:
--------------------------------------------------------------------------------
1 | Bus 007 Device 012: ID 046d:c218 Logitech, Inc. Logitech RumblePad 2 USB
2 | Device Descriptor:
3 | bLength 18
4 | bDescriptorType 1
5 | bcdUSB 1.10
6 | bDeviceClass 0 (Defined at Interface level)
7 | bDeviceSubClass 0
8 | bDeviceProtocol 0
9 | bMaxPacketSize0 8
10 | idVendor 0x046d Logitech, Inc.
11 | idProduct 0xc218 Logitech RumblePad 2 USB
12 | bcdDevice 1.00
13 | iManufacturer 1 Logitech
14 | iProduct 2 Logitech RumblePad 2 USB
15 | iSerial 0
16 | bNumConfigurations 1
17 | Configuration Descriptor:
18 | bLength 9
19 | bDescriptorType 2
20 | wTotalLength 41
21 | bNumInterfaces 1
22 | bConfigurationValue 1
23 | iConfiguration 0
24 | bmAttributes 0x80
25 | (Bus Powered)
26 | MaxPower 500mA
27 | Interface Descriptor:
28 | bLength 9
29 | bDescriptorType 4
30 | bInterfaceNumber 0
31 | bAlternateSetting 0
32 | bNumEndpoints 2
33 | bInterfaceClass 3 Human Interface Device
34 | bInterfaceSubClass 0 No Subclass
35 | bInterfaceProtocol 0 None
36 | iInterface 0
37 |
38 | -----
39 |
40 | Endpoint Descriptor:
41 | bLength 7
42 | bDescriptorType 5
43 | bEndpointAddress 0x81 EP 1 IN
44 | bmAttributes 3
45 | Transfer Type Interrupt
46 | Synch Type None
47 | Usage Type Data
48 | wMaxPacketSize 0x0008 1x 8 bytes
49 | bInterval 10
50 | Endpoint Descriptor:
51 | bLength 7
52 | bDescriptorType 5
53 | bEndpointAddress 0x01 EP 1 OUT
54 | bmAttributes 3
55 | Transfer Type Interrupt
56 | Synch Type None
57 | Usage Type Data
58 | wMaxPacketSize 0x0008 1x 8 bytes
59 | bInterval 10
60 |
61 |
--------------------------------------------------------------------------------
/emulator/hid.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | import os.path, sys
11 | from enumeration import enumeration
12 |
13 | sys.path.append(os.path.abspath('../'))
14 | from usbparser import *
15 | from descFuzzer import *
16 |
17 |
18 | class hid(enumeration):
19 | def __init__(self, fuzzer):
20 | super(hid, self).__init__(fuzzer)
21 |
22 |
23 | def __read_reports(self, reports_file):
24 | return "\x00\x00\x00\x00\x00\x00\x00\x00\x00"
25 |
26 | def __read_report_descriptor(self, report_descriptor_file):
27 | raw_data = ""
28 | f = open(report_descriptor_file)
29 | try:
30 | for line in f:
31 | raw_data += line
32 | finally:
33 | f.close()
34 |
35 | raw_data = raw_data.replace("\n", "").replace(" ", "\\x")
36 | if raw_data.endswith("\\x"):
37 | raw_data = data[:-2]
38 | raw_data = raw_data.decode('string-escape')
39 | Raw(raw_data).show()
40 | return raw_data
41 |
42 | def _calc_response(self, data):
43 |
44 | scapy_data = usbredir_parser(data).getScapyPacket()
45 | packet_length = 0
46 | extra_payload = None
47 |
48 | try:
49 | descriptor_request = scapy_data.value >> (8)
50 | descriptor_num = scapy_data.value % 256
51 | request = scapy_data.request
52 |
53 | # report request
54 | if request == 1:
55 | report = ""
56 | for i in range(scapy_data.length):
57 | report += chr(random.randint(0, 255))
58 | scapy_data.HLength = 10 + scapy_data.length
59 | return (scapy_data / extra_payload)
60 |
61 | # report_descriptor request
62 | elif descriptor_request == 0x22:
63 | scapy_data.status = 0
64 | scapy_data.HLength = 10 + scapy_data.length
65 | extra_payload = self.report_desc
66 | return (scapy_data / extra_payload)
67 |
68 | else:
69 | return super(hid, self)._calc_response(data)
70 | except:
71 | return super(hid, self)._calc_response(data)
72 |
--------------------------------------------------------------------------------
/test_generation/testcase.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/dev_desc/desc2.txt:
--------------------------------------------------------------------------------
1 | Speed Full
2 | Bus 001 Device 043: ID 1307:0165 Transcend Information, Inc. 2GB/4GB Flash Drive
3 | Device Descriptor:
4 | bLength 18
5 | bDescriptorType 1
6 | bcdUSB 2.00
7 | bDeviceClass 0 (Defined at Interface level)
8 | bDeviceSubClass 0
9 | bDeviceProtocol 0
10 | bMaxPacketSize0 64
11 | idVendor 0x3340 Transcend Information, Inc.
12 | idProduct 0x3457 2GB/4GB Flash Drive
13 | bcdDevice 1.00
14 | iManufacturer 1
15 | iProduct 2
16 | iSerial 3
17 | bNumConfigurations 1
18 | Configuration Descriptor:
19 | bLength 9
20 | bDescriptorType 2
21 | wTotalLength 39
22 | bNumInterfaces 1
23 | bConfigurationValue 1
24 | iConfiguration 0
25 | bmAttributes 0x80
26 | (Bus Powered)
27 | MaxPower 98mA
28 | Interface Descriptor:
29 | bLength 9
30 | bDescriptorType 4
31 | bInterfaceNumber 0
32 | bAlternateSetting 0
33 | bNumEndpoints 3
34 | bInterfaceClass 0 Mass Storage
35 | bInterfaceSubClass 0 SCSI
36 | bInterfaceProtocol 0 Bulk-Only
37 | iInterface 0
38 | Endpoint Descriptor:
39 | bLength 7
40 | bDescriptorType 5
41 | bEndpointAddress 0x81 EP 1 IN
42 | bmAttributes 3
43 | Transfer Type Interrupt
44 | Synch Type None
45 | Usage Type Data
46 | wMaxPacketSize 0x0404 1x 4 bytes
47 | bInterval 12
48 | Endpoint Descriptor:
49 | bLength 7
50 | bDescriptorType 5
51 | bEndpointAddress 0x01 EP 1 IN
52 | bmAttributes 2
53 | Transfer Type Interrupt
54 | Synch Type None
55 | Usage Type Data
56 | wMaxPacketSize 0x0004 1x 4 bytes
57 | bInterval 12
58 | Endpoint Descriptor:
59 | bLength 7
60 | bDescriptorType 5
61 | bEndpointAddress 0x82 EP 1 IN
62 | bmAttributes 1
63 | Transfer Type Interrupt
64 | Synch Type None
65 | Usage Type Data
66 | wMaxPacketSize 0x0004 1x 4 bytes
67 | bInterval 12
68 |
69 |
--------------------------------------------------------------------------------
/dev_desc/desc.txt:
--------------------------------------------------------------------------------
1 | Speed High
2 | Bus 001 Device 043: ID 1307:0165 Transcend Information, Inc. 2GB/4GB Flash Drive
3 | Device Descriptor:
4 | bLength 18
5 | bDescriptorType 1
6 | bcdUSB 2.00
7 | bDeviceClass 0 (Defined at Interface level)
8 | bDeviceSubClass 0
9 | bDeviceProtocol 0
10 | bMaxPacketSize0 64
11 | idVendor 0x3340 Transcend Information, Inc.
12 | idProduct 0x3457 2GB/4GB Flash Drive
13 | bcdDevice 1.00
14 | iManufacturer 1
15 | iProduct 2
16 | iSerial 3
17 | bNumConfigurations 1
18 | Configuration Descriptor:
19 | bLength 9
20 | bDescriptorType 2
21 | wTotalLength 39
22 | bNumInterfaces 1
23 | bConfigurationValue 1
24 | iConfiguration 0
25 | bmAttributes 0x80
26 | (Bus Powered)
27 | MaxPower 98mA
28 | Interface Descriptor:
29 | bLength 9
30 | bDescriptorType 4
31 | bInterfaceNumber 0
32 | bAlternateSetting 0
33 | bNumEndpoints 3
34 | bInterfaceClass 0 Mass Storage
35 | bInterfaceSubClass 0 SCSI
36 | bInterfaceProtocol 0 Bulk-Only
37 | iInterface 0
38 | Endpoint Descriptor:
39 | bLength 7
40 | bDescriptorType 5
41 | bEndpointAddress 0x01 EP 1 OUT
42 | bmAttributes 2
43 | Transfer Type Bulk
44 | Synch Type None
45 | Usage Type Data
46 | wMaxPacketSize 0x0200 1x 512 bytes
47 | bInterval 1
48 | Endpoint Descriptor:
49 | bLength 7
50 | bDescriptorType 5
51 | bEndpointAddress 0x82 EP 2 IN
52 | bmAttributes 3
53 | Transfer Type Bulk
54 | Synch Type None
55 | Usage Type Data
56 | wMaxPacketSize 0x0200 1x 512 bytes
57 | bInterval 1
58 | Endpoint Descriptor:
59 | bLength 7
60 | bDescriptorType 5
61 | bEndpointAddress 0x83 EP 3 IN
62 | bmAttributes 0
63 | Transfer Type Interrupt
64 | Synch Type None
65 | Usage Type Data
66 | wMaxPacketSize 0x0040 1x 64 bytes
67 | bInterval 8
68 |
69 |
--------------------------------------------------------------------------------
/dev_desc/desc6.txt:
--------------------------------------------------------------------------------
1 | Bus 007 Device 012: ID 046d:c218 Logitech, Inc. Logitech RumblePad 2 USB
2 | Device Descriptor:
3 | bLength 18
4 | bDescriptorType 1
5 | bcdUSB 1.10
6 | bDeviceClass 0 (Defined at Interface level)
7 | bDeviceSubClass 0
8 | bDeviceProtocol 0
9 | bMaxPacketSize0 8
10 | idVendor 0x046d Logitech, Inc.
11 | idProduct 0xc218 Logitech RumblePad 2 USB
12 | bcdDevice 2.00
13 | iManufacturer 1 Logitech
14 | iProduct 2 Logitech RumblePad 2 USB
15 | iSerial 0
16 | bNumConfigurations 1
17 | Configuration Descriptor:
18 | bLength 9
19 | bDescriptorType 2
20 | wTotalLength 41
21 | bNumInterfaces 1
22 | bConfigurationValue 1
23 | iConfiguration 0
24 | bmAttributes 0x80
25 | (Bus Powered)
26 | MaxPower 500mA
27 | Interface Descriptor:
28 | bLength 9
29 | bDescriptorType 4
30 | bInterfaceNumber 0
31 | bAlternateSetting 0
32 | bNumEndpoints 2
33 | bInterfaceClass 3 Human Interface Device
34 | bInterfaceSubClass 0 No Subclass
35 | bInterfaceProtocol 0 None
36 | iInterface 0
37 | HID Device Descriptor:
38 | bLength 9
39 | bDescriptorType 33
40 | bcdHID 1.10
41 | bCountryCode 0 Not supported
42 | bNumDescriptors 1
43 | bDescriptorType 34 Report
44 | wDescriptorLength 122
45 |
46 | Report Descriptors:
47 | ** UNAVAILABLE **
48 | Endpoint Descriptor:
49 | bLength 7
50 | bDescriptorType 5
51 | bEndpointAddress 0x81 EP 1 IN
52 | bmAttributes 3
53 | Transfer Type Interrupt
54 | Synch Type None
55 | Usage Type Data
56 | wMaxPacketSize 0x0008 1x 8 bytes
57 | bInterval 10
58 | Endpoint Descriptor:
59 | bLength 7
60 | bDescriptorType 5
61 | bEndpointAddress 0x01 EP 1 OUT
62 | bmAttributes 3
63 | Transfer Type Interrupt
64 | Synch Type None
65 | Usage Type Data
66 | wMaxPacketSize 0x0008 1x 8 bytes
67 | bInterval 10
68 |
69 |
--------------------------------------------------------------------------------
/dev_desc/desc5.txt:
--------------------------------------------------------------------------------
1 | Speed High
2 | Bus 001 Device 047: ID 17e9:02ee DisplayLink
3 | Device Descriptor:
4 | bLength 18
5 | bDescriptorType 1
6 | bcdUSB 2.00
7 | bDeviceClass 0 (Defined at Interface level)
8 | bDeviceSubClass 0
9 | bDeviceProtocol 0
10 | bMaxPacketSize0 8
11 | idVendor 0x17e9 DisplayLink
12 | idProduct 0x02ee
13 | bcdDevice 1.03
14 | iManufacturer 1
15 | iProduct 2
16 | iSerial 3
17 | bNumConfigurations 1
18 | Configuration Descriptor:
19 | bLength 9
20 | bDescriptorType 2
21 | wTotalLength 66
22 | bNumInterfaces 1
23 | bConfigurationValue 1
24 | iConfiguration 0
25 | bmAttributes 0x80
26 | (Bus Powered)
27 | MaxPower 500mA
28 | Interface Descriptor:
29 | bLength 9
30 | bDescriptorType 4
31 | bInterfaceNumber 0
32 | bAlternateSetting 0
33 | bNumEndpoints 3
34 | bInterfaceClass 255 Vendor Specific Class
35 | bInterfaceSubClass 0
36 | bInterfaceProtocol 0
37 | iInterface 0
38 | ** UNRECOGNIZED: 1b 5f 01 00 19 05 00 01 03 00 04 04 01 00 03 d0 00 02 04 00 bd 1f 00 01 04 01 02
39 | Endpoint Descriptor:
40 | bLength 7
41 | bDescriptorType 5
42 | bEndpointAddress 0x02 EP 1 OUT
43 | bmAttributes 3
44 | Transfer Type Bulk
45 | Synch Type None
46 | Usage Type Data
47 | wMaxPacketSize 0x0800 1x 512 bytes
48 | bInterval 5
49 | Endpoint Descriptor:
50 | bLength 7
51 | bDescriptorType 5
52 | bEndpointAddress 0x82 EP 2 IN
53 | bmAttributes 0
54 | Transfer Type Interrupt
55 | Synch Type None
56 | Usage Type Data
57 | wMaxPacketSize 0x0800 1x 8 bytes
58 | bInterval 4
59 | Endpoint Descriptor:
60 | bLength 7
61 | bDescriptorType 5
62 | bEndpointAddress 0x0a EP 10 OUT
63 | bmAttributes 2
64 | Transfer Type Bulk
65 | Synch Type None
66 | Usage Type Data
67 | wMaxPacketSize 0x1000 1x 512 bytes
68 | bInterval 2
69 |
70 |
71 |
--------------------------------------------------------------------------------
/payload/old_payload/panic_1.obj:
--------------------------------------------------------------------------------
1 | (lp0
2 | (lp1
3 | I2715386
4 | a(lp2
5 | (lp3
6 | S'name'
7 | p4
8 | aS'enumeration'
9 | p5
10 | aa(lp6
11 | S'descriptor'
12 | p7
13 | aS'desc3.txt'
14 | p8
15 | aa(lp9
16 | S'reload'
17 | p10
18 | aI01
19 | aaa(ifuzz_configuration.test
20 | test_package
21 | p11
22 | (dp12
23 | S'raw_data'
24 | p13
25 | (I1193
26 | I12889
27 | I2
28 | I2
29 | I17
30 | I5
31 | tp14
32 | sS'operation_list'
33 | p15
34 | (lp16
35 | (lp17
36 | I0
37 | aS'fuzz'
38 | p18
39 | aS'isVendor'
40 | p19
41 | aS'ALL'
42 | p20
43 | aa(lp21
44 | I0
45 | ag18
46 | aS'idProduct'
47 | p22
48 | aS'ALL'
49 | p23
50 | aa(lp24
51 | I1
52 | ag18
53 | aS'bDeviceClass'
54 | p25
55 | aS'ALL'
56 | p26
57 | aa(lp27
58 | I1
59 | ag18
60 | aS'bInterfaceClass'
61 | p28
62 | aS'ALL'
63 | p29
64 | aa(lp30
65 | I2
66 | ag18
67 | aS'bNumEndpoints'
68 | p31
69 | aS'USB_Interface_Descriptor'
70 | p32
71 | aa(lp33
72 | I3
73 | ag18
74 | aS'bNumInterfaces'
75 | p34
76 | aS'USB_Configuration_Descriptor'
77 | p35
78 | aasS'name_list'
79 | p36
80 | (lp37
81 | S'all_vender_product_ids'
82 | p38
83 | aS'all_class_ids'
84 | p39
85 | aS'dev_desc_blength_invalid'
86 | p40
87 | aS'conf_bNum_Interface_invalid'
88 | p41
89 | asS'emulator'
90 | p42
91 | Nsbaa(lp43
92 | I9287541
93 | ag2
94 | a(ifuzz_configuration.test
95 | test_package
96 | p44
97 | (dp45
98 | g13
99 | (I4184
100 | I4112
101 | I1
102 | I1
103 | I28
104 | I5
105 | tp46
106 | sg15
107 | g16
108 | sg36
109 | g37
110 | sg42
111 | Nsbaa(lp47
112 | I2626827
113 | ag2
114 | a(ifuzz_configuration.test
115 | test_package
116 | p48
117 | (dp49
118 | g13
119 | (I1193
120 | I12602
121 | I2
122 | I2
123 | I5
124 | I10
125 | tp50
126 | sg15
127 | g16
128 | sg36
129 | g37
130 | sg42
131 | Nsbaa(lp51
132 | I9511744
133 | ag2
134 | a(ifuzz_configuration.test
135 | test_package
136 | p52
137 | (dp53
138 | g13
139 | (I4454
140 | I43981
141 | I1
142 | I1
143 | I18
144 | I100
145 | tp54
146 | sg15
147 | g16
148 | sg36
149 | g37
150 | sg42
151 | Nsbaa(lp55
152 | I6059954
153 | ag2
154 | a(ifuzz_configuration.test
155 | test_package
156 | p56
157 | (dp57
158 | g13
159 | (I1891
160 | I4147
161 | I255
162 | I255
163 | I20
164 | I100
165 | tp58
166 | sg15
167 | g16
168 | sg36
169 | g37
170 | sg42
171 | Nsbaa(lp59
172 | I8455766
173 | ag2
174 | a(ifuzz_configuration.test
175 | test_package
176 | p60
177 | (dp61
178 | g13
179 | (I3294
180 | I26
181 | I1
182 | I1
183 | I23
184 | I5
185 | tp62
186 | sg15
187 | g16
188 | sg36
189 | g37
190 | sg42
191 | Nsbaa(lp63
192 | I9581823
193 | ag2
194 | a(ifuzz_configuration.test
195 | test_package
196 | p64
197 | (dp65
198 | g13
199 | (I4611
200 | I320
201 | I3
202 | I3
203 | I24
204 | I25
205 | tp66
206 | sg15
207 | g16
208 | sg36
209 | g37
210 | sg42
211 | Nsbaa.
--------------------------------------------------------------------------------
/help.txt:
--------------------------------------------------------------------------------
1 | Usage: vusbf.py [Running Type] [Fuzzing Type] [Target Type]
2 |
3 | Target Specification:
4 | -o : name of a target configuration file (stored at ./configurations/)
5 |
6 | Fuzzing Specification:
7 | -e : name of an execution name (stored at execution.xml) which should be executed
8 |
9 | (default xml files are stored in ./fuzz_configuration)
10 | -ef : path of an alternativ execution-xml file
11 | -tf : path of an alternativ test-xml file
12 | -cf : path of an alternativ testcase-xml file
13 |
14 | (the following options could be used multiple times. However it's not possible to used them with clustering options)
15 | -n : execute a specific test (could be useful for reproducing an error)
16 | -nr : same as described above, but specifices a range of numbers [NOT IMPLEMENTED YET :-)]
17 |
18 | Running Specification:
19 |
20 | -eon sending specified payload (NETWORK)
21 | -eo sending specified payload
22 | -v1 verbose level 1 (output device descriptor & control data)
23 | -v2 verbose level 2 (raw redir data)
24 | -sp single core mode (but sending data to an external process)
25 |
26 | (automatic mode)
27 | -r single core mode
28 | -rm multiprocessing mode
29 |
30 | (clustering mode)
31 | (Warning: These features are experimental and could cause deadlocks!)
32 | -s starting a test-distributor-server
33 | -sc starting a hybrid client-server [NOT IMPLEMENTED YET :-)]
34 | -c starting a client
35 | -p specify number of processes
36 |
37 | Extras:
38 | -l list all available payloads
39 | -L list all supported emulators
40 | -h print help message
41 | -sh shuffle job list
42 | -rl reload mode (disable burst mode)
43 |
44 | Example:
45 |
46 | LIST ALL AVAILABLE PAYLOADS:
47 | python vusbf.py -l
48 | SEND PAYLOAD TO EXTERNAL QEMU INSTANCE:
49 | python vusbf.py -eon 127.0.0.1 1235 panic_1.obj
50 | EXECUTE PAYLOAD:
51 | python vusbf.py -eo panic_1.obj -o ubuntu1404.config -v1
52 | RUN SINGLECORE MODE (EXTERN VM):
53 | python vusbf.py -sp 127.0.0.1 1235 -e ex2
54 | RUN SINGLECORE MODE:
55 | python vusbf.py -r -e ex1 -o ubuntu1404.config -rl
56 | RUN MULTICORE MODE (20 PROCESSES):
57 | python vusbf.py -rm -p 20 -e ex1 -o ubuntu1404.config -rl
58 |
59 |
--------------------------------------------------------------------------------
/dev_desc/desc3.txt:
--------------------------------------------------------------------------------
1 | Speed Full
2 | Bus 001 Device 043: ID 1307:0165 Transcend Information, Inc. 2GB/4GB Flash Drive
3 | Device Descriptor:
4 | bLength 18
5 | bDescriptorType 1
6 | bcdUSB 2.00
7 | bDeviceClass 0 (Defined at Interface level)
8 | bDeviceSubClass 0
9 | bDeviceProtocol 0
10 | bMaxPacketSize0 64
11 | idVendor 0x3340 Transcend Information, Inc.
12 | idProduct 0x3457 2GB/4GB Flash Drive
13 | bcdDevice 1.00
14 | iManufacturer 1
15 | iProduct 2
16 | iSerial 3
17 | bNumConfigurations 1
18 | Configuration Descriptor:
19 | bLength 9
20 | bDescriptorType 2
21 | wTotalLength 48
22 | bNumInterfaces 1
23 | bConfigurationValue 1
24 | iConfiguration 0
25 | bmAttributes 0x80
26 | (Bus Powered)
27 | MaxPower 98mA
28 | Interface Descriptor:
29 | bLength 9
30 | bDescriptorType 4
31 | bInterfaceNumber 0
32 | bAlternateSetting 0
33 | bNumEndpoints 3
34 | bInterfaceClass 0 Mass Storage
35 | bInterfaceSubClass 0 SCSI
36 | bInterfaceProtocol 0 Bulk-Only
37 | iInterface 0
38 | iInterface 0
39 | HID Device Descriptor:
40 | bLength 9
41 | bDescriptorType 33
42 | bcdHID 1.10
43 | bCountryCode 0 Not supported
44 | bNumDescriptors 1
45 | bDescriptorType 34 Report
46 | wDescriptorLength 119
47 | Report Descriptors:
48 | ** UNAVAILABLE **
49 |
50 | Endpoint Descriptor:
51 | bLength 7
52 | bDescriptorType 5
53 | bEndpointAddress 0x0A EP 1 OUT
54 | bmAttributes 2
55 | Transfer Type Bulk
56 | Synch Type None
57 | Usage Type Data
58 | wMaxPacketSize 0x0040 1x 512 bytes
59 | bInterval 1
60 | Endpoint Descriptor:
61 | bLength 7
62 | bDescriptorType 5
63 | bEndpointAddress 0x8C EP 2 IN
64 | bmAttributes 2
65 | Transfer Type Bulk
66 | Synch Type None
67 | Usage Type Data
68 | wMaxPacketSize 0x0040 1x 512 bytes
69 | bInterval 1
70 | Endpoint Descriptor:
71 | bLength 7
72 | bDescriptorType 5
73 | bEndpointAddress 0x85 EP 3 IN
74 | bmAttributes 1
75 | Transfer Type Interrupt
76 | Synch Type None
77 | Usage Type Data
78 | wMaxPacketSize 0x0040 1x 64 bytes
79 | bInterval 8
80 |
81 |
--------------------------------------------------------------------------------
/dev_desc/desc3.txt_tmp:
--------------------------------------------------------------------------------
1 | Speed Full
2 | Bus 001 Device 043: ID 1307:0165 Transcend Information, Inc. 2GB/4GB Flash Drive
3 | Device Descriptor:
4 | bLength 18
5 | bDescriptorType 1
6 | bcdUSB 2.00
7 | bDeviceClass 0 (Defined at Interface level)
8 | bDeviceSubClass 0
9 | bDeviceProtocol 0
10 | bMaxPacketSize0 64
11 | idVendor 0x3340 Transcend Information, Inc.
12 | idProduct 0x3457 2GB/4GB Flash Drive
13 | bcdDevice 1.00
14 | iManufacturer 1
15 | iProduct 2
16 | iSerial 3
17 | bNumConfigurations 1
18 | Configuration Descriptor:
19 | bLength 9
20 | bDescriptorType 2
21 | wTotalLength 48
22 | bNumInterfaces 1
23 | bConfigurationValue 1
24 | iConfiguration 0
25 | bmAttributes 0x80
26 | (Bus Powered)
27 | MaxPower 98mA
28 | Interface Descriptor:
29 | bLength 9
30 | bDescriptorType 4
31 | bInterfaceNumber 0
32 | bAlternateSetting 0
33 | bNumEndpoints 3
34 | bInterfaceClass 0 Mass Storage
35 | bInterfaceSubClass 0 SCSI
36 | bInterfaceProtocol 0 Bulk-Only
37 | iInterface 0
38 | iInterface 0
39 | HID Device Descriptor:
40 | bLength 9
41 | bDescriptorType 33
42 | bcdHID 1.10
43 | bCountryCode 0 Not supported
44 | bNumDescriptors 1
45 | bDescriptorType 34 Report
46 | wDescriptorLength 119
47 | Report Descriptors:
48 | ** UNAVAILABLE **
49 |
50 | Endpoint Descriptor:
51 | bLength 7
52 | bDescriptorType 5
53 | bEndpointAddress 0x0A EP 1 OUT
54 | bmAttributes 2
55 | Transfer Type Bulk
56 | Synch Type None
57 | Usage Type Data
58 | wMaxPacketSize 0x0040 1x 512 bytes
59 | bInterval 1
60 | Endpoint Descriptor:
61 | bLength 7
62 | bDescriptorType 5
63 | bEndpointAddress 0x8C EP 2 IN
64 | bmAttributes 2
65 | Transfer Type Bulk
66 | Synch Type None
67 | Usage Type Data
68 | wMaxPacketSize 0x0040 1x 512 bytes
69 | bInterval 1
70 | Endpoint Descriptor:
71 | bLength 7
72 | bDescriptorType 5
73 | bEndpointAddress 0x85 EP 3 IN
74 | bmAttributes 1
75 | Transfer Type Interrupt
76 | Synch Type None
77 | Usage Type Data
78 | wMaxPacketSize 0x0040 1x 64 bytes
79 | bInterval 8
80 |
81 |
--------------------------------------------------------------------------------
/monitor/linux_monitor.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | from monitor import monitor
11 | import fcntl
12 | from scapy.all import *
13 | sys.path.append(os.path.abspath('../'))
14 | import config
15 |
16 |
17 | class linux_monitor(monitor):
18 | def __init__(self, qemu, filename):
19 | super(linux_monitor, self).__init__(qemu, filename)
20 |
21 | def monitor(self, title):
22 | return self.__monitor(title)[0]
23 |
24 | def __non_block_read(self, output):
25 | fd = output.fileno()
26 | fl = fcntl.fcntl(fd, fcntl.F_GETFL)
27 | fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
28 | try:
29 | return output.read()
30 | except:
31 | return ""
32 |
33 | def __monitor(self, title):
34 | data = ""
35 | try_to_read = 0
36 | while True:
37 | if data.count('\n') >= config.SERIAL_READ_MAX_LINES:
38 | data = data + config.MESSAGE_TOO_MUCH_DATA
39 | self.qemu.kill()
40 | self.qemu.start()
41 | break
42 |
43 | fd = select([self.qemu.process.stdout], [], [], config.SERIAL_READ_TIMEOUT)
44 | fd = fd[0]
45 |
46 | if len(fd) != 0:
47 | if fd[0]:
48 | tmp = self.__non_block_read(fd[0])
49 | if tmp == "":
50 | break
51 | else:
52 | data = data + tmp
53 | try_to_read = 0
54 | else:
55 | break
56 | #else:
57 | # pass
58 | try_to_read += 1
59 |
60 | if try_to_read >= config.SERIAL_READ_RETRIES:
61 | break
62 |
63 | try:
64 | tmp_data = data.split("\r")[1].translate(None, "\n ").replace("(qemu)", "").replace("replay", "").replace(
65 | "loadvm", "")
66 | except:
67 | return False, ""
68 |
69 | if len(tmp_data) == 0:
70 | return False, ""
71 |
72 | tmp_data = tmp_data.translate(None, "\x6c\x5b\x4b\x44\x6f\x61\x64\x76\x72\x65\x70")
73 | if len(tmp_data) == 0:
74 | return False, ""
75 |
76 | if str(Raw(tmp_data.replace("\x1b", ""))).encode("hex") == "":
77 | return False, ""
78 |
79 | _tmp = data
80 | data = data.split("\n")
81 | data2 = title + "\n" # + data + delimiter
82 | f = open(self.filename, "a")
83 | f.write(data2)
84 | for line in data:
85 | if not line.startswith("(qemu)") and not line.startswith(
86 | "QEMU ") and not "Clocksource tsc unstable (delta" in line:
87 | f.write(line + "\n")
88 | f.write(config.DELIMITER + "\n")
89 | f.close()
90 | return True, _tmp
91 |
92 |
--------------------------------------------------------------------------------
/payload/panic_2.obj:
--------------------------------------------------------------------------------
1 | REPRODUCE_KEY:
2 | MQoKMjk5Mf9pc1ZlbmRvcv9BTEwKMjM1/2lkUHJvZHVjdP9BTEwKM/9iRGV2aWNlQ2xhc3P/QUxMCjP/YkludGVyZmFjZUNsYXNz/0FMTAoz/2JOdW1FbmRwb2ludHP/VVNCX0ludGVyZmFjZV9EZXNjcmlwdG9yCjD/Yk51bUludGVyZmFjZXP/VVNCX0NvbmZpZ3VyYXRpb25fRGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMy50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24K
3 |
4 | REPRODUCE_KEY:
5 | MgoKMzQ2Of9pc1ZlbmRvcv9BTEwKMTM2Mv9pZFByb2R1Y3T/QUxMCjP/YkRldmljZUNsYXNz/0FMTAoz/2JJbnRlcmZhY2VDbGFzc/9BTEwKMjX/Yk51bUVuZHBvaW50c/9VU0JfSW50ZXJmYWNlX0Rlc2NyaXB0b3IKNf9iTnVtSW50ZXJmYWNlc/9VU0JfQ29uZmlndXJhdGlvbl9EZXNjcmlwdG9yCgpkZXNjcmlwdG9y/2Rlc2MzLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgo=
6 |
7 | REPRODUCE_KEY:
8 | MwoKMTg5Mf9pc1ZlbmRvcv9BTEwKNDExN/9pZFByb2R1Y3T/QUxMCjI1Nf9iRGV2aWNlQ2xhc3P/QUxMCjI1Nf9iSW50ZXJmYWNlQ2xhc3P/QUxMCjH/Yk51bUVuZHBvaW50c/9VU0JfSW50ZXJmYWNlX0Rlc2NyaXB0b3IKMTD/Yk51bUludGVyZmFjZXP/VVNCX0NvbmZpZ3VyYXRpb25fRGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMy50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24K
9 |
10 | REPRODUCE_KEY:
11 | NAoKMTMyM/9pc1ZlbmRvcv9BTEwKNTM5Nv9pZFByb2R1Y3T/QUxMCjL/YkRldmljZUNsYXNz/0FMTAoy/2JJbnRlcmZhY2VDbGFzc/9BTEwKMv9iTnVtRW5kcG9pbnRz/1VTQl9JbnRlcmZhY2VfRGVzY3JpcHRvcgow/2JOdW1JbnRlcmZhY2Vz/1VTQl9Db25maWd1cmF0aW9uX0Rlc2NyaXB0b3IKCmRlc2NyaXB0b3L/ZGVzYzMudHh0CmVtdWxhdG9y/2VudW1lcmF0aW9uCg==
12 |
13 | REPRODUCE_KEY:
14 | NQoKMTE5M/9pc1ZlbmRvcv9BTEwKNDI2M/9pZFByb2R1Y3T/QUxMCjH/YkRldmljZUNsYXNz/0FMTAox/2JJbnRlcmZhY2VDbGFzc/9BTEwKMTb/Yk51bUVuZHBvaW50c/9VU0JfSW50ZXJmYWNlX0Rlc2NyaXB0b3IKMTAw/2JOdW1JbnRlcmZhY2Vz/1VTQl9Db25maWd1cmF0aW9uX0Rlc2NyaXB0b3IKCmRlc2NyaXB0b3L/ZGVzYzMudHh0CmVtdWxhdG9y/2VudW1lcmF0aW9uCg==
15 |
16 | REPRODUCE_KEY:
17 | NgoKNDkzMf9pc1ZlbmRvcv9BTEwKNf9pZFByb2R1Y3T/QUxMCjD/YkRldmljZUNsYXNz/0FMTAow/2JJbnRlcmZhY2VDbGFzc/9BTEwKMjj/Yk51bUVuZHBvaW50c/9VU0JfSW50ZXJmYWNlX0Rlc2NyaXB0b3IKMTD/Yk51bUludGVyZmFjZXP/VVNCX0NvbmZpZ3VyYXRpb25fRGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMy50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24K
18 |
19 | REPRODUCE_KEY:
20 | NwoKMTQ5Nv9pc1ZlbmRvcv9BTEwKMTYzOTP/aWRQcm9kdWN0/0FMTAox/2JEZXZpY2VDbGFzc/9BTEwKMf9iSW50ZXJmYWNlQ2xhc3P/QUxMCjE3/2JOdW1FbmRwb2ludHP/VVNCX0ludGVyZmFjZV9EZXNjcmlwdG9yCjX/Yk51bUludGVyZmFjZXP/VVNCX0NvbmZpZ3VyYXRpb25fRGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMy50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24K
21 |
22 | REPRODUCE_KEY:
23 | OAoKNTY0MP9pc1ZlbmRvcv9BTEwKMjc2/2lkUHJvZHVjdP9BTEwKMP9iRGV2aWNlQ2xhc3P/QUxMCjD/YkludGVyZmFjZUNsYXNz/0FMTAoyNf9iTnVtRW5kcG9pbnRz/1VTQl9JbnRlcmZhY2VfRGVzY3JpcHRvcgoxMDD/Yk51bUludGVyZmFjZXP/VVNCX0NvbmZpZ3VyYXRpb25fRGVzY3JpcHRvcgoKZGVzY3JpcHRvcv9kZXNjMy50eHQKZW11bGF0b3L/ZW51bWVyYXRpb24K
24 |
25 | REPRODUCE_KEY:
26 | OQoKNjkxNv9pc1ZlbmRvcv9BTEwKMjQ3MDP/aWRQcm9kdWN0/0FMTAow/2JEZXZpY2VDbGFzc/9BTEwKMP9iSW50ZXJmYWNlQ2xhc3P/QUxMCjIz/2JOdW1FbmRwb2ludHP/VVNCX0ludGVyZmFjZV9EZXNjcmlwdG9yCjEwMP9iTnVtSW50ZXJmYWNlc/9VU0JfQ29uZmlndXJhdGlvbl9EZXNjcmlwdG9yCgpkZXNjcmlwdG9y/2Rlc2MzLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgo=
27 |
28 | REPRODUCE_KEY:
29 | MTAKCjIxMjX/aXNWZW5kb3L/QUxMCjI1/2lkUHJvZHVjdP9BTEwKMjU1/2JEZXZpY2VDbGFzc/9BTEwKMjU1/2JJbnRlcmZhY2VDbGFzc/9BTEwKMjT/Yk51bUVuZHBvaW50c/9VU0JfSW50ZXJmYWNlX0Rlc2NyaXB0b3IKNf9iTnVtSW50ZXJmYWNlc/9VU0JfQ29uZmlndXJhdGlvbl9EZXNjcmlwdG9yCgpkZXNjcmlwdG9y/2Rlc2MzLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgo=
30 |
31 | REPRODUCE_KEY:
32 | MTEKCjE1MDf/aXNWZW5kb3L/QUxMCjc2Of9pZFByb2R1Y3T/QUxMCjL/YkRldmljZUNsYXNz/0FMTAoy/2JJbnRlcmZhY2VDbGFzc/9BTEwKMP9iTnVtRW5kcG9pbnRz/1VTQl9JbnRlcmZhY2VfRGVzY3JpcHRvcgoxMP9iTnVtSW50ZXJmYWNlc/9VU0JfQ29uZmlndXJhdGlvbl9EZXNjcmlwdG9yCgpkZXNjcmlwdG9y/2Rlc2MzLnR4dAplbXVsYXRvcv9lbnVtZXJhdGlvbgo=
33 |
34 |
--------------------------------------------------------------------------------
/emulator/enumeration.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | import os.path, sys, time, random
11 |
12 | from emulator import emulator
13 |
14 | sys.path.append(os.path.abspath('../'))
15 | from usbparser import *
16 | from fileParser import *
17 | from descFuzzer import *
18 |
19 |
20 | class enumeration(emulator):
21 | def __init__(self, fuzzer):
22 | super(enumeration, self).__init__(fuzzer)
23 | self.descriptor = self.fuzzer.get_descriptor()
24 | #print self.descriptor
25 | self.string_descriptor = self.fuzzer.get_string_descriptor()
26 |
27 | def __get_complete_configuration_descriptor(self, configuration_num):
28 | configuration = get_configuration_descriptor(self.descriptor, configuration_num)
29 | if configuration == None:
30 | return None
31 |
32 | extra_payload = configuration[0]
33 | for ifDesc in configuration[1]:
34 | extra_payload = extra_payload / ifDesc[0]
35 | for e in ifDesc[1]:
36 | extra_payload = extra_payload / e
37 | return extra_payload
38 |
39 | def _calc_response(self, data):
40 | scapy_data = usbredir_parser(data).getScapyPacket()
41 | packet_length = 0
42 | extra_payload = None
43 |
44 | # check if data comes from control endpoint
45 | if scapy_data.Htype != 100:
46 | return None
47 |
48 | # check if data comes from endpoint 0 (output)
49 | if scapy_data.endpoint != 0x80:
50 | return scapy_data
51 |
52 | descriptor_request = scapy_data.value >> (8)
53 | descriptor_num = scapy_data.value % 256
54 | request = scapy_data.request
55 |
56 | # device descriptor
57 | if descriptor_request == 0x01:
58 | extra_payload = self.descriptor[0]
59 | packet_length = len(str(extra_payload))
60 |
61 | # configuration descriptor
62 | elif descriptor_request == 0x02:
63 | if scapy_data.length <= 9:
64 | configuration = get_configuration_descriptor(self.descriptor, descriptor_num)
65 | if configuration == None:
66 | extra_payload == None
67 | else:
68 | packet_length = scapy_data.length
69 | extra_payload = configuration[0]
70 | else:
71 | extra_payload = self.__get_complete_configuration_descriptor(descriptor_num)
72 | packet_length = len(str(extra_payload))
73 |
74 | # string descriptor
75 | elif descriptor_request == 0x03:
76 | if descriptor_num < len(self.string_descriptor) + 1:
77 | extra_payload = self.string_descriptor[descriptor_num - 1]
78 | else:
79 | extra_payload = usb_string_descriptor('\x04\x03\x09\04')
80 | packet_length = len(str(extra_payload))
81 | #extra_payload.show()
82 |
83 | # redir stuff
84 | scapy_data.HLength = 10 + len(str(extra_payload))
85 | scapy_data.status = 0
86 | scapy_data.length = packet_length
87 |
88 |
89 | if extra_payload is None:
90 | scapy_data.HLength = 10
91 | return scapy_data
92 |
93 | return (scapy_data / extra_payload)
94 |
--------------------------------------------------------------------------------
/fuzzer.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 |
9 | from usbscapy import usb_string_descriptor
10 |
11 | class fuzzer(object):
12 | def __init__(self, test):
13 | self.test = test
14 | self.string_descriptor = None
15 |
16 | def set_descriptor(self, descriptor):
17 | self.descriptor = descriptor
18 |
19 | def set_string_descriptor(self, string_descriptor):
20 | self.string_descriptor = string_descriptor
21 |
22 | def get_descriptor(self):
23 | return self.descriptor
24 |
25 | def get_string_descriptor(self):
26 | # if self.string_descriptor is None:
27 | min_d = usb_string_descriptor('\x04\x03\x09\01')
28 | max_d = usb_string_descriptor(
29 | '\xfe\x03\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P\x00P')
30 | format_string = usb_string_descriptor(
31 | '\xfe\x03%\x00\x00\x00%\x00\x01\x00%\x00\x02\x00%\x00\x03\x00%\x00\x04\x00%\x00\x05\x00%\x00\x06\x00%\x00\x07\x00%\x00\x08\x00%\x00\t\x00%\x00\n\x00%\x00\x0b\x00%\x00\x0c\x00%\x00\r\x00%\x00\x0e\x00%\x00\x0f\x00%\x00\x10\x00%\x00\x11\x00%\x00\x12\x00%\x00\x13\x00%\x00\x14\x00%\x00\x15\x00%\x00\x16\x00%\x00\x17\x00%\x00\x18\x00%\x00\x19\x00%\x00\x1a\x00%\x00\x1b\x00%\x00\x1c\x00%\x00\x1d\x00%\x00\x1e\x00%\x00\x1f\x00%\x00 \x00%\x00!\x00%\x00"\x00%\x00#\x00%\x00$\x00%\x00%\x00%\x00&\x00%\x00\'\x00%\x00(\x00%\x00)\x00%\x00*\x00%\x00+\x00%\x00,\x00%\x00-\x00%\x00.\x00%\x00/\x00%\x000\x00%\x001\x00%\x002\x00%\x003\x00%\x004\x00%\x005\x00%\x006\x00%\x007\x00%\x008\x00%\x009\x00%\x00:\x00%\x00;\x00%\x00<\x00%\x00=\x00%\x00>\x00')
32 |
33 | string_descriptor_list = []
34 | string_descriptor_list.append(min_d)
35 | string_descriptor_list.append(min_d)
36 | string_descriptor_list.append(format_string)
37 | return string_descriptor_list
38 |
39 | def post_fuzzing(self, scapy_data):
40 |
41 | # return scapy_data
42 |
43 | if self.test is None:
44 | raise Exception('Test is not set')
45 |
46 | test_elements = self.test.get_testcases()
47 |
48 | tmp = scapy_data
49 | i = 0
50 |
51 | while len(str(tmp)) != 0:
52 | try:
53 | for i in range(len(test_elements)):
54 | if True:
55 | if test_elements[i].get_packet_type() == "ALL":
56 | try:
57 | setattr(tmp, test_elements[i].get_field(), test_elements[i].get_value())
58 | except:
59 | pass
60 | elif test_elements[i].get_packet_type().lower() == str(type(tmp)).split(".")[1].split("'")[0]:
61 | setattr(tmp, test_elements[i].get_field(), test_elements[i].get_value())
62 |
63 | i += 1
64 | except:
65 | pass
66 | tmp = tmp.payload
67 | return scapy_data
--------------------------------------------------------------------------------
/payload/old_payload/panic_2.obj:
--------------------------------------------------------------------------------
1 | (lp0
2 | (lp1
3 | I7841715
4 | a(lp2
5 | (lp3
6 | S'name'
7 | p4
8 | aS'enumeration'
9 | p5
10 | aa(lp6
11 | S'descriptor'
12 | p7
13 | aS'desc3.txt'
14 | p8
15 | aa(lp9
16 | S'reload'
17 | p10
18 | aI01
19 | aaa(ifuzz_configuration.test
20 | test_package
21 | p11
22 | (dp12
23 | S'raw_data'
24 | p13
25 | (I2991
26 | I235
27 | I3
28 | I3
29 | I3
30 | I0
31 | tp14
32 | sS'operation_list'
33 | p15
34 | (lp16
35 | (lp17
36 | I0
37 | aS'fuzz'
38 | p18
39 | aS'isVendor'
40 | p19
41 | aS'ALL'
42 | p20
43 | aa(lp21
44 | I0
45 | ag18
46 | aS'idProduct'
47 | p22
48 | aS'ALL'
49 | p23
50 | aa(lp24
51 | I1
52 | ag18
53 | aS'bDeviceClass'
54 | p25
55 | aS'ALL'
56 | p26
57 | aa(lp27
58 | I1
59 | ag18
60 | aS'bInterfaceClass'
61 | p28
62 | aS'ALL'
63 | p29
64 | aa(lp30
65 | I2
66 | ag18
67 | aS'bNumEndpoints'
68 | p31
69 | aS'USB_Interface_Descriptor'
70 | p32
71 | aa(lp33
72 | I3
73 | ag18
74 | aS'bNumInterfaces'
75 | p34
76 | aS'USB_Configuration_Descriptor'
77 | p35
78 | aasS'name_list'
79 | p36
80 | (lp37
81 | S'all_vender_product_ids'
82 | p38
83 | aS'all_class_ids'
84 | p39
85 | aS'dev_desc_blength_invalid'
86 | p40
87 | aS'conf_bNum_Interface_invalid'
88 | p41
89 | asS'emulator'
90 | p42
91 | Nsbaa(lp43
92 | I8622576
93 | ag2
94 | a(ifuzz_configuration.test
95 | test_package
96 | p44
97 | (dp45
98 | g13
99 | (I3469
100 | I1362
101 | I3
102 | I3
103 | I25
104 | I5
105 | tp46
106 | sg15
107 | g16
108 | sg36
109 | g37
110 | sg42
111 | Nsbaa(lp47
112 | I6056107
113 | ag2
114 | a(ifuzz_configuration.test
115 | test_package
116 | p48
117 | (dp49
118 | g13
119 | (I1891
120 | I4117
121 | I255
122 | I255
123 | I1
124 | I10
125 | tp50
126 | sg15
127 | g16
128 | sg36
129 | g37
130 | sg42
131 | Nsbaa(lp51
132 | I3901060
133 | ag2
134 | a(ifuzz_configuration.test
135 | test_package
136 | p52
137 | (dp53
138 | g13
139 | (I1323
140 | I5396
141 | I2
142 | I2
143 | I2
144 | I0
145 | tp54
146 | sg15
147 | g16
148 | sg36
149 | g37
150 | sg42
151 | Nsbaa(lp55
152 | I2396484
153 | ag2
154 | a(ifuzz_configuration.test
155 | test_package
156 | p56
157 | (dp57
158 | g13
159 | (I1193
160 | I4263
161 | I1
162 | I1
163 | I16
164 | I100
165 | tp58
166 | sg15
167 | g16
168 | sg36
169 | g37
170 | sg42
171 | Nsbaa(lp59
172 | I9789142
173 | ag2
174 | a(ifuzz_configuration.test
175 | test_package
176 | p60
177 | (dp61
178 | g13
179 | (I4931
180 | I5
181 | I0
182 | I0
183 | I28
184 | I10
185 | tp62
186 | sg15
187 | g16
188 | sg36
189 | g37
190 | sg42
191 | Nsbaa(lp63
192 | I5006486
193 | ag2
194 | a(ifuzz_configuration.test
195 | test_package
196 | p64
197 | (dp65
198 | g13
199 | (I1496
200 | I16393
201 | I1
202 | I1
203 | I17
204 | I5
205 | tp66
206 | sg15
207 | g16
208 | sg36
209 | g37
210 | sg42
211 | Nsbaa(lp67
212 | I10230879
213 | ag2
214 | a(ifuzz_configuration.test
215 | test_package
216 | p68
217 | (dp69
218 | g13
219 | (I5640
220 | I276
221 | I0
222 | I0
223 | I25
224 | I100
225 | tp70
226 | sg15
227 | g16
228 | sg36
229 | g37
230 | sg42
231 | Nsbaa(lp71
232 | I10845869
233 | ag2
234 | a(ifuzz_configuration.test
235 | test_package
236 | p72
237 | (dp73
238 | g13
239 | (I6916
240 | I24703
241 | I0
242 | I0
243 | I23
244 | I100
245 | tp74
246 | sg15
247 | g16
248 | sg36
249 | g37
250 | sg42
251 | Nsbaa(lp75
252 | I6711721
253 | ag2
254 | a(ifuzz_configuration.test
255 | test_package
256 | p76
257 | (dp77
258 | g13
259 | (I2125
260 | I25
261 | I255
262 | I255
263 | I24
264 | I5
265 | tp78
266 | sg15
267 | g16
268 | sg36
269 | g37
270 | sg42
271 | Nsbaa(lp79
272 | I5170052
273 | ag2
274 | a(ifuzz_configuration.test
275 | test_package
276 | p80
277 | (dp81
278 | g13
279 | (I1507
280 | I769
281 | I2
282 | I2
283 | I0
284 | I10
285 | tp82
286 | sg15
287 | g16
288 | sg36
289 | g37
290 | sg42
291 | Nsbaa.
--------------------------------------------------------------------------------
/config.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | # monitor specific ######
11 | # serial port read timeout (select timeout)
12 | SERIAL_READ_TIMEOUT = 0.45
13 | # maximal number of lines reading in
14 | SERIAL_READ_MAX_LINES = 1024
15 | # maximal number of read retries
16 | SERIAL_READ_RETRIES = 1
17 | # fuzzing test print delimiter
18 | DELIMITER = "\n#######################################################\n\n"
19 | # fuzzing test SERIAL_READ_MAX_LINES message
20 | MESSAGE_READ_MAX_LINES = "\n ------->>>>> MESSAGE_READ_MAX_LINES <<<<<-------"
21 | # VM reload message
22 | MESSAGE_VM_RELOAD = "====================\tRELOAD\t====================\n"
23 | # log message for 'too much data to process' case
24 | MESSAGE_TOO_MUCH_DATA = "\n ------->>>>> TOO MUCH DATA FROM STDOUT! <<<<<-------"
25 | PRINT_VERBOSE_TEST_INFO = True
26 |
27 | # usbemulator specific ######
28 | # number of reconnects (QEMU usbredir interface)
29 | NUMBER_OF_RECONNECTS = 3
30 | # timeout between reconnects
31 | TIME_BETWEEN_RECONNECTS = 0
32 | # defined content of usbredir hello_packet
33 | USB_REDIR_HELLO_PACKET = 'usbredirserver 0.6\x00\x00\x00\x00\x00\x00\xc0\x1f@\x00\x00\x00\x00\x00\x00\x9dj\x00\x00\x00\x00\x00uB\xe8h:\x7f\x00\x00\x80\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\xfe\x00\x00\x00'
34 | # path to folder, which contains all available devices descriptors
35 | DEV_DESC_FOLDER = "dev_desc/"
36 | # unix socket timeout
37 | UNIX_SOCKET_TIMEOUT = 0.5
38 | # tcp socket timeout
39 | TCP_SOCKET_TIMEOUT = 0.75
40 | # connection to victim timeout
41 | # (Linux: 0.2 - 0,75 / FreeBSD: 1.25 - 2.0)
42 | CONNECTION_TO_VICTIM_TIMEOUT = 1.35
43 | # max redir packet recv (deadlock prevention)
44 | MAX_PACKETS = 500
45 |
46 | # execution process specific ######
47 | # fail counter
48 | PROCESS_FAIL_COUNTER = 4
49 | PROCESS_FAIL_REPAIR_COUNTER = 5
50 | PROCESS_FAIL_SLEEP_A = 0.1
51 | PROCESS_FAIL_SLEEP_B = 0.4
52 | PROCESS_NOTIFY_SHARED_MEMORY = 1
53 | PROCESS_TIMOUT_AFTER_REPAIR = 1.0
54 | # threshold number of succesful testcases until qemu loadvm is used
55 | PROCESS_SLOW_START_THRESHOLD = 5
56 | PROCESS_SLOW_START_THRESHOLD_FAIL_COUNTER = 100
57 | PROCESS_REPAIR_SEMAPHORE = 5
58 |
59 | # debug specific ######
60 | # define verbose level distinctions
61 | VERBOSE_LEVEL_PRINT_ERROR_MESSAGES = 4
62 | VERBOSE_LEVEL_PRINT_RECV_DATA = 3
63 | VERBOSE_LEVEL_PRINT_SEND_DATA = 2
64 | VERBOSE_LEVEL_PRINT_INFO = 1
65 | VERBOSE_LEVEL_PRINT_NOTHING = 0
66 | # SIGUSR1 debug option
67 | ENABLE_DEBUG_PROCESS = False
68 | VERBOSE_LEVEL = 0
69 |
70 | # performance process ######
71 | PRINT_PERFORMANCE_TIMEOUT = 5.0
72 | PRINT_PERFORMANCE_SERVER_TIMEOUT = 10.0
73 |
74 | # multiprocessing specific ######
75 | NUMBER_OF_JOBS_PER_PROCESS = 2048
76 | PROCESS_STARTUP_TIME = 5.0
77 | PROCESS_STARTUP_RATE = 0.5
78 |
79 | # qemu specific #####
80 | OVERLAY_FILE_PREFIX = "overlay_"
81 | OVERLAY_FILE_POSTFIX = ".qcow2"
82 |
83 | # non multiprocessing specifc #####
84 | NUMBER_OF_JOBS_PER_PROCESS_NM = 100000
85 | SLEEP_BETWEEN_TESTS = 0.2
86 |
87 | # clustering specific #####
88 | CLUSTERING_DEBUG_SERVER = False
89 | CLUSTERING_DEBUG_CLIENT = False
90 | CLUSTERING_CHUNK_SIZE = 2
91 | CLUSTERING_CONNECTION_RETRY_TIME = 1
92 |
93 | # execute mode specific #####
94 | SERIAL_READ_RETRIES_EXECUTE_MODE = 8
95 | PROCESS_SLOW_START_THRESHOLD_EXECUTE_MODE = 0
96 | PROCESS_SLOW_START_THRESHOLD_FAIL_COUNTER_EXECUTE_MODE = 0
97 | PROCESS_FAIL_REPAIR_COUNTER_EXECUTE_MODE = 2
98 |
99 | # options #####
100 | PRINT_DEVICE_DESCRIPTORS = False
101 |
--------------------------------------------------------------------------------
/process/print_performance_process.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | import signal
11 | import sys
12 | import os
13 | import time
14 | import datetime
15 |
16 | sys.path.append(os.path.abspath('../'))
17 | import config
18 |
19 |
20 |
21 | def signal_handler(signal, frame):
22 | sys.exit(0)
23 |
24 |
25 | def getTime(timeValue):
26 | HOUR = 3600
27 | return "[" + str(int(str(datetime.datetime.fromtimestamp(timeValue).strftime('%j')),10)-1) + str(datetime.datetime.fromtimestamp(timeValue-HOUR).strftime(':%H:%M:%S')) + "]"
28 |
29 | def getTimeDate(timeValue):
30 | return "[" + str(datetime.datetime.fromtimestamp(timeValue).strftime('%d/%m/%y:%H:%M:%S')) + "]"
31 |
32 |
33 | def printPerf_Server(max_num_of_tasks, timeout, connection_list):
34 | # print "INFO_THREAD"
35 | start_time = time.time()
36 |
37 | while True:
38 | time.sleep(config.PRINT_PERFORMANCE_SERVER_TIMEOUT)
39 | total = 0
40 | for element in connection_list:
41 | total += element[1].value
42 |
43 | if total != 0:
44 | new_time = time.time()
45 | raw_value = float(total) / (float(new_time) - float(start_time))
46 | print "Jobs Done: " + str(total) + " \tPerformance: " + str(round(raw_value, 2)) + " t/s"
47 | else:
48 | print "\nClients:"
49 |
50 | for element in connection_list:
51 | print "\t" + element[0] + " \t",
52 | if element[2].is_alive():
53 | print "Condition: alive \t",
54 | else:
55 | print "Condition: dead \t",
56 | print "Jobs Done: " + str(element[1].value) + " \t",
57 | print "'Connection Time: " + getTimeDate(element[3])
58 | print ""
59 | #print element[1].value
60 |
61 |
62 | def printPerf(max_num_of_tasks, sm_tasks_num):
63 | signal.signal(signal.SIGINT, signal_handler)
64 | start_time = time.time()
65 | old = 0
66 | while True:
67 | tmp = sm_tasks_num.value
68 |
69 | if tmp == max_num_of_tasks and max_num_of_tasks != 0:
70 | print getTimeDate(time.time()) + "\t Running time: " + getTime(time.time() - start_time )
71 | return
72 | else:
73 | new_time = time.time()
74 | raw_value = float(tmp) / (float(new_time) - float(start_time))
75 | value = round(raw_value, 2)
76 |
77 | if raw_value != 0:
78 | remaining_time = (max_num_of_tasks - tmp) / raw_value
79 | else:
80 | remaining_time = 0.0
81 |
82 | if remaining_time != 0.0 and max_num_of_tasks != 0:
83 | print getTimeDate(time.time()) + "\t" + str(value) + " t/s " + "\tREAL: " + str(
84 | round(float((tmp - old) / (float(config.PRINT_PERFORMANCE_TIMEOUT))), 2)) + " t/s" + " \t" + str(
85 | tmp) + "/" + str(max_num_of_tasks) + " \t running time: " + getTime(
86 | time.time() - start_time) + "\t remaining time: " + getTime(remaining_time )
87 | else:
88 | value = max_num_of_tasks
89 | if max_num_of_tasks == 0:
90 | value = '-'
91 | print getTimeDate(time.time()) + "\t" + "\tREAL: " + str(
92 | round(float((tmp - old) / (float(config.PRINT_PERFORMANCE_TIMEOUT))), 2)) + " t/s" + " \t" + str(
93 | tmp) + "/" + str(value) + "\t running time: " + getTime(time.time() - start_time )
94 |
95 | time.sleep(config.PRINT_PERFORMANCE_TIMEOUT)
96 |
97 | old = tmp
98 |
99 |
--------------------------------------------------------------------------------
/process/client_process.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | from multiprocessing import Process, Value, Queue, Semaphore
11 | from qemu import qemu
12 | from process import process
13 | from print_performance_process import *
14 | import signal
15 | import time
16 | from clustering.network_task_requester import start_network_task_requester
17 |
18 | process_list = None
19 | printPerf_process = None
20 | network_requester_process = None
21 |
22 | def signal_handler(signal, frame):
23 | kill_all()
24 |
25 | def kill_all():
26 | global process_list
27 | global network_requester_process
28 | if process_list is not None:
29 | for p in process_list:
30 | if p.is_alive:
31 | p.terminate()
32 |
33 | if network_requester_process is not None:
34 | if network_requester_process.is_alive:
35 | try:
36 | network_requester_process.terminate()
37 | network_requester_process.join()
38 | except AttributeError:
39 | pass
40 | sys.exit(0)
41 |
42 |
43 | def client(process_number, target_object, host, port, reload_test):
44 | global process_list
45 | global network_requester_process
46 | signal.signal(signal.SIGINT, signal_handler)
47 | number_of_threads = process_number
48 |
49 | max_tasks = 100000
50 | sm_num_of_tasks = Value('i', 0)
51 |
52 | info_queue = Queue()
53 | queue_list = []
54 | process_list = []
55 | process_lock = Semaphore(process_number)
56 | for i in range(process_number):
57 | process_lock.acquire()
58 | sem = Semaphore(config.PROCESS_REPAIR_SEMAPHORE)
59 |
60 | for i in range(number_of_threads):
61 | queue_list.append(Queue())
62 | qemu_object = qemu("configurations/" + target_object, "/tmp/vusbf_" + str(i) + "_socket", i)
63 | process_list.append(Process(target=process, args=("t" + str(i), qemu_object, sm_num_of_tasks, i, info_queue, queue_list[i], reload_test, sem, process_lock)))
64 |
65 | printPerf_process = Process(target=printPerf, args=(0, sm_num_of_tasks))
66 |
67 | payload_queue = Queue()
68 | request_queue = Queue()
69 | request_queue.put(config.CLUSTERING_CHUNK_SIZE)
70 |
71 | j = 0
72 | print "[*] Starting processes..."
73 | for e in process_list:
74 | e.start()
75 | time.sleep(0.1)
76 | print "[*] Preparing processes..."
77 | time.sleep(config.PROCESS_STARTUP_TIME)
78 |
79 | # start network task requester
80 | network_requester_process = Process(target=start_network_task_requester, args=(host, port, "sdsds", "sasas", sm_num_of_tasks, info_queue, payload_queue, request_queue, 1337, 2))
81 | network_requester_process.start()
82 |
83 | num_of_fin = 0
84 | num_of_processes = len(process_list)
85 | j = 0
86 | no_data = False
87 | while True:
88 | if num_of_fin == num_of_processes:
89 | break
90 | if j == num_of_processes-num_of_fin:
91 | print "[*] Done..."
92 | printPerf_process.start()
93 | for i in range(num_of_processes):
94 | time.sleep(config.PROCESS_STARTUP_RATE)
95 | process_lock.release()
96 |
97 | process_num = info_queue.get()
98 |
99 | if not no_data:
100 | request_queue.put(config.CLUSTERING_CHUNK_SIZE)
101 | data = payload_queue.get()
102 | else:
103 | data = None
104 | if data is not None:
105 | queue_list[process_num].put(data)
106 | j += 1
107 | else:
108 | num_of_fin += 1
109 | queue_list[process_num].put(None)
110 | no_data = True
111 |
112 | print "[*] Finished..."
113 | printPerf_process.terminate()
114 | network_requester_process.terminate()
--------------------------------------------------------------------------------
/process/distributor_process.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | from fileParser import *
11 | from clustering.network_task_distributor import process
12 | from multiprocessing import Process, Value, Queue
13 | from threading import Thread
14 | #from fuzz_configuration.xml_parser import xml_parser
15 | from test_generation.XMLParser import xml_parser
16 | from random import shuffle
17 | from print_performance_process import printPerf_Server
18 | import signal
19 | import config
20 |
21 | server_process_list = []
22 | print_perf_process = None
23 | dist_process = None
24 |
25 | def signal_handler2(signal, frame):
26 | exit(0)
27 |
28 | def signal_handler(signal, frame):
29 | kill_all()
30 |
31 | def kill_all_process():
32 | global server_process_list
33 | for e in server_process_list:
34 | if e is not None:
35 | if e.is_alive():
36 | e.terminate()
37 |
38 | def kill_all():
39 | global dist_process
40 | print dist_process
41 | if dist_process is not None:
42 | print "A"
43 | if dist_process.is_alive():
44 | print "KILL"
45 | os.kill(dist_process.pid, signal.SIGINT)
46 | print "KILLKILL"
47 | sys.exit(0)
48 |
49 | def distributor_process(host, port, info_queue, payload_queue):
50 | global server_process_list, print_perf_process
51 | signal.signal(signal.SIGINT, signal_handler2)
52 |
53 | perf_list = []
54 | print_perf_process = Thread(target=printPerf_Server, args=(0, 10, perf_list)).start()
55 |
56 | while True:
57 | try:
58 | Socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
59 | Socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
60 | Socket.bind((host, port))
61 | while True:
62 | Socket.listen(1)
63 | Connection, Addr = Socket.accept()
64 | print str(Addr[0]) + " connected..."
65 | sm = Value('i', 0)
66 | p = Process(target=process, args=(Connection, 2, 33, 444, sm, info_queue, payload_queue, 5))
67 | server_process_list.append(p)
68 | perf_list.append([Addr[0], sm, p, time.time()])
69 | p.start()
70 | except socket.error:
71 | time.sleep(config.CLUSTERING_CONNECTION_RETRY_TIME)
72 |
73 |
74 | def server(host, port, exec_name, exec_list, exec_path, testcase_path, test_path, shuffle_test):
75 | global dist_process
76 | signal.signal(signal.SIGINT, signal_handler)
77 | info_queue = Queue()
78 | payload_queue = Queue()
79 | dist_process = Process(target=distributor_process, args=(host, port, info_queue, payload_queue))
80 | dist_process.start()
81 |
82 | pos = 0
83 | path_prefix = "test_generation/"
84 | exec_path_value = path_prefix + "execution.xml"
85 | if exec_path != "":
86 | exec_path_value = exec_path
87 |
88 | testcase_path_value = path_prefix + "testcase.xml"
89 | if testcase_path != "":
90 | testcase_path_value = testcase_path
91 |
92 | test_path_value = path_prefix + "test.xml"
93 | if test_path != "":
94 | test_path_value = test_path
95 |
96 | xml_tree = xml_parser(test_path_value, testcase_path_value, exec_path_value)
97 | xml_tree.calc_tests(exec_name)
98 |
99 | print "[*] Number of tests: " + str(xml_tree.get_number_of_elements())
100 | xml_tree.print_tree()
101 |
102 | while True:
103 | try:
104 | number = info_queue.get()
105 | except:
106 | break
107 | tmp = xml_tree.get_data_chunk(config.CLUSTERING_CHUNK_SIZE)
108 | try:
109 | payload_queue.put(tmp)
110 | except:
111 | break
112 | if tmp is None:
113 | break
114 | pos += len(tmp)
115 |
116 | time.sleep(5)
117 | dist_process.terminate()
118 | print "[*] Done"
119 |
--------------------------------------------------------------------------------
/process/process.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | from fileParser import *
11 | import signal
12 | import os
13 |
14 | sys.path.append(os.path.abspath('../'))
15 | import config
16 |
17 | import pdb
18 |
19 |
20 | class ForkedPdb2(pdb.Pdb):
21 | def interaction(self, *args, **kwargs):
22 | _stdin = sys.stdin
23 | try:
24 | sys.stdin = file('/dev/stdin')
25 | pdb.Pdb.interaction(self, *args, **kwargs)
26 | finally:
27 | sys.stdin = _stdin
28 |
29 |
30 | class ForkedPdb(pdb.Pdb):
31 | def interaction(self, *args, **kwargs):
32 | _stdin = sys.stdin
33 | _stdout = sys.stdout
34 | try:
35 | sys.stdin = open('/home/sergej/log/debug_pipe_in', "r")
36 | sys.stdout = open('/home/sergej/log/debug_pipe_out', "w")
37 | pdb.Pdb(None, sys.stdin, sys.stdout).set_trace()
38 | finally:
39 | sys.stdin = _stdin
40 | sys.stdout = _stdout
41 |
42 |
43 | def handle_pdb(sig, frame):
44 | print "INTERRUPT"
45 | ForkedPdb2().set_trace(frame)
46 |
47 |
48 | qemu_obj = None
49 |
50 |
51 | def signal_handler(signal, frame):
52 | global qemu_obj
53 | if qemu_obj is not None:
54 | qemu_obj.kill()
55 | sys.exit(0)
56 |
57 |
58 | qemu_obj = None
59 |
60 |
61 | def process(name, qemu, sm, worker_id, request_queue, response_queue, replay, sema, process_lock, file_postfix_name=None):
62 | global qemu_obj
63 | signal.signal(signal.SIGINT, signal_handler)
64 | signal.signal(signal.SIGUSR1, handle_pdb)
65 |
66 | log_postfix = str(worker_id)
67 | if file_postfix_name is not None:
68 | log_postfix = file_postfix_name
69 |
70 | f = open("./log/vusbf_log_" + str(worker_id), "a")
71 | f.write("\nPROCESS_ID: " + str(os.getpid()) + "\n")
72 | f.close()
73 |
74 | qemu_obj = qemu
75 | qemu_obj.set_file_name("./log/vusbf_log_" + str(worker_id))
76 | qemu_obj.start()
77 | time.sleep(1)
78 |
79 | i = 0
80 | tasks = []
81 | restore_counter = 0
82 | repair_counter = 0
83 | slow_start_counter = 0
84 | first_run = True
85 | while True:
86 |
87 | if restore_counter >= config.PROCESS_FAIL_COUNTER:
88 | # slow start exeption
89 | if not (
90 | slow_start_counter < config.PROCESS_SLOW_START_THRESHOLD and restore_counter < config.PROCESS_SLOW_START_THRESHOLD_FAIL_COUNTER):
91 | sema.acquire()
92 | restore_counter = 0
93 | repair_counter += 1
94 | slow_start_counter = 0
95 | if repair_counter >= config.PROCESS_FAIL_REPAIR_COUNTER:
96 | qemu.repair_image()
97 | #time.sleep(config.PROCESS_TIMOUT_AFTER_REPAIR)
98 | #qemu.reload()
99 | time.sleep(config.PROCESS_TIMOUT_AFTER_REPAIR)
100 | else:
101 | qemu.reload()
102 | sema.release()
103 |
104 | # Abbruchbedingung
105 | if len(tasks) == 0:
106 | request_queue.put(worker_id)
107 | tasks = response_queue.get()
108 | if first_run:
109 | process_lock.acquire()
110 | first_run = False
111 | if tasks is None:
112 | qemu_obj.kill()
113 | return
114 |
115 | tmp = tasks.pop(0)
116 | if not qemu.fire(tmp):
117 | tasks.append(tmp)
118 | restore_counter += 1
119 | continue
120 |
121 | if not qemu.log_qemu_output_select("./log/vusbf_log_" + log_postfix, str(tmp)):
122 | tasks.append(tmp)
123 | restore_counter += 1
124 | continue
125 | restore_counter = 0
126 | repair_counter = 0
127 | slow_start_counter += 1
128 | if replay:
129 | qemu.reload()
130 |
131 | qemu.check_if_image_corrupted()
132 |
133 | i += 1
134 | if i == config.PROCESS_NOTIFY_SHARED_MEMORY:
135 | sm.value += i
136 | i = 0
137 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | vusbf-Framework
2 | ===========
3 | _ __ __ __ _______ ____
4 | _ __(_)____/ /___ ______ _/ / / / / / ___// __ )
5 | | | / / / ___/ __/ / / / __ `/ / / / / /\__ \/ __ |
6 | | |/ / / / / /_/ /_/ / /_/ / / / /_/ /___/ / /_/ /
7 | |_______/ \__/\__,_/\__,_/_/ \____//____/_____/
8 | / __/_ __________ ___ _____
9 | / /_/ / / /_ /_ / / _ \/ ___/
10 | / __/ /_/ / / /_/ /_/ __/ /
11 | /_/ \__,_/ /___/___/\___/_/
12 |
13 | A KVM/QEMU based USB-fuzzing framework.
14 | Sergej Schumilo, OpenSource Security Spenneberg 2015
15 | Version: 0.2
16 |
17 | GENERAL
18 | ===========
19 |
20 | A USB-fuzzer which takes advantage of massive usage of virtual machines and also offers high reproducibility.
21 | This framework was initially released at Black Hat Europe 2014.
22 |
23 | https://www.blackhat.com/docs/eu-14/materials/eu-14-Schumilo-Dont-Trust-Your-USB-How-To-Find-Bugs-In-USB-Device-Drivers-wp.pdf
24 |
25 | This software is under heavy development. Get a copy of the actual version at github:
26 |
27 | www.github.com/schumilo
28 |
29 | This software is licensed under GPLv2.
30 |
31 |
32 | This framework provides:
33 | - USB-fuzzing in practical time frames
34 | - multiprocessing and clustering
35 | - export sequences of payloads and replay them for debugging or investigation
36 | - XML-based dynamic testcase generating
37 | - expandable by writing new testcases, USB-emulators or monitoring-modules
38 |
39 | vUSBf was written in python2 and requires the Scapy-framework.
40 |
41 | PREPARATIONS
42 | ==========
43 |
44 | First of all we've to build a compatible version of QEMU! Get the newest version of QEMU and usbredir:
45 |
46 | QEMU: http://www.qemu.org
47 | usbredir: https://github.com/SPICE/usbredir
48 |
49 | Be sure that you compile QEMU with the option "usb_redir" and you also patch the file /hw/usb/redirection.c.
50 | If you're using the QEMU version 2.1.1, you can apply our patch (qemu-2.1.1.patch).
51 | QEMU 2.2.x is currently unsupported by vUSBf!
52 |
53 | vUSBf requires some prepared QCOW2-images for fuzzing!
54 | At first you've to create a QCOW2-image for your virtual machine. You can do this by using the following command:
55 |
56 | qemu-img create -f qcow2 vm.qcow2 10G
57 |
58 | Install your preferred operating system on that image. You've to configure a TTY which is available at the (virtual) serial port.
59 |
60 | The next step is to create a backing-file (overlay which contains all of the future delta) and an image which will contain a snapshot of the VM (the size should be larger than your virtual memory you have configured):
61 |
62 | qemu-img create -b vm.img -f qcow2 overlay.qcow2
63 | qemu-img create -f qcow2 ram.qcow2 1G
64 |
65 | Start your VM with the following command, wait until the kernel is loaded, log in and change the verbosity of printk by entering "echo '7' > /proc/sys/kernel/printk".
66 | Now you can take a snapshot by entering the QEMU console (press ctrl+a and c) and type savevm . You should start the VM by the following command:
67 |
68 | qemu-system-x86_64 --enable-kvm -m 1024 -hdb ram.qcow2 -hda overlay.qcow2 -serial mon:stdio -device nec-usb-xhci -device usb-redir,chardev=usbchardev,debug=0 -chardev socket,server,id=usbchardev,nowait,host=127.0.0.1,port=1336
69 |
70 | Create a customized configuration in the "vusbf/configurations/" folder. You'll find there some examples. Modify the following information:
71 |
72 | - location of your QEMU-binary you want to use
73 | - KVM support (write yes or no)
74 | - size of your memory (the unit is MB)
75 | - location of your ram-file
76 | - location of your overlay-file
77 | - location where your overlay duplicates should be stored
78 | - configured USB-host-controller (if you have no idea just write nec-usb-xhci)
79 | - some extra parameters for QEMU (if you need some)
80 | - the name of the snapshot
81 |
82 | That's all. Now your VM is ready for some fuzzing.
83 |
84 | RUNNING VUSBF
85 | ==========
86 |
87 | Take a look at help.txt or run vusbf with the parameter -h for help :-)
88 |
89 |
90 | BUGS
91 | ==========
92 |
93 | There are some known bugs like the buggy support for Windows systems. We are working on these issues, so be sure you are using the newest version.
94 | Moreover the lack of USB-emulators is another point we are working on.
95 |
96 | Furthermore some inline comments have been written in my native language (german). They will be translated later ;-) and the code will be more documented!
97 |
98 | Comrade-in-arms are welcome :-)!
99 | There is a lot of work to do!
100 |
101 |
102 | CONTACT
103 | ==========
104 |
105 | Feel free to send us an email:
106 | schumilo@fh-muenster.de
107 | info@os-t.net
108 |
109 |
110 |
--------------------------------------------------------------------------------
/process/multi_process.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | from multiprocessing import Process, Value, Queue, Semaphore
11 | from qemu import qemu
12 | from process import process
13 | from print_performance_process import *
14 | from test_generation.XMLParser import xml_parser
15 | import signal
16 | import time
17 | import os
18 | sys.path.append(os.path.abspath('../'))
19 | import config
20 |
21 | process_list = None
22 | printPerf_process = None
23 | network_requester_process = None
24 |
25 |
26 | def signal_handler(a,b):
27 | kill_all()
28 |
29 |
30 | def kill_all():
31 | global process_list, printPerf_process, network_requester_process
32 | if process_list is not None:
33 | for p in process_list:
34 | if p.is_alive:
35 | if type(p.pid) == int:
36 | os.kill(p.pid, signal.SIGINT)
37 |
38 | if printPerf_process is not None:
39 | if printPerf_process.is_alive:
40 | if type(printPerf_process.pid) == int:
41 | os.kill(printPerf_process.pid, signal.SIGINT)
42 |
43 | if network_requester_process is not None:
44 | if network_requester_process.is_alive:
45 | if type(network_requester_process.pid) == int:
46 | os.kill(network_requester_process.pid, signal.SIGINT)
47 | sys.exit(0)
48 |
49 |
50 | def multi_processing(process_number, target_object, exec_name, exec_list, exec_path, testcase_path, test_path,
51 | reload_test, shuffle_test, payloads=None, file_name=None):
52 | global process_list
53 | global printPerf_process
54 | signal.signal(signal.SIGINT, signal_handler)
55 |
56 | path_prefix = "test_generation/"
57 | exec_path_value = path_prefix + "execution.xml"
58 | if exec_path != "":
59 | exec_path_value = exec_path
60 |
61 | testcase_path_value = path_prefix + "testcase.xml"
62 | if testcase_path != "":
63 | testcase_path_value = testcase_path
64 |
65 | test_path_value = path_prefix + "test.xml"
66 | if test_path != "":
67 | test_path_value = test_path
68 |
69 | if payloads is None:
70 | xml_tree = xml_parser(test_path_value, testcase_path_value, exec_path_value)
71 | xml_tree.calc_tests(exec_name)
72 |
73 | print "[*] Number of tests: " + str(xml_tree.get_number_of_elements())
74 | xml_tree.print_tree()
75 | else:
76 | xml_tree = payloads
77 | print "[*] Number of tests: " + str(xml_tree.get_number_of_elements())
78 |
79 | max_tasks = xml_tree.get_number_of_elements()
80 | sm_num_of_tasks = Value('i', 0)
81 |
82 | info_queue = Queue()
83 | queue_list = []
84 | process_list = []
85 | qemu_list = []
86 |
87 | process_lock = Semaphore(process_number)
88 | for i in range(process_number):
89 | process_lock.acquire()
90 | sem = Semaphore(config.PROCESS_REPAIR_SEMAPHORE)
91 |
92 | for i in range(process_number):
93 | queue_list.append(Queue())
94 | qemu_object = qemu("configurations/" + target_object, "/tmp/vusbf_" + str(i) + "_socket", i)
95 | qemu_list.append(qemu_object)
96 | if process_number == 1 and file_name is not None:
97 | process_list.append(Process(target=process, args=(
98 | "t" + str(i), qemu_object, sm_num_of_tasks, i, info_queue, queue_list[i], reload_test, sem, process_lock), kwargs={"file_postfix_name": file_name}))
99 | else:
100 | process_list.append(Process(target=process, args=(
101 | "t" + str(i), qemu_object, sm_num_of_tasks, i, info_queue, queue_list[i], reload_test, sem, process_lock)))
102 |
103 | printPerf_process = Process(target=printPerf, args=(max_tasks, sm_num_of_tasks))
104 |
105 | j = 0
106 | print "[*] Starting processes..."
107 | for e in process_list:
108 | e.start()
109 | time.sleep(0.1)
110 | print "[*] Preparing processes..."
111 | time.sleep(config.PROCESS_STARTUP_TIME)
112 | num_of_fin = 0
113 | num_of_processes = len(process_list)
114 | j = 0
115 | while True:
116 | if num_of_fin == num_of_processes:
117 | break
118 | if j == num_of_processes-num_of_fin:
119 | print "[*] Done..."
120 | printPerf_process.start()
121 | for i in range(num_of_processes):
122 | time.sleep(config.PROCESS_STARTUP_RATE)
123 | process_lock.release()
124 |
125 | process_num = info_queue.get()
126 |
127 | data = xml_tree.get_data_chunk(config.NUMBER_OF_JOBS_PER_PROCESS)
128 | if data is not None:
129 | queue_list[process_num].put(data)
130 | j += 1
131 | else:
132 | num_of_fin += 1
133 | queue_list[process_num].put(None)
134 |
135 | print "[*] Finished..."
--------------------------------------------------------------------------------
/test_generation/Testcase.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | import base64
11 | import os
12 | import sys
13 | sys.path.append(os.path.abspath('../'))
14 | import config
15 |
16 | class Testcase(object):
17 | def __init__(self, ID):
18 | self.ID = ID
19 | self.list = []
20 | self.option = {}
21 |
22 | def S(*x):
23 | if len(x) == 1 and type(x[0]) == list:
24 | x = x[0]
25 | else:
26 | x = list(x)
27 | return ListSequence(x)
28 |
29 | def add_testcase(self, *testcase):
30 | # print type(testcase[0])
31 | if len(testcase) == 1 and type(testcase[0]) == list:
32 | self.list.append(testcase[0])
33 | else:
34 | self.list.extend(testcase)
35 |
36 | def print_message(self):
37 | message = "Test #" + str(self.ID) + ":\n"
38 | message += "+---------------------------------------------------------+\n"
39 | if config.PRINT_VERBOSE_TEST_INFO:
40 | for e in self.list:
41 | message += "\t" + e.gen_info_string() + "\n"
42 | message += str(self.option) + "\n"
43 | message += "REPRODUCE_KEY:\n" + self.encode_base64() + "\n"
44 | message += "+---------------------------------------------------------+\n"
45 |
46 | return message
47 |
48 | def encode_base64(self):
49 | message = str(self.ID) + "\n"
50 | message += "\n"
51 | for e in self.list:
52 | message += e.gen_info_string().replace("FT: ", "").replace("\t", " ").replace(":", "") + "\n"
53 | message += "\n"
54 | for k in self.option.keys():
55 | message += k
56 | message += " " + self.option[k] + "\n"
57 | return base64.b64encode(message.replace(" ", "\xff"))
58 |
59 | def decode_base64(self, data):
60 | return base64.b64decode(data).replace("\xff", " ")
61 |
62 | def load_bas64_strings(self, data):
63 | data = base64.b64decode(data).split("\n\n")
64 | try:
65 | self.ID = int(data[0], 10)
66 | except:
67 | self.ID = data[0]
68 | for e in data[1].split("\n"):
69 | _tmp = e.split("\xff")
70 | if len(_tmp) == 3:
71 | self.add_testcase(Fuzzing_instruction(int(_tmp[0],10), _tmp[1], _tmp[2]))
72 | for e in data[2].split("\n"):
73 | _tmp = e.split("\xff")
74 | if len(_tmp) == 2:
75 | self.add_option(_tmp[0], _tmp[1])
76 |
77 | def get_ID(self):
78 | return self.ID
79 |
80 | def get_number_of_testcases(self):
81 | return len(self.list)
82 |
83 | def get_testcase(self, num):
84 | try:
85 | return self.list[num]
86 | except:
87 | raise Exception("Bounds exception (num=" + str(num) + ")")
88 |
89 | def get_testcases(self):
90 | return self.list
91 |
92 | def add_option(self, key, value):
93 | self.option[str(key)] = str(value)
94 |
95 | def add_options(self, hm):
96 | self.option = hm
97 |
98 | def get_option(self, key):
99 | return self.option[key]
100 |
101 | def get_options(self):
102 | return self.option.keys()
103 |
104 | def __str__(self):
105 | return self.print_message()
106 |
107 |
108 | class Instruction(object):
109 | def __init__(self):
110 | pass
111 |
112 | def gen_info_string(self):
113 | return "stub"
114 |
115 |
116 | class Fuzzing_instruction(Testcase):
117 | def __init__(self, value, field, packet_type):
118 | self.value = value
119 | self.field = field
120 | self.packet_type = packet_type
121 |
122 | def gen_info_string(self):
123 | output = "FT: "
124 | try:
125 | output += self.value + "\t"
126 | except:
127 | output += str(self.value) + "\t"
128 | output += self.field + ": " + self.packet_type
129 |
130 | return output
131 |
132 | def get_value(self):
133 | return self.value
134 |
135 | def get_field(self):
136 | return self.field
137 |
138 | def get_packet_type(self):
139 | return self.packet_type
140 |
141 | def __str__(self):
142 | return self.gen_info_string()
143 |
144 |
145 | if __name__ == "__main__":
146 | testcase = Testcase(33346)
147 | testcase.add_testcase(Fuzzing_instruction(1337, "A", "I"))
148 | testcase.add_testcase(Fuzzing_instruction("YO00", "B", "II"))
149 | testcase.add_testcase(Fuzzing_instruction(3317, "C", "III"))
150 | testcase.add_testcase(Fuzzing_instruction(12, "A", "I"), Fuzzing_instruction(21, "A", "I"))
151 | # print testcase.print_message()
152 |
153 | testcase.add_option(1, "Eins")
154 | testcase.add_option(2, "Zwei")
155 | testcase.add_option(3, "Drei")
156 |
157 | #print testcase.get_option(1)
158 | #print testcase.get_option(2)
159 | #print testcase.get_option(3)
160 | #print testcase.encode_base64()
161 | #print testcase.decode_base64(testcase.encode_base64())
162 | print testcase.print_message()
163 | t2 = Testcase(0)
164 | t2.load_bas64_strings(testcase.encode_base64())
165 | print t2
166 |
--------------------------------------------------------------------------------
/test_generation/test.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 0
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | 0
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | 0
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 | 1
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | 0
45 | 2
46 | 30
47 | 31
48 | 255
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | 0
57 | 2
58 | 30
59 | 31
60 | 255
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | 0
69 | 2
70 | 255
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 | 0
79 | 20
80 | 255
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 | 0
89 | 20
90 | 255
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | 0
99 | 137
100 | 255
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | 0
109 | 137
110 | 255
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 | 0
120 | 137
121 | 255
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 | 0
130 | 137
131 | 255
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 | 0
140 | 137
141 | 255
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 | 0
150 | 255
151 | 50000
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 | 0
160 | 255
161 | 12
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
--------------------------------------------------------------------------------
/descFuzzer.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 |
9 | from usbscapy import *
10 |
11 | def print_descriptor(descriptor):
12 | if descriptor == None:
13 | return
14 |
15 | descriptor[0].show()
16 | for confDesc in descriptor[1]:
17 | confDesc[0].show()
18 | for ifDesc in confDesc[1]:
19 | ifDesc[0].show()
20 | for e in ifDesc[1]:
21 | e.show()
22 |
23 |
24 | def patch_descriptor_length_fields(descriptor):
25 | if descriptor == None:
26 | return
27 |
28 | for configuration_num in range(len(descriptor[1])):
29 | patch_configuration_descriptor_length_field(descriptor, configuration_num)
30 |
31 |
32 | def patch_configuration_descriptor_length_field(descriptor, configuration_num):
33 | confDesc = get_configuration_descriptor(descriptor, configuration_num)
34 |
35 | conf_length = 0
36 | for ifDesc in confDesc[1]:
37 | if_length = 0
38 | for e in ifDesc[1]:
39 | if_length += e.bLength
40 | conf_length += 9 + if_length
41 | confDesc[0].wTotalLength = 9 + conf_length
42 |
43 |
44 | def get_configuration_descriptor(descriptor, configuration_num):
45 | # check Device Descriptor
46 | if descriptor == None:
47 | return None
48 | if descriptor[1] == None:
49 | return None
50 | if len(descriptor[1]) - 1 < configuration_num:
51 | return None
52 |
53 | return descriptor[1][configuration_num]
54 |
55 |
56 | def get_interface_descriptor(descriptor, configuration_num, interface_num):
57 | configuration_descriptor = get_configuration_descriptor(descriptor, configuration_num)
58 | if configuration_descriptor == None:
59 | return None
60 | if configuration_descriptor[1] == None:
61 | return None
62 | if len(configuration_descriptor[1]) - 1 < interface_num:
63 | return None
64 |
65 | return configuration_descriptor[1][interface_num]
66 |
67 |
68 | def add_new_descriptor_to_interface(descriptor, configuration_num, interface_num, new_descriptor):
69 | if new_descriptor == None:
70 | return False
71 |
72 | if not (type(new_descriptor) == usb_endpoint_descriptor or type(new_descriptor) == usb_hid_descriptor):
73 | return False
74 |
75 | interface_descriptor = get_interface_descriptor(descriptor, configuration_num, interface_num)
76 | if interface_descriptor == None:
77 | return False
78 | if interface_descriptor[1] == None:
79 | return False
80 | if interface_descriptor[0] == None:
81 | return False
82 | if interface_descriptor[0].bNumEndpoints == 255:
83 | return False
84 |
85 | if interface_descriptor[0].bNumEndpoints == None:
86 | interface_descriptor[0] = 0
87 |
88 | if type(new_descriptor) == usb_endpoint_descriptor:
89 | interface_descriptor[0].bNumEndpoints += 1
90 |
91 | interface_descriptor[1].append(new_descriptor)
92 | patch_descriptor_length_fields(descriptor)
93 |
94 | return True
95 |
96 |
97 | def add_new_interface_to_configuration(descriptor, configuration_num, new_interface):
98 | if new_interface == None:
99 | return False
100 |
101 | if not type(new_interface) == usb_interface_descriptor:
102 | return False
103 |
104 | configuration_descriptor = get_configuration_descriptor(descriptor, configuration_num)
105 | if configuration_descriptor == None:
106 | return False
107 | if configuration_descriptor[1] == None:
108 | return False
109 | if configuration_descriptor[0] == None:
110 | return False
111 | if configuration_descriptor[0].bNumInterfaces == 255:
112 | return False
113 |
114 | if configuration_descriptor[0].bNumInterfaces == None:
115 | configuration_descriptor[0].bNumInterfaces = 0
116 |
117 | configuration_descriptor[0].bNumInterfaces += 1
118 | length = len(configuration_descriptor[1])
119 | configuration_descriptor[1].append([new_interface, []])
120 | configuration_descriptor[1][length - 1][0].bInterfaceNumber = length
121 |
122 | patch_descriptor_length_fields(descriptor)
123 |
124 | return True
125 |
126 |
127 | def add_new_configuration_to_device_descriptor(descriptor, new_configuration):
128 | if new_configuration == None:
129 | return False
130 |
131 | if not type(new_configuration) == usb_configuration_descriptor:
132 | return False
133 |
134 | if descriptor == None:
135 | return False
136 | if descriptor[1] == None:
137 | return False
138 | if descriptor[0].bNumConfigurations == 255:
139 | return False
140 |
141 | if descriptor[0].bNumConfigurations == None:
142 | descriptor[0].bNumConfigurations = 0
143 |
144 | descriptor[0].bNumConfigurations += 1
145 | descriptor[1].append([new_configuration, []])
146 | patch_descriptor_length_fields(descriptor)
147 |
148 | return True
149 |
150 |
151 | def del_interface_descriptor_object(descriptor, configuration_num, interface_num, object_num):
152 | interface_descriptor = get_interface_descriptor(descriptor, configuration_num, interface_num)
153 |
154 | if interface_descriptor == None:
155 | return False
156 | if interface_descriptor[1] == None:
157 | return False
158 | if interface_descriptor[0] == None:
159 | return False
160 | if len(interface_descriptor[1]) - 1 < object_num:
161 | return False
162 |
163 | # if you delete an endpointdescriptor, you also have to decrement bEndpointNum
164 | if interface_descriptor[1][object_num].bDescriptorType == 0x05:
165 | interface_descriptor[0].bNumEndpoints -= 1
166 | del interface_descriptor[1][object_num]
167 |
168 | patch_descriptor_length_fields(descriptor)
169 |
170 | return True
171 |
172 |
173 | def del_interface_descriptor(descriptor, configuration_num, interface_num):
174 | interface_descriptor = get_interface_descriptor(descriptor, configuration_num, interface_num)
175 | if interface_descriptor == None:
176 | return False
177 |
178 | configuration_descriptor = get_configuration_descriptor(descriptor, configuration_num)
179 | configuration_descriptor[0].bNumInterfaces -= 1
180 |
181 | length = len(configuration_descriptor[1])
182 |
183 | del configuration_descriptor[1][interface_num]
184 |
185 | for i in range(length - 1 - interface_num):
186 | configuration_descriptor[1][i + interface_num][0].bInterfaceNumber -= 1
187 |
188 | return True
189 |
190 |
191 | def del_configuration_descriptor(descriptor, configuration_num):
192 | if descriptor == None:
193 | return False
194 | if descriptor[0] == None:
195 | return False
196 | if descriptor[1] == None:
197 | return False
198 |
199 | length = len(descriptor[1])
200 |
201 | if length - 1 < configuration_num:
202 | return False
203 |
204 | del descriptor[1][configuration_num]
205 |
206 | descriptor[0].bNumConfigurations = length - 1
207 |
208 | return True
209 |
--------------------------------------------------------------------------------
/test_generation/Sequence.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python
2 | """
3 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
4 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
5 | This file is part of vUSBf.
6 |
7 | See the file LICENSE for copying permission.
8 | """
9 | __author__ = 'Sergej Schumilo'
10 |
11 | class Sequence(object):
12 | def __init__(self):
13 | pass
14 |
15 | def next(self):
16 | pass
17 |
18 | def reset(self):
19 | pass
20 |
21 | def __mul__(a, b):
22 | return ProductSequence(a, b)
23 |
24 | def __add__(a, b):
25 | return ChainSequence(a, b)
26 |
27 | def __mod__(a, b):
28 | return LinkSequence(a, b)
29 |
30 | def __iter__(self):
31 | return SequenceIter(self)
32 |
33 | def __len__(self):
34 | return 12
35 |
36 |
37 | class SequenceIter(object):
38 | def __init__(self, seq):
39 | self.len_value = len(seq)
40 | self.seq = seq
41 |
42 | def next(self):
43 | n = self.seq.next()
44 | if n == None:
45 | raise StopIteration
46 | return n
47 |
48 | def __len__(self):
49 | return self.len_value
50 |
51 |
52 | class ListSequence(Sequence):
53 | def __init__(self, list):
54 | self.len_value = len(list)
55 | self.__list = list
56 | self.__pos = 0
57 |
58 | def next(self):
59 | if len(self.__list) == self.__pos:
60 | # self.reset()
61 | return None
62 | n = self.__list[self.__pos]
63 | self.__pos += 1
64 | return n
65 |
66 | def reset(self):
67 | self.__pos = 0
68 |
69 | def __len__(self):
70 | return self.len_value
71 |
72 |
73 | class GeneratorSequence(Sequence):
74 | def __init__(self, gen):
75 | self.__gen = gen
76 | self.reset()
77 |
78 | def next(self):
79 | try:
80 | return self.__g.next()
81 | except StopIteration:
82 | return None
83 |
84 | def reset(self):
85 | self.__g = self.__gen()
86 |
87 | def __len__(self):
88 | return 1
89 |
90 |
91 | class ChainSequence(GeneratorSequence):
92 | def __init__(self, *sequences):
93 | self.__sequences = []
94 | for s in sequences:
95 | if type(s) == list:
96 | s = ListSequence(s)
97 | self.__sequences.append(s)
98 | self.len_value = 0
99 | for e in self.__sequences:
100 | self.len_value += len(e)
101 | gen = lambda: self.gen_seq(self.__sequences)
102 | super(ChainSequence, self).__init__(gen)
103 |
104 | def gen_seq(self, sequences):
105 | for s in sequences:
106 | while True:
107 | e = s.next()
108 | if e == None:
109 | break
110 | yield e
111 |
112 | def reset(self):
113 | super(ChainSequence, self).reset()
114 | for s in self.__sequences:
115 | s.reset()
116 |
117 | def __len__(self):
118 | return self.len_value
119 |
120 |
121 | class LinkSequence(GeneratorSequence):
122 | def __init__(self, *sequences):
123 | self.__sequences = []
124 | for s in sequences:
125 | if type(s) == list:
126 | s = ListSequence(s)
127 | self.__sequences.append(s)
128 | self.len_value = 0
129 | for e in self.__sequences:
130 | if self.len_value == 0:
131 | self.len_value = len(e)
132 | else:
133 | if self.len_value > len(e):
134 | self.len_value = len(e)
135 | gen = lambda: self.gen_seq(self.__sequences)
136 | super(LinkSequence, self).__init__(gen)
137 |
138 | def gen_seq(self, sequences):
139 | linked_value = []
140 | while True:
141 | linked_value = []
142 | for s in sequences:
143 | var = s.next()
144 | if var == None:
145 | return
146 | linked_value.append(var)
147 | yield self.flatten(linked_value)
148 |
149 | def reset(self):
150 | super(LinkSequence, self).reset()
151 | for s in self.__sequences:
152 | s.reset()
153 |
154 | def flatten(self, x):
155 | result = []
156 | for el in x:
157 | if hasattr(el, "__iter__") and not isinstance(el, basestring):
158 | result.extend(self.flatten(el))
159 | else:
160 | result.append(el)
161 | return result
162 |
163 | def __len__(self):
164 | return self.len_value
165 |
166 |
167 | class ProductSequence(GeneratorSequence):
168 | def __init__(self, *sequences):
169 | self.__sequences = []
170 | for s in sequences:
171 | if type(s) == list:
172 | s = ListSequence(s)
173 | self.__sequences.append(s)
174 | self.len_value = 1
175 | # len
176 | for e in self.__sequences:
177 | self.len_value *= len(e)
178 | if len(sequences) == 2:
179 | gen = lambda: self.gen_seq2(self.__sequences[0], self.__sequences[1])
180 | else:
181 | gen = lambda: self.gen_seqx(self.__sequences)
182 |
183 | super(ProductSequence, self).__init__(gen)
184 |
185 | def gen_seq2(self, s1, s2):
186 | res = []
187 | while 1:
188 | e1 = s1.next()
189 | if e1 == None:
190 | break
191 | res.append(e1)
192 | s2.reset()
193 | while 1:
194 | e2 = s2.next()
195 | if e2 == None:
196 | break
197 | res.append(e2)
198 | yield self.flatten(res)
199 | res.pop()
200 | res.pop()
201 |
202 | def gen_seqx(self, sequences):
203 | seq = ProductSequence(sequences[0], sequences[1]);
204 | for n in range(2, len(sequences)):
205 | seq = ProductSequence(seq, sequences[n]);
206 | while True:
207 | res = seq.next();
208 | if res == None:
209 | break;
210 | yield self.flatten(res);
211 |
212 | def reset(self):
213 | super(ProductSequence, self).reset()
214 | for s in self.__sequences:
215 | s.reset()
216 |
217 | def flatten(self, x):
218 | result = []
219 | for el in x:
220 | if hasattr(el, "__iter__") and not isinstance(el, basestring):
221 | result.extend(self.flatten(el))
222 | else:
223 | result.append(el)
224 | return result
225 |
226 | def __len__(self):
227 | return self.len_value
228 |
229 |
230 | def S(*x):
231 | # print type(x)
232 | #if type(x) != tuple and type(x) != list:
233 | # print "EXIT"
234 | # return x
235 |
236 | if len(x) == 1 and (isinstance(x[0], Sequence)):
237 | return x[0]
238 |
239 | if len(x) == 1 and type(x[0]) == list:
240 | x = x[0]
241 | else:
242 | x = list(x)
243 | return ListSequence(x)
244 |
245 | # some testing stuff up here
246 | if __name__ == "__main__":
247 | #
248 | list1 = ['A', 'B', 'C']
249 | list2 = ['X', 'Y']
250 | list3 = ['1', '2', '3', '4']
251 |
252 | # Sequence
253 | a = S(1, 2)
254 | print "LEN:" + str(len(a))
255 | for x in a:
256 | print x
257 | print "--------------"
258 | # ChainSequence
259 | # a = S(1,2,3) * S(446) * S(list2) * S(list3)
260 | a = S(1, 2) * S(3, 4)
261 | print "LEN:" + str(len(a))
262 | for x in a:
263 | print x
264 | print "--------------"
265 |
266 | # ProductSequence
267 | a = S(1, 2) + S(3, 4)
268 | print "LEN:" + str(len(a))
269 | for x in a:
270 | print x
271 | print "--------------"
272 |
273 | # LinkSequence
274 | a = (S(1, 2) % S(3, 4))
275 | #print "-> " + str(type(a))
276 | #a = S(a)
277 | #a = S(a)
278 | #print "-> " + str(type(a))
279 | print "LEN:" + str(len(a))
280 | for x in a:
281 | print x
282 |
283 |
--------------------------------------------------------------------------------
/usbparser.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | from usbscapy import *
11 | import copy
12 |
13 | # GENERIC CLASS
14 | class parser(object):
15 | __raw = ""
16 |
17 | def __init__(self, raw):
18 | self.__raw = raw
19 |
20 | def getScapyPacket(self):
21 | return None
22 |
23 | def _getRaw(self):
24 | return self.__raw
25 |
26 | # USBREDIR PARSER (USE THIS PARSER ONLY WITH DEVICE DATA)
27 | class usbredir_parser(parser):
28 | scapyData = None
29 |
30 | def __init__(self, raw):
31 | if raw == None:
32 | raise Exception("illegal redirData")
33 | if len(raw) < 12:
34 | raise Exception("illegal redirData")
35 |
36 | parser.__init__(self,raw)
37 | self.scapyData = self.__parseRaw(raw)
38 |
39 | if len(self.scapyData) != len(raw):
40 | pass
41 | #print "ERROR " + str(len(self.scapyData)) + " " + str(len(raw))
42 | #print Raw(raw).show()
43 |
44 | def getScapyPacket(self):
45 | return self.scapyData
46 |
47 | def getScapyLayers(self):
48 | scapyLayers = []
49 | scapyLayer = copy.copy(self.scapyData)
50 |
51 | scapyLayers.append(type(scapyLayer))
52 | while scapyLayer.payload:
53 | scapyLayer = scapyLayer.payload
54 | scapyLayers.append(type(scapyLayer))
55 |
56 | return scapyLayers
57 |
58 | def modifyLayer(self, layerType, field, value):
59 | scapyLayer = self.scapyData
60 | if layerType == type(scapyLayer):
61 | setattr(scapyLayer, field, value)
62 |
63 | while scapyLayer.payload:
64 | scapyLayer = scapyLayer.payload
65 | if layerType == type(scapyLayer):
66 | setattr(scapyLayer, field, value)
67 |
68 | def __parseRaw(self, raw):
69 |
70 | header_layer = usbredirheader(raw[0:12])
71 |
72 | Htype = header_layer.Htype
73 | HLength = header_layer.HLength
74 |
75 | #if header_layer.Hid == 150761568:
76 | # print hexdump(Raw(raw))
77 | # pdb.set_trace()
78 | # print "yo"
79 |
80 | if len(raw) == 12:
81 | return header_layer
82 |
83 | specific_layer = None
84 | for layer in redir_specific_type:
85 | if Htype == layer[0]:
86 | try:
87 | specific_layer = layer[1](raw[12:HLength+12])
88 | except:
89 | pass
90 | break
91 |
92 | # UNKOWN SPECIFIC REDIR HEADER
93 | if specific_layer == None:
94 | specific_layer = Raw(raw[12:HLength+12])
95 | header_layer = header_layer / specific_layer
96 |
97 | # CONTROL DATA REDIR HEADER
98 | elif Htype == 100:
99 | if specific_layer.haslayer(Raw):
100 |
101 | # IF REPORT DESC EXIT
102 | tmp_value = ""
103 | tmp_value = specific_layer.value
104 | tmp_value = tmp_value - 8704
105 | if tmp_value < 256 and tmp_value >= 0:
106 | hid_report = usb_hid_report_descriptor(str(specific_layer.payload))
107 | specific_layer.payload = None
108 | return header_layer / specific_layer / hid_report
109 | control_layer = control_packet_parser(specific_layer.load, specific_layer.request).getScapyPacket()
110 | specific_layer[Raw] = None
111 | header_layer = header_layer / specific_layer / control_layer
112 | else:
113 | header_layer = header_layer / specific_layer
114 |
115 | # BULK DTA
116 | elif Htype == 101 and specific_layer.haslayer(Raw):
117 | raw_layer = Raw(specific_layer.load)
118 | specific_layer[Raw] = None
119 | header_layer = header_layer / specific_layer / raw_layer
120 |
121 | raw = raw[HLength+12:]
122 | if raw != "":
123 | header_layer = header_layer / Raw(raw)
124 | return header_layer
125 |
126 | # EXTRACT REQUEST TYPE
127 | # 0 : self.handle_get_status_request,
128 | # 1 : self.handle_clear_feature_request,
129 | # 3 : self.handle_set_feature_request,
130 | # 5 : self.handle_set_address_request,
131 | # 6 : self.handle_get_descriptor_request,
132 | # 7 : self.handle_set_descriptor_request,
133 | # 8 : self.handle_get_configuration_request,
134 | # 9 : self.handle_set_configuration_request,
135 | # 10 : self.handle_get_interface_request,
136 | # 11 : self.handle_set_interface_request,
137 | # 12 : self.handle_synch_frame_request
138 |
139 |
140 | # USB DESCRIPTOR PARSER (USB REDIR CONTROL DATA)
141 | class control_packet_parser(parser):
142 |
143 | scapyData = None
144 |
145 | def __init__(self, raw, index):
146 | parser.__init__(self,raw)
147 | self.scapyData = self.__parseRaw(raw, index)
148 | if self.scapyData == None:
149 | raise Exception("Unknown data exception...")
150 |
151 |
152 | def getScapyPacket(self):
153 | return self.scapyData
154 |
155 | def __parseRaw(self, data, index):
156 | if data == "":
157 | return None
158 |
159 | # GENERIC DESCRIPTOR HEADER
160 | generic_descriptor_header = usb_generic_descriptor_header(data)
161 | #print generic_descriptor_header.bLength
162 |
163 | # DEVICE DESCRIPTOR
164 | if generic_descriptor_header.bDescriptorType == 0x01 and len(data) >= 18:
165 | # IF LEN == 5 AND TYPE == 1 -> REPORT DESCRIPTOR
166 | if generic_descriptor_header.bLength < 18:
167 | return Raw(data)
168 | newlayer = usb_device_descriptor(data[0:generic_descriptor_header.bLength])
169 |
170 | # CONFIGURATION DESCRIPTOR
171 | elif generic_descriptor_header.bDescriptorType == 0x2 and len(data) >= 9:
172 | newlayer = usb_configuration_descriptor(data[0:generic_descriptor_header.bLength])
173 |
174 | # INTERFACE DESCRIPTOR
175 | elif generic_descriptor_header.bDescriptorType == 0x04 and len(data) >= 9:
176 | newlayer = usb_interface_descriptor(data[0:generic_descriptor_header.bLength])
177 |
178 | # STRING LANGID DESCRIPTOR
179 | elif generic_descriptor_header.bDescriptorType == 0x03 and index == 0 and len(data) >= 4:
180 | newlayer = usb_string_descriptor_langid(data[:generic_descriptor_header.bLength])
181 |
182 | # STRING DESCRIPTOR
183 | elif generic_descriptor_header.bDescriptorType == 0x03 and index != 0 and len(data) >= 4:
184 | newlayer = usb_string_descriptor(data[:generic_descriptor_header.bLength])
185 |
186 | # HID DESCRIPTOR
187 | elif generic_descriptor_header.bDescriptorType == 0x09 and index != 0 and len(data) >= 4:
188 | newlayer = usb_hid_descriptor(data[:generic_descriptor_header.bLength])
189 |
190 | # ENDPOINT DESCRIPTOR
191 | elif generic_descriptor_header.bDescriptorType == 0x05 and len(data) >= 7:
192 | newlayer = usb_endpoint_descriptor(data[:generic_descriptor_header.bLength])
193 |
194 | # UNKNOWN DATA
195 | else:
196 | if len(data) >= generic_descriptor_header.bLength and generic_descriptor_header.bLength != 0:
197 | newlayer = Raw(data[:generic_descriptor_header.bLength])
198 | else:
199 | newlayer = Raw(data)
200 |
201 | # NEXT LAYER
202 | if len(data) >= generic_descriptor_header.bLength and generic_descriptor_header.bLength != 0:
203 | nextLayer = self.__parseRaw(data[generic_descriptor_header.bLength:], index)
204 | if nextLayer != None:
205 | newlayer = newlayer / nextLayer
206 |
207 | return newlayer
208 |
209 | class data_bulk_parser(parser):
210 |
211 | scapyData = None
212 |
--------------------------------------------------------------------------------
/clustering/network_task_requester.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | from protocol import *
11 | import signal
12 | from threading import Lock
13 | import threading
14 | import select
15 | import config
16 |
17 | Socket = None
18 | controller = None
19 |
20 | # currently not in usage :-)
21 | def signal_handler(signal, frame):
22 | global controller
23 | if controller is not None:
24 | controller.kill_listing_thread()
25 | sys.exit(0)
26 |
27 |
28 | class network_task_requester():
29 | cancel = False
30 |
31 | def __init__(self, ip, port, md5_vm, md5_overlay, sm_num_of_fin_tasks, info_queue, data_queue, worker_id,
32 | verbose_level):
33 | self.md5_vm = md5_vm
34 | self.md5_overlay = md5_overlay
35 | self.sm_num_of_fin_tasks = sm_num_of_fin_tasks
36 | self.info_queue = info_queue
37 | self.data_queue = data_queue
38 | self.verbose_level = verbose_level
39 | self.connection_lock = Lock()
40 | self.thread = None
41 | self.worker_id = worker_id
42 |
43 | try:
44 | self.connection = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
45 | self.connection.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
46 | self.connection.connect((ip, port))
47 | except socket.error:
48 | self.__put_error_code_to_queue("server not found")
49 |
50 | self.__connect()
51 |
52 | def __connect(self):
53 |
54 | # hello packet exchange
55 | data = vusbf_proto_header()
56 | data.Length = 0
57 | data.Type = 0
58 | self.__send_data(str(data))
59 | raw_data = self.__recv_data(self.connection, 8)
60 | hello = vusbf_proto_header(raw_data)
61 | # self.print_verbose("recv hello", self.verbose_level, 2)
62 | if not (hello.Type == 0 and hello.Length == 0):
63 | self.__put_error_code_to_queue("wrong type recv")
64 |
65 | # check TODO
66 | data = self.__recv_data(self.connection, 4 + 8)
67 | header = vusbf_proto_header(data)
68 | data = self.__recv_data(self.connection, header.Length)
69 | data = vusbf_proto_header()
70 | data.Length = 1
71 | data.Type = 6
72 |
73 | extra_data = vusbf_check_response("\x01")
74 | self.__send_data(str(data) + str(extra_data))
75 |
76 | # print "DONE"
77 |
78 |
79 | def send_data_request(self, number_of_tasks):
80 |
81 |
82 | # atomic block
83 | self.connection_lock.acquire()
84 |
85 | data = vusbf_proto_header()
86 | data.Type = 1
87 | data.Length = 4
88 |
89 | extra_data = vusbf_task()
90 | extra_data.Number_of_tasks = number_of_tasks
91 |
92 | #data.show()
93 | #print len(extra_data)
94 | #extra_data.show()
95 |
96 | self.__send_data(str(data) + str(extra_data))
97 |
98 | # atomic block end
99 | self.connection_lock.release()
100 |
101 | def start_listing_thread(self):
102 | if self.thread:
103 | return
104 | self.cancel = False
105 | self.thread = threading.Thread(target=self.connection_loop, args=())
106 | self.thread.start()
107 |
108 | def kill_listing_thread(self):
109 | self.cancel = True
110 | self.thread.join()
111 | self.thread = None
112 |
113 | def close_connection(self):
114 | try:
115 | self.kill_listing_thread()
116 | except:
117 | pass
118 | self.connection.close()
119 |
120 | def connection_loop(self):
121 | while True:
122 |
123 | fd = select.select([self.connection], [], [], 0.5)[0]
124 | if self.cancel:
125 | return
126 | if fd:
127 | if len(fd) > 0:
128 |
129 | # atomic block
130 | self.connection_lock.acquire()
131 |
132 | raw_data = self.__recv_data(fd[0], 8)
133 | #raw_data = fd[0].recv(8)
134 | if len(raw_data) == 0:
135 | # atomic block end
136 | self.connection_lock.release()
137 | return
138 | header = vusbf_proto_header(raw_data)
139 | if config.CLUSTERING_DEBUG_CLIENT:
140 | header.show()
141 |
142 | # task response
143 | if header.Type == 2:
144 | #print "RESPONSE"
145 | extra_data = None
146 |
147 | # Keine Daten mehr
148 | if not header.Length == 4:
149 | raw_extra_data = self.__recv_all(fd[0], header.Length)
150 | extra_data = cPickle.loads(raw_extra_data[4:])
151 | self.__put_data_to_queue(extra_data)
152 | #print "RECV TASK RESPONSE"
153 |
154 | # sync request
155 | elif header.Type == 3:
156 | # print "RECV SYNC REQUEST"
157 |
158 | data = vusbf_proto_header()
159 | data.Type = 4
160 | data.Length = 4
161 |
162 | extra_data = vusbf_sync()
163 | extra_data.Number_of_fin_tasks = self.__get_sm_value()
164 |
165 | self.__send_data(str(data) + str(extra_data))
166 |
167 |
168 | # close connection
169 | elif header.Type == 7:
170 | #print "RECV END"
171 | # atomic block end
172 | self.connection_lock.release()
173 | return
174 |
175 | elif header.Type == None:
176 | self.connection_lock.release()
177 | return
178 |
179 |
180 | # atomic block end
181 | self.connection_lock.release()
182 |
183 | def __recv_all(self, fd, Length):
184 | data = ""
185 | recv_length = 0
186 | while True:
187 | # print len(data)
188 | data += self.__recv_data(fd, (Length - len(data)))
189 | #data += fd.recv(Length-len(data))
190 | if len(data) == Length:
191 | return data
192 |
193 |
194 | # TODO Falls die Verbindung abbricht, sollen nur noch Nones in die Queue getan werden.
195 | # Gegebenenfalls sogar ein kompletter Abbruch des Programms
196 | # z.B info_queue.put(-1) --> EXIT
197 | # geprueft wird das am besten mit send/recv Wrapper methoden die exceptions abfangen
198 | # Das gilt uebrigens fuer alle Exceptions
199 | def __recv_data(self, fd, length):
200 | try:
201 | return fd.recv(length)
202 | except:
203 | self.__put_error_code_to_queue(sys.exc_info()[0])
204 |
205 | def __send_data(self, data):
206 | try:
207 | return self.connection.send(data)
208 | except:
209 | self.__put_error_code_to_queue(sys.exc_info()[0])
210 |
211 | def __put_data_to_queue(self, obj):
212 |
213 | # negativ - also Daten einfuegen
214 | #self.info_queue.put((self.worker_id*(-1)))
215 | self.data_queue.put(obj)
216 |
217 | #self.info_queue_lock.release()
218 |
219 | def __get_sm_value(self):
220 | return self.sm_num_of_fin_tasks.value
221 |
222 | def __put_error_code_to_queue(self, err_msg):
223 | self.data_queue.put(-1)
224 | print err_msg
225 | #raise Exception(err_msg)
226 | sys.exit(0)
227 |
228 |
229 | def start_network_task_requester(server, port, md5_vm, md5_overlay, sm_num_of_fin_tasks, info_queue, data_queue, request_queue, worker_id, verbose_level):
230 | global controller
231 | signal.signal(signal.SIGTERM, signal_handler)
232 | controller = network_task_requester(server, port, md5_vm, md5_overlay, sm_num_of_fin_tasks, info_queue, data_queue, worker_id, verbose_level)
233 | #print "START"
234 | controller.start_listing_thread()
235 |
236 |
237 | # WAIT FOR REQUEST FROM MAIN PROCESS
238 | # SEND REQUEST TO MASTER
239 | # RECV DATA AND PUT THEM TO DATA QUEUE
240 | while True:
241 | value = request_queue.get()
242 | #print value
243 | #print "REQUEST"
244 | if value == 0:
245 | controller.close()
246 | break
247 | else:
248 | controller.send_data_request(value)
249 |
250 | #print "EXIT"
251 |
252 |
--------------------------------------------------------------------------------
/test_generation/XMLParser.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | ##
11 | ## Chain (a,b)(c,d) -> (a,c,b,d)
12 | ## Product (a,b)(c,d) -> (a,c)(a,d)(b,c)(b,d)
13 | ## Linked (a,b)(c,d) -> (a,c)(b,d)
14 | ##
15 |
16 | import xml.etree.ElementTree as ET
17 | from Sequence import *
18 | from Testcase import *
19 |
20 | EX_TAG = "execute"
21 | EX_NAME = "name"
22 |
23 | EX_TESTCASE_TAG = "testcase"
24 | EX_TESTCASE_TAG_NAME = "name"
25 |
26 | EX_OPTION_TAG = "option"
27 | EX_OPTION_TAG_EMUL = "emulator"
28 | EX_OPTION_TAG_DESC = "descriptor"
29 | EX_OPTION_TAG_VMRL = "reload-vm"
30 |
31 |
32 | TC_TAG = "testcase"
33 | TC_NAME = "name"
34 |
35 | TC_TU_TAG = "testunit"
36 | TC_TU_TYPE = "type"
37 | TC_TU_TYPE_P = "product"
38 | TC_TU_TYPE_S = "chain"
39 | TC_TU_TYPE_L = "linked"
40 |
41 | TC_T_TAG = "test"
42 | TC_T_NAME = "name"
43 |
44 | class xml_parser(object):
45 |
46 | def __init__(self, path_test, path_testcase, path_exec):
47 | self.test_root = self.__get_root(path_test)
48 | self.testcase_root = self.__get_root(path_testcase)
49 | self.exec_root = self.__get_root(path_exec)
50 | self.data = None
51 | self.options = {}
52 |
53 | def get_descriptor():
54 | return "desc2.txt"
55 |
56 | def get_reload():
57 | return True
58 |
59 | def get_number_of_elements(self):
60 | if self.number_of_elements == None:
61 | raise Exception("Data error!")
62 | return self.number_of_elements
63 |
64 | def get_data_chunk(self, number_of_elements):
65 | if self.data == None:
66 | raise Exception("Data error!")
67 | return_data = []
68 | new_index = 0
69 | #print len(self.data)
70 | for e in self.data:
71 | self.index += 1
72 | tmp = Testcase(self.index)
73 | tmp.add_options(self.options)
74 | #print "ADD"
75 | if type(e) == list:
76 | for i in e:
77 | tmp.add_testcase(i)
78 | else:
79 | tmp.add_testcase(e)
80 |
81 | #tmp.add_testcase(e)
82 | return_data.append(tmp)
83 | new_index = new_index + 1
84 | if new_index >= number_of_elements:
85 | #print new_index
86 | break
87 | if len(return_data) == 0:
88 | return None
89 | return return_data
90 |
91 |
92 | def reset_data():
93 | calc_tests(self.default_exec_name)
94 |
95 | def print_tree(self):
96 | if self.tree != None:
97 | print "+---------------------------------------------------+"
98 | self.__print_rec(self.tree, "")
99 | print "+---------------------------------------------------+"
100 |
101 | def __print_rec(self, list, tab_string):
102 | for e in list:
103 | if type(e) == dict:
104 | self.__print_rec(e, tab_string + "\t")
105 | next = []
106 | try:
107 | next.extend(e.get(TC_TU_TYPE_P))
108 | except:
109 | pass
110 | try:
111 | next.extend(e.get(TC_TU_TYPE_S))
112 | except:
113 | pass
114 | try:
115 | next.extend(e.get(TC_TU_TYPE_L))
116 | except:
117 | pass
118 | self.__print_rec(next, tab_string + "\t\t")
119 | else:
120 | print tab_string + e,
121 | tmp = self.build_list(e.replace("\t", ""))
122 | if tmp != None:
123 | print " [" + str(len(tmp)) + "]"
124 | else:
125 | print ""
126 |
127 | def __calc_rec(self, list, operator):
128 | data = []
129 | for e in list:
130 | if type(e) == dict:
131 | if e.get(TC_TU_TYPE_P) != None:
132 | data.append(self.__calc_rec(e.get(TC_TU_TYPE_P), TC_TU_TYPE_P))
133 | if e.get(TC_TU_TYPE_S) != None:
134 | data.append(self.__calc_rec(e.get(TC_TU_TYPE_S), TC_TU_TYPE_S))
135 | if e.get(TC_TU_TYPE_L) != None:
136 | data.append(self.__calc_rec(e.get(TC_TU_TYPE_L), TC_TU_TYPE_L))
137 | else:
138 | data.append(e)
139 |
140 | final = S()
141 | if data == None:
142 | return None
143 | else:
144 | it = iter(data)
145 | first_element = it.next()
146 | if type(first_element) == str:
147 | final = self.build_list(first_element)
148 | else:
149 | final = first_element
150 | for e in it:
151 | if type(e) == str:
152 | if operator == TC_TU_TYPE_P:
153 | final *= self.build_list(e)
154 | if operator == TC_TU_TYPE_S:
155 | final += self.build_list(e)
156 | if operator == TC_TU_TYPE_L:
157 | final = final % self.build_list(e)
158 | else:
159 | if operator == TC_TU_TYPE_P:
160 | final *= e
161 | if operator == TC_TU_TYPE_S:
162 | final += e
163 | if operator == TC_TU_TYPE_L:
164 | final = final % e
165 |
166 | return final
167 |
168 | def build_list(self, test_name):
169 | node = self.test_root
170 | for e in node:
171 | if test_name == e.attrib["name"] and e.attrib["type"] == "fuzz":
172 | for fuzz_block in e:
173 | a = None
174 | b = None
175 | c = None
176 | for values in fuzz_block:
177 | if values.tag == "packet":
178 | a = str(values.attrib["name"])
179 | #print a
180 | elif values.tag == "field":
181 | b = str(values.attrib["name"])
182 | #print b
183 | elif values.tag == "range" or values.tag == "file" or values.tag == "value":
184 | c = self.__value_parser(fuzz_block)
185 | #print c
186 | if (a != None) and (b != None) and (c != None):
187 | tmp = []
188 | for e in c:
189 | tmp.append(Fuzzing_instruction(e,b,a))
190 | tmp = S(tmp)
191 | return tmp
192 |
193 | def __read_value_from_file(self, file_name, delimiter, column, data_type):
194 | # TODO test if file exists
195 | data = []
196 | #f = open("fuzz_configuration/" + file_name)
197 | try:
198 | f = open(file_name)
199 | except:
200 | f = open("fuzz_configuration/" + file_name)
201 |
202 | try:
203 | for line in f:
204 | raw_data = line.replace("\n", "").split(delimiter)[column]
205 | if data_type == "int":
206 | data.append(int(raw_data))
207 | elif data_type == "hex":
208 | data.append(int(raw_data, 16))
209 | elif data_type == "string":
210 | data.append(raw_data)
211 | else:
212 | raise Exception("Unknown data type")
213 | finally:
214 | f.close()
215 |
216 | return data
217 |
218 | def __value_parser(self, node):
219 | packet_name = ""
220 | field_name = ""
221 |
222 | value_list = []
223 | for element in node:
224 | if element.tag == "range":
225 | a = int(element[0].text)
226 | b = int(element[1].text)
227 | if b - a <= 0:
228 | raise Exception("Range error")
229 | for i in range(b - a):
230 | value_list.append(i + a)
231 | elif element.tag == "value":
232 | value_list.append(int(element.text))
233 | elif element.tag == "file":
234 | value_list = self.__read_value_from_file(element.attrib["path"], element[0].attrib["delimiter"],int(element[0].text), element.attrib["type"])
235 | elif element.tag == "field":
236 | field_name = element.attrib['name']
237 | elif element.tag == "packet":
238 | packet_name = element.attrib['name']
239 | else:
240 | raise Exception("Unknown tag \"" + str(element.tag) + "\"")
241 | return value_list
242 |
243 |
244 | def __get_root(self, path):
245 | try:
246 | return ET.parse(path).getroot()
247 | except:
248 | raise Exception("XML Error: File not found (" + path + ")")
249 |
250 | def __testunit_parser(self, node, tab_str):
251 | final_list = []
252 | for e in node:
253 | if e.tag == TC_TU_TAG or e.tag == TC_T_TAG:
254 | if e.get(TC_TU_TYPE) == TC_TU_TYPE_P:
255 | final_list.append({TC_TU_TYPE_P: self.__testunit_parser(e, tab_str +"\t")})
256 |
257 | elif e.get(TC_TU_TYPE) == TC_TU_TYPE_S:
258 | final_list.append({TC_TU_TYPE_S: self.__testunit_parser(e, tab_str + "\t")})
259 |
260 | elif e.get(TC_TU_TYPE) == TC_TU_TYPE_L:
261 | final_list.append({TC_TU_TYPE_L: self.__testunit_parser(e, tab_str + "\t")})
262 |
263 | else:
264 | final_list.append(e.get("name"))
265 |
266 | return final_list
267 |
268 |
269 |
270 | def __testcase_parser(self, testcase_name):
271 | node = self.testcase_root
272 | for e in node:
273 | if e.tag == TC_TAG:
274 | if e.get(TC_NAME) == testcase_name:
275 | self.tree = self.__testunit_parser(e, "")
276 | self.data = self.__calc_rec(self.tree, "chain")
277 | self.number_of_elements = len(self.data)
278 | self.index = 0
279 |
280 |
281 |
282 | def __execution_parser(self, execution_name):
283 | node = self.exec_root
284 | data_list = []
285 | for execute in node:
286 | if execute.tag == EX_TAG:
287 | if execute.get(EX_NAME) == execution_name:
288 | data_list.append(execute)
289 | return data_list
290 |
291 | def __execution_parser_options(self, execution):
292 | node = execution
293 | for subelement in node:
294 | if subelement.tag == EX_TESTCASE_TAG:
295 | self.__testcase_parser(subelement.get(EX_TESTCASE_TAG_NAME))
296 |
297 | elif subelement.tag == EX_OPTION_TAG:
298 | self.options = subelement.attrib
299 | # NOT IMPLEMENTED :-)
300 | pass
301 |
302 |
303 | def calc_tests(self, exec_name):
304 | self.default_exec_name = exec_name
305 | execution = self.__execution_parser(exec_name)
306 | for e in execution:
307 | self.__execution_parser_options(e)
308 |
309 | if __name__ == "__main__":
310 | xml_tree = xml_parser("test.xml", "testcase.xml", "execution.xml")
311 | xml_tree.calc_tests("ex2")
312 | xml_tree.print_tree()
313 | print xml_tree.get_number_of_elements()
314 | i = 0
315 | while True:
316 | a = xml_tree.get_data_chunk(1000)
317 | i += 1
318 | print len(a)*i
319 | if a == None:
320 | break
321 | for e in a:
322 | print e
323 |
--------------------------------------------------------------------------------
/clustering/network_task_distributor.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | from protocol import *
11 | import select
12 | import threading
13 | from threading import Lock
14 | import cPickle
15 | import config
16 | import signal
17 |
18 | exit_flag = False
19 |
20 | controller = None
21 | timeout = 0
22 |
23 | def signal_handler(signal, frame):
24 | global timeout, controller
25 | print "SIGHANDLER"
26 | if controller is not None:
27 | try:
28 | controller.stop_sync_callback()
29 | finally:
30 | print "Exit..."
31 |
32 | class network_task_distributor:
33 | number_of_finished_tasks = 0
34 |
35 | # print some verbose stuff
36 | def print_verbose(self, data, verbose_level, verbose):
37 | if verbose_level >= verbose:
38 | print data
39 |
40 | # send synchronize request packet
41 | def synchronize(self):
42 | #print "REQ"
43 | # atomic block
44 | self.connection_lock.acquire()
45 | data = vusbf_proto_header()
46 | data.Type = 3
47 | data.Length = 0
48 | try:
49 | self.connection.send(str(data))
50 | except:
51 | # print "ERR"
52 | global exit_flag
53 | exit_flag = True
54 | self.connection_lock.release()
55 | # atomic block end
56 |
57 | self.timer = threading.Timer(self.sync_timeout, self.synchronize)
58 | self.timer.start()
59 |
60 |
61 | # constructor
62 | def __init__(self, connection, sync_timeout, md5_vm, md5_overlay, sm_num_of_fin_tasks, info_queue, data_queue,
63 | verbose_level):
64 | self.connection = connection
65 | self.sync_timeout = sync_timeout
66 | self.md5_vm = md5_vm
67 | self.md5_overlay = md5_overlay
68 | self.sm_num_of_fin_tasks = sm_num_of_fin_tasks
69 | self.info_queue = info_queue
70 | self.data_queue = data_queue
71 |
72 | self.verbose_level = verbose_level
73 | self.connection_lock = Lock()
74 |
75 | self.__connect()
76 |
77 |
78 | # init connection to client (part of the constructor)
79 | def __connect(self):
80 |
81 | # recv and response hello packet
82 | # 8Byte + 4Byte = 12Byte
83 | raw_data = self.connection.recv(8)
84 | hello = vusbf_proto_header(raw_data)
85 | self.print_verbose("recv hello", self.verbose_level, 2)
86 | if not (hello.Type == 0 and hello.Length == 0):
87 | raise Exception("Wrong type recv")
88 | self.connection.send(str(hello))
89 | self.print_verbose("send hello", self.verbose_level, 2)
90 |
91 |
92 | # send check packet and wait for response
93 | check = vusbf_proto_header()
94 | check.Type = 5
95 | # LongField x 2 = 16Byte
96 | check.Length = 16
97 |
98 | check_layer = vusbf_check_request()
99 | check_layer.MD5_VM = self.md5_vm
100 | check_layer.MD5_Overlay = self.md5_overlay
101 | self.connection.send(str(check) + str(check_layer))
102 | self.print_verbose("send check", self.verbose_level, 2)
103 |
104 | raw_data = self.connection.recv(8)
105 | check_response = vusbf_proto_header(raw_data)
106 | if not (check_response.Type == 6 and check_response.Length != 0):
107 | raise Exception("Wrong type recv")
108 | raw_data = self.connection.recv(check_response.Length)
109 | self.print_verbose("recv check", self.verbose_level, 2)
110 | if vusbf_check_response(raw_data).Test_passed == 0:
111 | raise Exception("Test not passed")
112 | self.print_verbose("connection established", self.verbose_level, 2)
113 |
114 | # wait for incoming data
115 | def connection_loop(self):
116 |
117 | while True:
118 |
119 | fd = select.select([self.connection], [], [], self.sync_timeout)
120 | fd = fd[0]
121 | if fd:
122 | if exit_flag:
123 | return
124 | if len(fd) > 0:
125 | try:
126 | # atomic block
127 | self.connection_lock.acquire()
128 |
129 | data = fd[0].recv(8)
130 | #print "DATA: "+ str(data)
131 | #print len(data)
132 | #data.show()
133 | if not len(data) == 8:
134 | # atomic block end
135 | self.connection_lock.release()
136 | break
137 | header = vusbf_proto_header(data)
138 | if config.CLUSTERING_DEBUG_SERVER:
139 | header.show()
140 |
141 | if header.Type is None:
142 | # atomic block end
143 | self.connection_lock.release()
144 | break
145 |
146 | # end
147 | elif header.Type == 7:
148 | #print "RECV END"
149 | self.connection_lock.release()
150 | break
151 |
152 | # task request
153 | elif header.Type == 1:
154 | #print "RECV TASK_REQUEST"
155 | extra_data = fd[0].recv(header.Length)
156 | header.Type = 2
157 | # self.connection.send(str(header) + extra_data)
158 |
159 |
160 |
161 | response = vusbf_proto_header()
162 | response.Type = 2
163 |
164 | reponse_extra = vusbf_task()
165 | reponse_extra.Number_of_tasks = 100
166 |
167 | response_payload = self.__request_data_from_queue()
168 | #response_payload = Raw("fdfdsggfdfgddfdgdddfdfdf")
169 | response.Length = len(str(reponse_extra)) + len(str(response_payload))
170 | #response.show()
171 | self.connection.send(str(response) + str(reponse_extra) + str(response_payload))
172 |
173 | # sync response
174 | elif header.Type == 4:
175 | extra_data = self.connection.recv(header.Length)
176 | self.__update_sm_value(vusbf_sync(extra_data).Number_of_fin_tasks)
177 | #print "RECV SYNC RESPONSE " + str(vusbf_sync(extra_data).Number_of_fin_tasks)
178 |
179 | # atomic block end
180 | self.connection_lock.release()
181 |
182 | except:
183 | print "Oops"
184 | #global exit_flag
185 | #exit_flag = True
186 | break
187 | else:
188 | print "NOPE"
189 |
190 |
191 | def start_sync_callback(self):
192 | self.timer = threading.Timer(self.sync_timeout, self.synchronize)
193 | self.timer.start()
194 |
195 |
196 | def stop_sync_callback(self):
197 | self.timer.cancel()
198 |
199 | # #### process data exchange stuff #####
200 |
201 | def __request_data_from_queue(self):
202 | self.info_queue.put(-300)
203 | data = self.data_queue.get()
204 | #data = self.data_queue
205 | #print data
206 | #print "SEND"
207 | return Raw(cPickle.dumps(data))
208 |
209 | # put request in the info_queue
210 | # wait for data from data_queue
211 | # return data object
212 | pass
213 |
214 |
215 | def __return_data_to_queue(self):
216 | # TODO LATER
217 | #self.info_queue.put()
218 | # put request in the info_queue
219 | # send data to data_queue
220 | # fin
221 | pass
222 |
223 | def __update_sm_value(self, value):
224 | self.sm_num_of_fin_tasks.value = value
225 | #self.sm_num_of_fin_tasks.value("i", value)
226 | #print "GOT " + str(value)
227 | #update sem_value :-)
228 | pass
229 |
230 |
231 | # data = fuzzer(100).gen_data(sys.argv[3], sys.argv[4])
232 |
233 | # INFO QUEUE NEGATIVE WERT -> ENTSPRICHT DER ANZAHL DER BENOETIGTEN PACKETE
234 | # WARTE AUF DATEN
235 | # RACE CONDITION MOEGLICH...DUERFTE ABER ZU KEINEN PROBLEMEN FUEHREN
236 |
237 | def process(Connection, sync_timeout, md5_vm, md5_overlay, sm_num_of_fin_tasks, info_queue, payload_queue, verbose_level):
238 | global timeout, controller
239 | signal.signal(signal.SIGTERM, signal_handler)
240 | timeout = sync_timeout
241 | if config.CLUSTERING_DEBUG_SERVER:
242 | verbose_level = 5
243 | controller = network_task_distributor(Connection, sync_timeout, md5_vm, md5_overlay, sm_num_of_fin_tasks,
244 | info_queue, payload_queue, verbose_level)
245 | controller.start_sync_callback()
246 | controller.connection_loop()
247 | #time.sleep(100)
248 | #print "EXXXX"
249 | controller.stop_sync_callback()
250 |
251 |
252 |
253 | # PROCESS KOMMUNIKATION:
254 | # Positive worker_id -> Datenanfrage
255 | # Negative worker_id -> Daten werden zurueck gegeben (communications error)
256 | # sharedmemory variable dient zum Abgleich der Anzahl der aktuell erledigen Aufgaben
257 | # Datenqueue (max_packet x max_num_of_packtes)
258 |
259 |
260 | #sync_timeout, md5_vm, md5_overlay, verbose_level)
261 |
--------------------------------------------------------------------------------
/qemu.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 |
9 | import shutil
10 | from usbEmulator import *
11 | from monitor.linux_monitor import *
12 | import config
13 |
14 |
15 | class qemu:
16 | file_name = ""
17 | config_args = ["qemu_bin", "kvm", "memory", "ram_file", "overlay_file", "device_type", "snapshot", "qemu_extra",
18 | "overlay_folder"]
19 | call = ""
20 |
21 | def __read_config(self, config_file):
22 | if not os.path.isfile(config_file):
23 | print "FILE NOT FOUND " + config_file
24 | return False
25 | f = open(config_file)
26 | try:
27 | for line in f:
28 | if not line.startswith("#") and not line == "" and ":" in line:
29 | arg = line.split(":")[0]
30 | value = line.split(":")[1].replace(" ", "").replace("\t", "").replace("\n", "").replace("\"", "")
31 |
32 | # qemu binary
33 | if arg == self.config_args[0]:
34 | if os.path.isfile(value):
35 | self.config_qemu_bin = value
36 |
37 | # kvm support
38 | elif arg == self.config_args[1]:
39 | if value == "yes" or value == "no":
40 | if value == "yes":
41 | self.config_kvm = True
42 | else:
43 | self.config_kvm = False
44 | # memory size
45 | elif arg == self.config_args[2]:
46 | if value.isdigit():
47 | self.config_memory_size = int(value)
48 | # ram file
49 | elif arg == self.config_args[3]:
50 | if os.path.isfile(value):
51 | self.config_ram_file = value
52 | # overlay file
53 | elif arg == self.config_args[4]:
54 | if os.path.isfile(value):
55 | self.config_overlay = value
56 | # usb device type
57 | elif arg == self.config_args[5]:
58 | self.config_usb_device_type = value
59 | # snapshot
60 | elif arg == self.config_args[6]:
61 | self.config_snapshot = value
62 | # qemu extra
63 | elif arg == self.config_args[7]:
64 | self.config_qemu_extra = line.split(":")[1].replace("\n", "").replace("\"", "").replace("\t",
65 | " ")
66 | # overlay folder
67 | elif arg == self.config_args[8]:
68 | # print value
69 | if os.path.isdir(value):
70 | self.config_overlay_folder = value
71 | if self.config_overlay_folder.endswith("/"):
72 | self.config_overlay_folder = self.config_overlay_folder[:-1]
73 |
74 | finally:
75 | f.close()
76 |
77 | if self.config_qemu_bin is None \
78 | or self.config_kvm is None \
79 | or self.config_memory_size is None \
80 | or self.config_ram_file is None \
81 | or self.config_overlay is None \
82 | or self.config_usb_device_type is None \
83 | or self.config_overlay_folder is None \
84 | or self.config_snapshot is None:
85 | print "READ CONFIG ERROR:"
86 | print self.config_qemu_bin
87 | print self.config_kvm
88 | print self.config_memory_size
89 | print self.config_overlay
90 | print self.config_usb_device_type
91 | print self.config_overlay_folder
92 | print self.config_snapshot
93 | return False
94 | else:
95 | return True
96 |
97 | def __gen_start_script(self, address):
98 | call = ""
99 | call += self.config_qemu_bin
100 | if self.config_kvm:
101 | call += " --enable-kvm"
102 | call += " -m " + str(self.config_memory_size)
103 | call += " -nographic"
104 | call += " -hdb " + self.config_ram_file
105 | call += " -hda " + self.config_overlay
106 | call += " -device " + self.config_usb_device_type
107 | call += " -loadvm " + self.config_snapshot
108 | call += " -serial mon:stdio"
109 | call += " -device usb-redir,chardev=usbchardev,debug=0 "
110 |
111 | if type(address) == list and len(address) == 2:
112 | call += " -chardev socket,server,id=usbchardev,port="
113 | call += str(address[1])
114 | call += ",host="
115 | call += str(address[0])
116 | call += ",nodelay,nowait"
117 | elif type(address) == str:
118 | call += " -chardev socket,server,id=usbchardev,nowait"
119 | call += ",path="
120 | call += address
121 | else:
122 | print "E"
123 | return None
124 | call += " " + self.config_qemu_extra
125 | return call
126 |
127 | # def __init__(self, config_file, log_file, data_socket, address, instance_id, verbose_level)
128 | def __init__(self, config_file, address, instance_id):
129 |
130 | self.process = None
131 | self.monitor = None
132 | self.instance_id = instance_id
133 |
134 | if not self.__read_config(config_file):
135 | raise Exception("read config error...")
136 |
137 | # copy overlay file
138 | self.config_overlay_backup = self.config_overlay
139 |
140 | if os.path.isfile(self.config_overlay_folder + "/" + config.OVERLAY_FILE_PREFIX + str(self.instance_id) + config.OVERLAY_FILE_POSTFIX):
141 |
142 | os.remove(self.config_overlay_folder + "/" + config.OVERLAY_FILE_PREFIX + str(self.instance_id) + config.OVERLAY_FILE_POSTFIX)
143 | shutil.copy(self.config_overlay,
144 | self.config_overlay_folder + "/" + config.OVERLAY_FILE_PREFIX + str(self.instance_id) + config.OVERLAY_FILE_POSTFIX)
145 |
146 | else:
147 | if config.VERBOSE_LEVEL >= config.VERBOSE_LEVEL_PRINT_INFO:
148 | print "copy overlay-file"
149 |
150 | shutil.copy(self.config_overlay,
151 | self.config_overlay_folder + "/" + config.OVERLAY_FILE_PREFIX + str(self.instance_id) + config.OVERLAY_FILE_POSTFIX)
152 |
153 | self.config_overlay = self.config_overlay_folder + "/" + config.OVERLAY_FILE_PREFIX + str(self.instance_id) + config.OVERLAY_FILE_POSTFIX
154 | self.call = self.__gen_start_script(address)
155 | if self.call is None:
156 | raise Exception("address error...")
157 |
158 | if type(address) == str:
159 | self.emu = usb_emulator(address, 1)
160 | else:
161 | self.emu = usb_emulator(address, 0)
162 |
163 | def __del__(self):
164 | if self.alive():
165 | self.kill()
166 |
167 | def start(self):
168 | self.log_reload()
169 | self.process = subprocess.Popen(filter(None, self.call.split(" ")), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
170 | time.sleep(1.0)
171 |
172 | def alive(self):
173 | if self.process is None:
174 | return False
175 |
176 | if self.process.poll() is None:
177 | return True
178 | else:
179 | return False
180 |
181 | def set_file_name(self, file_name):
182 | self.file_name = file_name
183 |
184 | def log_reload(self):
185 | if self.monitor is not None:
186 | self.monitor.log_reload()
187 |
188 | def log_qemu_output_select(self, file_name, title):
189 | try:
190 | if self.monitor is None:
191 | self.monitor = linux_monitor(self, file_name)
192 | return self.monitor.monitor(title)
193 | except:
194 | return False
195 |
196 | def kill(self):
197 | try:
198 | self.process.stdout.close()
199 | except:
200 | pass
201 | try:
202 | self.process.stdin.close()
203 | except:
204 | pass
205 | try:
206 | self.process.kill()
207 | except:
208 | pass
209 |
210 | def check_if_image_corrupted(self):
211 | fd = select([self.process.stderr], [], [], 0)
212 | fd = fd[0]
213 | if len(fd) != 0:
214 | self.repair_image()
215 | else:
216 | pass
217 | # fd[0].close()
218 |
219 | def repair_image(self):
220 | self.kill()
221 | os.remove(self.config_overlay_folder + "/" + config.OVERLAY_FILE_PREFIX + str(self.instance_id) + config.OVERLAY_FILE_POSTFIX)
222 | shutil.copy(self.config_overlay_backup,
223 | self.config_overlay_folder + "/" + config.OVERLAY_FILE_PREFIX + str(self.instance_id) + config.OVERLAY_FILE_POSTFIX)
224 | self.start()
225 |
226 | def reload(self):
227 | self.log_reload()
228 | if not self.alive():
229 | self.start()
230 | try:
231 | self.process.stdin.write("\1" + 'c' + "loadvm " + self.config_snapshot + '\n' + "\1" + 'c')
232 | except:
233 | pass
234 |
235 | def fire(self, payload):
236 | self.emu.setup_payload(payload)
237 | return self.emu.execute()
--------------------------------------------------------------------------------
/usbEmulator.py:
--------------------------------------------------------------------------------
1 | """
2 | vUSBf: A KVM/QEMU based USB-fuzzing framework.
3 | Copyright (C) 2015 Sergej Schumilo, OpenSource Security Ralf Spenneberg
4 | This file is part of vUSBf.
5 |
6 | See the file LICENSE for copying permission.
7 | """
8 | __author__ = 'Sergej Schumilo'
9 |
10 | from usbparser import *
11 | from fileParser import *
12 | from emulator.enumeration_abortion import abortion_enumeration
13 | from emulator.enumeration import enumeration
14 | from emulator.hid import hid
15 | from fuzzer import fuzzer
16 | import config
17 |
18 |
19 | class usb_emulator:
20 | port = 0
21 | ip = ""
22 | unix_socket = ""
23 |
24 | # payload specific member variables
25 | payload = []
26 | hello_packet = ""
27 | connect_packet = None
28 | if_info_packet = None
29 | ep_info_packet = None
30 | enum_emulator = None
31 |
32 | # address_type:
33 | # 0: [IP, TCP]
34 | # 1: [Unix-Socket]
35 | def __init__(self, victim_address, address_type):
36 |
37 | if victim_address is None or address_type is None:
38 | raise Exception("Victim address errror")
39 |
40 | if address_type == 0:
41 | if len(victim_address) != 2:
42 | raise Exception("Victim address error - expected format is [IP, PORT]")
43 | else:
44 | if victim_address[0] is None or victim_address[1] is None:
45 | raise Exception("Victim address error - expected format is [IP, PORT]")
46 | self.ip = victim_address[0]
47 | self.port = victim_address[1]
48 |
49 | elif address_type == 1:
50 | self.unix_socket = victim_address
51 | else:
52 | raise Exception("Unknown address type")
53 |
54 | self.hello_packet = config.USB_REDIR_HELLO_PACKET
55 |
56 | def setup_payload(self, payload):
57 |
58 | data = usbdescFileParser(config.DEV_DESC_FOLDER + payload.get_option("descriptor")).parse()
59 | self.payload = data[0]
60 | self.if_info_packet = data[3]
61 | self.ep_info_packet = data[4]
62 | self.connect_packet = data[2]
63 |
64 | fuzzer_obj = fuzzer(payload)
65 | fuzzer_obj.set_descriptor(self.payload)
66 |
67 | emulator = payload.get_option("emulator")
68 | if emulator == "enumeration":
69 | self.enum_emulator = enumeration(fuzzer_obj)
70 | elif emulator == "enumeration_abortion":
71 | self.enum_emulator = abortion_enumeration(fuzzer_obj)
72 | elif emulator == "hid":
73 | self.enum_emulator = hid(fuzzer_obj)
74 | else:
75 | raise Exception("Unknown emulator")
76 |
77 | def execute(self):
78 | connection_to_victim = self.__connect_to_server()
79 | if connection_to_victim is None:
80 | return False
81 | if connection_to_victim is None:
82 | print "Unable to connect to victim..."
83 | return False
84 | r_value = self.__connection_loop(connection_to_victim)
85 | return r_value
86 |
87 | def __get_hello_packet(self):
88 | pkt = usbredirheader()
89 | pkt.Htype = 0
90 | pkt.HLength = 68
91 | pkt.Hid = 0
92 | pkt = pkt / Raw(self.hello_packet)
93 | return str(pkt)
94 |
95 | def __get_connect_packet(self):
96 | pkt = usbredirheader()
97 | pkt.Htype = 1
98 | pkt.HLength = 10
99 | pkt.Hid = 0
100 | pkt = pkt / Raw(str(self.connect_packet))
101 | return str(pkt)
102 |
103 | def __get_if_info_packet(self):
104 | pkt = usbredirheader()
105 | pkt.Htype = 4
106 | pkt.HLength = 132
107 | pkt.Hid = 0
108 | pkt = pkt / Raw(str(self.if_info_packet))
109 | return str(pkt)
110 |
111 | def __get_ep_info_packet(self):
112 | pkt = usbredirheader()
113 | pkt.Htype = 5
114 | pkt.HLength = 160
115 | pkt.Hid = 0
116 | pkt = pkt / Raw(str(self.ep_info_packet))
117 | return str(pkt)
118 |
119 | def __get_reset_packet(self):
120 | pkt = usbredirheader()
121 | pkt.Htype = 3
122 | pkt.HLength = 0
123 | pkt.Hid = 0
124 | return str(pkt)
125 |
126 | def __connection_loop(self, connection_to_victim):
127 |
128 | connection_to_victim.settimeout(config.CONNECTION_TO_VICTIM_TIMEOUT)
129 | try:
130 | self.__print_data(self.__recv_data(80, connection_to_victim), True)
131 | self.__print_data(self.__send_data(self.__get_hello_packet(), connection_to_victim), False)
132 | self.__print_data(self.__send_data(self.__get_if_info_packet(), connection_to_victim), False)
133 | self.__print_data(self.__send_data(self.__get_ep_info_packet(), connection_to_victim), False)
134 | self.__print_data(self.__send_data(self.__get_connect_packet(), connection_to_victim), False)
135 | except:
136 | return False
137 |
138 | for _ in range(config.MAX_PACKETS):
139 | try:
140 | new_packet = usbredirheader(self.__recv_data_dont_print(12, connection_to_victim))
141 | if new_packet.Htype == -1:
142 | return True
143 | raw_data = self.__recv_data_dont_print(new_packet.HLength, connection_to_victim)
144 | raw_data = str(new_packet) + raw_data
145 | new_packet = usbredir_parser(raw_data).getScapyPacket()
146 | except:
147 | return True
148 |
149 | # hello packet
150 | if new_packet.Htype == 0:
151 | self.__print_data(str(new_packet), True)
152 | self.__print_data(self.__send_data(str(new_packet), connection_to_victim), False)
153 |
154 | # reset packet
155 | elif new_packet.Htype == 3:
156 | self.__print_data(str(new_packet), True)
157 | self.__print_data(self.__send_data(self.__get_reset_packet(), connection_to_victim), False)
158 |
159 |
160 | # set_configuration packet
161 | elif new_packet.Htype == 6:
162 | self.__print_data(str(new_packet), True)
163 | new_packet.Htype = 8
164 | new_packet.HLength = new_packet.HLength + 1
165 | new_packet.payload = Raw('\x00' + str(new_packet.payload))
166 | self.__print_data(self.__send_data(str(new_packet), connection_to_victim), False)
167 | #connection_to_victim.settimeout(0.5)
168 |
169 | # start_interrupt_receiving packet
170 | elif new_packet.Htype == 15:
171 | self.__print_data(str(new_packet), True)
172 | new_packet.Htype = 17
173 | new_packet.HLength = new_packet.HLength + 1
174 | new_packet.payload = Raw('\x00' + str(new_packet.payload))
175 | self.__print_data(self.__send_data(str(new_packet), connection_to_victim), False)
176 | return True
177 |
178 | # cancle_data_packet packet
179 | elif new_packet.Htype == 21:
180 | return True
181 |
182 | # data_control_packet packet
183 | elif new_packet.Htype == 100:
184 | # recv request
185 | self.__print_data(raw_data, True)
186 | # send response
187 | response = str(self.enum_emulator.get_response(str(new_packet)))
188 | self.__print_data(self.__send_data(response, connection_to_victim), False)
189 |
190 | # data_bulk_packet packet
191 | elif new_packet.Htype == 101:
192 | self.__send_data(response, connection_to_victim)
193 |
194 | # data_interrupt_packet packet
195 | elif new_packet.Htype == 103:
196 | new_packet.HLength = 4
197 | Raw(raw_data).show()
198 | interrupt_payload = data_interrupt_redir_header(raw_data[12:])
199 | Raw(str(new_packet) + str(interrupt_payload)).show()
200 | interrupt_payload.status = 0
201 | interrupt_payload.load = None
202 | Raw(str(new_packet) + str(interrupt_payload)).show()
203 | self.__send_data(str(new_packet) + str(interrupt_payload), connection_to_victim)
204 |
205 | else:
206 | return True
207 |
208 | return True
209 |
210 | def __print_data(self, data, recv):
211 | if config.VERBOSE_LEVEL >= config.VERBOSE_LEVEL_PRINT_RECV_DATA:
212 | print config.DELIMITER
213 | if recv:
214 | print "RECV: Type ",
215 | else:
216 | print "SEND: Type ",
217 |
218 | try:
219 | print usbredir_type_enum[usbredirheader(data).Htype]
220 | except:
221 | print usbredirheader(data).Htype
222 | try:
223 | usbredirheader(data).show()
224 | except:
225 | Raw(data).show()
226 | print ""
227 |
228 | # if verbose level 3 or higher print packet content
229 | def __recv_data(self, length, connection_to_victim):
230 | try:
231 | data = connection_to_victim.recv(length)
232 | return data
233 | except:
234 | return ""
235 |
236 | def __recv_data_dont_print(self, length, connection_to_victim):
237 | return connection_to_victim.recv(length)
238 |
239 |
240 | def __send_data(self, data, connection_to_victim):
241 | try:
242 | connection_to_victim.send(data)
243 | return data
244 | except:
245 | return ""
246 |
247 | def __print_error(self, msg):
248 | if config.VERBOSE_LEVEL >= config.VERBOSE_LEVEL_PRINT_ERROR_MESSAGES:
249 | print "ERROR:\t" + msg
250 |
251 |
252 | def __connect_to_server(self):
253 | num_of_tries = 0
254 | connection_to_victim = None
255 | while True:
256 | try:
257 | if self.unix_socket == "":
258 | connection_to_victim = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
259 | connection_to_victim.settimeout(config.UNIX_SOCKET_TIMEOUT)
260 | connection_to_victim.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
261 | connection_to_victim.connect((self.ip, self.port))
262 | else:
263 | connection_to_victim = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
264 | connection_to_victim.settimeout(config.TCP_SOCKET_TIMEOUT)
265 | connection_to_victim.connect(self.unix_socket)
266 | break
267 | except:
268 | num_of_tries += 1
269 | if config.NUMBER_OF_RECONNECTS == num_of_tries:
270 | time.sleep(config.TIME_BETWEEN_RECONNECTS)
271 | return None
272 | return connection_to_victim
--------------------------------------------------------------------------------