-
Notifications
You must be signed in to change notification settings - Fork 14.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add 32-bit/64-bit RISC-V LE NOP sled modules
- Loading branch information
Showing
2 changed files
with
165 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
## | ||
# This module requires Metasploit: https://metasploit.com/download | ||
# Current source: https://github.com/rapid7/metasploit-framework | ||
## | ||
|
||
# This class implements a simple NOP generator for RISC-V 32-bit (Little Endian) | ||
class MetasploitModule < Msf::Nop | ||
|
||
def initialize | ||
super( | ||
'Name' => 'Simple', | ||
'Alias' => 'riscv32le_simple', | ||
'Description' => 'Simple NOP generator', | ||
'License' => MSF_LICENSE, | ||
'Author' => ['bcoles'], | ||
'Arch' => ARCH_RISCV32LE) | ||
register_advanced_options([ | ||
OptBool.new('RandomNops', [false, 'Generate a random NOP sled', true]) | ||
]) | ||
end | ||
|
||
def generate_sled(length, opts) | ||
badchars = opts['BadChars'] || '' | ||
random = opts['Random'] || datastore['RandomNops'] | ||
nops = [ | ||
0x00028293, # addi t0, t0, 0 | ||
0x00030313, # addi t1, t1, 0 | ||
0x00038393, # addi t2, t2, 0 | ||
0x000e0e13, # addi t3, t3, 0 | ||
0x000e8e93, # addi t4, t4, 0 | ||
0x000f0f13, # addi t5, t5, 0 | ||
0x000f8f93, # addi t6, t6, 0 | ||
] | ||
|
||
# addi x0, x0, 0 | ||
# addi x0, x0, 1 | ||
# addi x0, x0, 2 | ||
# addi x0, x0, ... | ||
# addi x0, x0, 0x799 | ||
instruction = 0x00000013 | ||
while instruction <= 0x79900013 | ||
instruction += 0x100000 | ||
nops << instruction | ||
end | ||
|
||
# Remove nops containing BadChars | ||
good_nops = [] | ||
nops.each do |nop| | ||
good_byte = true | ||
[nop].pack('V*').each_byte do |nop_byte| | ||
badchars.each_byte do |bad_byte| | ||
if nop_byte == bad_byte | ||
good_byte = false | ||
break | ||
end | ||
end | ||
break unless good_byte | ||
end | ||
good_nops << nop if good_byte | ||
end | ||
|
||
# Give up if no safe nops are available | ||
return if good_nops.empty? | ||
|
||
# Use random instructions for all NOPs | ||
if random | ||
sled = '' | ||
(length / 4).times do | ||
sled << [good_nops.sample].pack('V*') | ||
end | ||
return sled | ||
end | ||
|
||
# Use a single instruction for all NOPs | ||
return ([good_nops.sample].pack('V*') * (length / 4)) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
## | ||
# This module requires Metasploit: https://metasploit.com/download | ||
# Current source: https://github.com/rapid7/metasploit-framework | ||
## | ||
|
||
# This class implements a simple NOP generator for RISC-V 64-bit (Little Endian) | ||
class MetasploitModule < Msf::Nop | ||
|
||
def initialize | ||
super( | ||
'Name' => 'Simple', | ||
'Alias' => 'riscv64le_simple', | ||
'Description' => 'Simple NOP generator', | ||
'License' => MSF_LICENSE, | ||
'Author' => ['bcoles'], | ||
'Arch' => ARCH_RISCV64LE) | ||
register_advanced_options([ | ||
OptBool.new('RandomNops', [false, 'Generate a random NOP sled', true]) | ||
]) | ||
end | ||
|
||
def generate_sled(length, opts) | ||
badchars = opts['BadChars'] || '' | ||
random = opts['Random'] || datastore['RandomNops'] | ||
nops = [ | ||
0x40000033, # subi x0, x0, 0 | ||
0x02000033, # mul x0, x0, 0 | ||
0x02004033, # div x0, x0, 0 | ||
0x00028293, # addi t0, t0, 0 | ||
0x00030313, # addi t1, t1, 0 | ||
0x00038393, # addi t2, t2, 0 | ||
0x000e0e13, # addi t3, t3, 0 | ||
0x000e8e93, # addi t4, t4, 0 | ||
0x000f0f13, # addi t5, t5, 0 | ||
0x000f8f93, # addi t6, t6, 0 | ||
0x400282b3, # subi t0, t0, 0 | ||
0x40030333, # subi t1, t1, 0 | ||
0x400383b3, # subi t2, t2, 0 | ||
0x400e0e33, # subi t3, t3, 0 | ||
0x400e8eb3, # subi t4, t4, 0 | ||
0x400f0f33, # subi t5, t5, 0 | ||
0x400f8fb3, # subi t6, t6, 0 | ||
] | ||
|
||
# Add harmless zero register addition instructions as NOPs | ||
# addi x0, x0, 0 | ||
# addi x0, x0, 1 | ||
# addi x0, x0, 2 | ||
# addi x0, x0, ... | ||
# addi x0, x0, 0x799 | ||
instruction = 0x00000013 | ||
while instruction <= 0x79900013 | ||
instruction += 0x100000 | ||
nops << instruction | ||
end | ||
|
||
# Remove nops containing BadChars | ||
good_nops = [] | ||
nops.each do |nop| | ||
good_byte = true | ||
[nop].pack('V*').each_byte do |nop_byte| | ||
badchars.each_byte do |bad_byte| | ||
if nop_byte == bad_byte | ||
good_byte = false | ||
break | ||
end | ||
end | ||
break unless good_byte | ||
end | ||
good_nops << nop if good_byte | ||
end | ||
|
||
# Give up if no safe nops are available | ||
return if good_nops.empty? | ||
|
||
# Use random instructions for all NOPs | ||
if random | ||
sled = '' | ||
(length / 4).times do | ||
sled << [good_nops.sample].pack('V*') | ||
end | ||
return sled | ||
end | ||
|
||
# Use a single instruction for all NOPs | ||
return ([good_nops.sample].pack('V*') * (length / 4)) | ||
end | ||
end |