Shellcode sizes in Metasploit


When working on DNS tunneling shellcode, I was wondering how small the shellcode needed to be to work with most exploits. In case you have the same question, this is how you find out how much space, for example, all Windows exploits have, or see how many exploits a given payload will work with, although you should leave extra space for encoders. It is fairly easy to do this from outside the framework since each exploit has a line like "'Space' => 500," so I used some quick grep/awk commands. I am sure those better at bash-fu than me can provide improvements. Or it could be easily done from within the framework as well, but this is one way to do it.

How many will work with shellcode, say 500 bytes long?

$ grep -rn "'Space'" /opt/metasploit/msf3/modules/exploits/windows/ | awk '-FS' '{print $2}' | awk '-F>' '{print $2}' | awk -F, '{print $1}' | sort | ruby -e '$stdin.each {|line| puts(500 <= eval(line)) }' | sort -n | uniq -c 82 false 510 true

How much space do all the exploits allow for?

$ grep -rn "'Space'" /opt/metasploit/msf3/modules/exploits/windows/ | awk '-FS' '{print $2}' | awk '-F>' '{print $2}' | awk -F, '{print $1}' | sort | ruby -e '$stdin.each {|line| puts(eval(line)) }' | sort -n | uniq -c
1 148
1 160
1 164
1 210
1 212
1 213
1 228
1 236
5 250
1 253
3 256
1 260
1 284
1 296
3 300
2 336
1 344
1 350
2 370
1 380
1 382
1 384
1 392
26 400
1 407
1 417
2 424
1 434
1 440
7 450
1 460
1 469
1 472
2 476
2 480
2 490
1 498
35 500
25 512
1 526
12 550
26 600
1 614
1 632
1 636
1 640
10 650
1 674
1 698
8 700
1 710
1 728
22 750
1 768
38 800
1 830
4 850
1 870
1 880
1 896
5 900
3 936
1 950
1 962
1 970
1 979
1 987
58 1000
2 1012
2 1014
141 1024
1 1026
1 1104
1 1200
1 1216
1 1321
1 1456
1 1500
1 1508
1 1800
1 1871
1 1900
12 2000
36 2048
2 2052
2 2339
4 3000
1 3500
9 4000
3 4096
1 4100
1 4108
1 4150
1 4500
1 4658
1 4720
1 4724
3 5000
1 5100
1 6000
4 8000
1 10240
2 20480
1 32767

I needed to use ruby to eval the line since some of the exploits included expressions calculating exactly how large a shellcode could fit, such as "'Space' => ((1024*2)+4)," Unfortunately for those writing large shellcodes, many of those are not very specific. A lot of developers (I'm guilty too) just put in nice round numbers like 500 or 1000 and didn't test to see just how large a shellcode could actually be fit in. Frustratingly, some exploits even include random numbers in their space calculation: "'Space' => 1024 + (rand(1000)),". This is because the framework will pad payloads with nops to get them to fill the full space, and the developers wanted more randomness for evasion. I think it would make more sense if the number of nops were decided somewhere else. Who wants to rewrite a bunch of exploits?

Comments are closed.