Nmap Development mailing list archives

Re: Always practice safe software: a lesson from UnrealIRCd


From: David Fifield <david () bamsoftware com>
Date: Wed, 23 Jun 2010 17:26:44 -0600

On Tue, Jun 22, 2010 at 03:55:38PM -0500, Ron wrote:
On Tue, 22 Jun 2010 14:05:56 -0600 David Fifield
<david () bamsoftware com> wrote:
Yes, but at that point you are at least assured that your script
holds a socket. My bet is that almost all of the excessive delay is
scripts waiting for a socket. NSE only allows 20 scripts to hold a
socket at a time, so others must wait until an earlier script gives
up all its sockets. I think this waiting is what's taking up most of
the time.

There aren't any timeslices. Your script has exclusive control of the
processor until it reliquishes it with a socket operation or sleep. It
gets called back as soon as the socket operation finishes though
(unless another script is refusing to yield).

You'll only be timing the very small delay imposed by the NSE
scheduler, and not the very long delay waiting for a socket to be
free.

Sadly, the solution of starting the timer immediately after tryssl()
doesn't solve the problem (although I'm pretty sure it helps). 

I seems to help a lot. Here's a histogram of how many hosts responded in
0, 1, 2, ... seconds with the timing change. Each # stands for 2 hosts.

  0 ###########################################################################
  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 #

You can compare this with the graph before the timing change, which is
at the end of the message because it's so long.

There are peaks at 0, 6, 11, and 18 seconds. The prominent bowl between
0 and 11 seconds suggests that the timing test is working. Let's sample
each of the times and see what the times are when run individually. I
took a sample of up to five hosts for each port, then ran a separate
Nmap invocation for each host. The number on the left is the time from
the graph above, and the numbers following are the times taken for each
sampled host when re-scanned individually. -- means "Server closed
connection."

  0:  1  1  1  1  1
  1:  1  1 --  0  4
  2:  3  0  0 --  0
  3:  5 -- --  1  3
  4:  5  3  1  1  2
  5:  5 --  6  6 --
  6:  6  6  7  7  6
  7: -- 22 -- -- --
  8:  8
  9: 11 12 11 10 12
 10: 10 12 11 11 11 
 11: 11 11 11 12 11
 12: 11 12 12 11 10
 13: 12 -- 12 -- --
 14: 17 -- 13
        ...
 17: 20
 18: 20 -- 18 -- --
 19: 18 19 18 19 20
 20: -- -- -- -- 20
 21: 18
        ...
 30: 32

This looks like the initial scan was pretty accurate. Except for one
outlier that took 7 seconds in the first scan and 22 in the second, all
the times lie within 3 seconds of their original measurement. In other
words, the hosts found to be vulnerable in the parallel scan likely
really are vulnerable.

I think this is working as designed. Please commit the script with the
timing fix.

I've attached the scripts I used to run these tests. The procedure is

./nmap -n --datadir . -p 6666,6667 -iL unreal.nmap -d --script=irc-unrealircd-backdoor.nse 2>&1 | tee 
unrealircd-orig.log
./graph.py unrealircd.log
./splitscans.py unrealircd.log
for a in unreal-*.hosts; do echo $a; sh $a 2>&1 >> $a.out; done
egrep -o '(command in.*seconds|Server closed)' unreal-*.hosts.out

David Fifield

P.S. Here is the histogram before the timing change. All the times
contain roughly the same number of hosts, and the latest host took 318
seconds to respond.

  0 ##
  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 
244 #
245 #
246 #
247 #
248 ####
249 ##
250 
251 ##
252 #
253 
254 #
255 #
256 #
257 #
258 
259 ##
260 #
261 #
262 ##
263 ##
264 #
265 
266 
267 #
268 ###
269 ###
270 #
271 #
272 
273 ##
274 #
275 #
276 #
277 
278 
279 #
280 #
281 #
282 ##
283 #
284 ##
285 #
286 #
287 
288 ##
289 
290 #
291 ##
292 #
293 #
294 #
295 #
296 #
297 #
298 
299 
300 #
301 
302 ##
303 ##
304 ##
305 ##
306 ##
307 
308 #
309 #
310 #
311 
312 
313 #
314 ##
315 #
316 
317 
318 #
_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://seclists.org/nmap-dev/


Current thread: