Changes

Jump to navigation Jump to search
1,003 bytes added ,  17:39, 26 July 2019
m
explain how superhax can be used to overwrite the boot9 vector table without an NDMA overwrite
Line 145: Line 145:  
|-
 
|-
 
| Boot9 FIRM loading doesn't blacklist memory-mapped I/O
 
| Boot9 FIRM loading doesn't blacklist memory-mapped I/O
| [[Bootloader|Boot9]]'s FIRM loading blacklists Boot9 data regions, but forgets to do other important regions, including Memory-mapped I/O. Combined with sighax, by loading a malicious FIRM section to MMIO, one can get Boot9/Boot11 code execution.
+
| [[Bootloader|Boot9]]'s FIRM loading blacklists Boot9 data regions, but forgets to do other important regions, including Memory-mapped I/O. Combined with sighax, a malicious FIRM can be used to overwrite:
 +
a) boot9 data-abort handler, coupled with a 4th section that tries to NDMA copy to NULL, causing a data abort
 +
 
 +
b) boot9 IRQ handler (this has the disadvantage that you must restore the original handler, then call it manually when your payload runs)
 
| None
 
| None
 
| New3DS
 
| New3DS
Line 153: Line 156:  
| "superhax": Boot9 FIRM loading blacklist check is flawed
 
| "superhax": Boot9 FIRM loading blacklist check is flawed
 
| Boot9 only makes sure the '''start''' and '''end''' address of each section is not covered by a blacklisted region. Thus, it is possible to overwrite blacklisted regions (e.g. ARM9 Exception Vectors) by choosing a FIRM section range that encloses an entire blacklisted region. The vulnerable code looks like this: if(blRegions[i].start <= sectionStart && blRegions[i].end > sectionStart <nowiki>||</nowiki> blRegions[i].start <= sectionEnd && blRegions[i].end > sectionEnd) return false; // failure
 
| Boot9 only makes sure the '''start''' and '''end''' address of each section is not covered by a blacklisted region. Thus, it is possible to overwrite blacklisted regions (e.g. ARM9 Exception Vectors) by choosing a FIRM section range that encloses an entire blacklisted region. The vulnerable code looks like this: if(blRegions[i].start <= sectionStart && blRegions[i].end > sectionStart <nowiki>||</nowiki> blRegions[i].start <= sectionEnd && blRegions[i].end > sectionEnd) return false; // failure
 +
The boot9 vector table (0x08000000) contains 6 entries, each 8-bytes wide (0x30 bytes); Only 0x08000000 through 0x08000040 are blacklisted, and boot9 doesn't use the region after the vector table (this is convenient because we can put any payload we want after it and not worry about overwriting chunks of boot9 code)
 +
 +
To exploit this, craft a FIRM section payload that's loaded a few bytes before 0x08000000, add padding to get to 0x08000000 and overwrite the vector table; You could overwrite the data-abort vector and craft a 4th FIRM section that causes a data-abort OR you can just overwrite the IRQ function pointer at 0x08000004 (make sure your payload replaces the original boot9 function pointer); you can point the rest of the vectors to infinite loops since they shouldn't be triggered.
 
| None
 
| None
 
| New3DS
 
| New3DS
1

edit

Navigation menu