We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 18397
    • 3,250 Posts
    I already commited this to index.php several revisions ago.
      • 16189
      • 5 Posts
      May be I am wrong but I think that is not enough.

      I maintain some phpbb sites and took a closer look at the Perl.Sanity worm.
      http://securityresponse.symantec.com/avcenter/venc/data/perl.santy.html

      There are some GET-requests trying to execute some Perl code on the system which is characteristic for such an attack.
      Here is an example:
      p=23012&highlight=%2527%252esystem(chr(112)%252echr(101)%252echr(114)
      %252echr(108)%252echr(32)%252echr(45)%252echr(101)%252echr(32)%252echr(34)
      %252echr(112)%252echr(114)%252echr(105)%252echr(110)%252echr(116)%252echr(32)
      %252echr(113)%252echr(40)%252echr(106)%252echr(83)%252echr(86)%252echr(111)
      %252echr(119)%252echr(77)%252echr(115)%252echr(100)%252echr(41)%252echr(34))
      %252e%2527


      Because the server does urldecode that query string you will get
      p=6046&highlight='.system(perl -e "print q(jSVowMsd)").'


      You can try it at
      http://www.whoopis.com/php/decoder/index.php

      So I looked around a bit and found the cback "Stand alone CrackerTracker".
      German site: http://www.cback.de/cback_software/standalonect.php
      I now auto_prepend that to nearly all of my PHP sites and it works fine for me.
      If there is a need you can modify it very easy to work not only for $_SERVER[’QUERY_STRING’] but for all kinds of gpc variables.

      The license is GPL so I may post the origin code here:
      // Cracker Tracker Protection System
      // Created by: Christian Knerr - www.cback.de
      // Version: 2.0.0
      //
      // License: GPL
      //
      //
      // Begin CrackerTracker  StandAlone
      //
      
        $cracktrack = $_SERVER['QUERY_STRING'];
        $wormprotector = array('chr(', 'chr=', 'chr%20', '%20chr', 'wget%20', '%20wget', 'wget(',
       			       'cmd=', '%20cmd', 'cmd%20', 'rush=', '%20rush', 'rush%20',
                         'union%20', '%20union', 'union(', 'union=', 'echr(', '%20echr', 'echr%20', 'echr=',
                         'esystem(', 'esystem%20', 'cp%20', '%20cp', 'cp(', 'mdir%20', '%20mdir', 'mdir(',
                         'mcd%20', 'mrd%20', 'rm%20', '%20mcd', '%20mrd', '%20rm',
                         'mcd(', 'mrd(', 'rm(', 'mcd=', 'mrd=', 'mv%20', 'rmdir%20', 'mv(', 'rmdir(',
                         'chmod(', 'chmod%20', '%20chmod', 'chmod(', 'chmod=', 'chown%20', 'chgrp%20', 'chown(', 'chgrp(',
                         'locate%20', 'grep%20', 'locate(', 'grep(', 'diff%20', 'kill%20', 'kill(', 'killall',
                         'passwd%20', '%20passwd', 'passwd(', 'telnet%20', 'vi(', 'vi%20',
                         'insert%20into', 'select%20', 'nigga(', '%20nigga', 'nigga%20', 'fopen', 'fwrite', '%20like', 'like%20',
                         '$_request', '$_get', '$request', '$get', '.system', 'HTTP_PHP', '&aim', '%20getenv', 'getenv%20',
                         'new_password', '&icq','/etc/password','/etc/shadow', '/etc/groups', '/etc/gshadow',
                         'HTTP_USER_AGENT', 'HTTP_HOST', '/bin/ps', 'wget%20', 'uname\x20-a', '/usr/bin/id',
                         '/bin/echo', '/bin/kill', '/bin/', '/chgrp', '/chown', '/usr/bin', 'g\+\+', 'bin/python',
                         'bin/tclsh', 'bin/nasm', 'perl%20', 'traceroute%20', 'ping%20', '.pl', '/usr/X11R6/bin/xterm', 'lsof%20',
                         '/bin/mail', '.conf', 'motd%20', 'HTTP/1.', '.inc.php', 'config.php', 'cgi-', '.eml',
                         'file\://', 'window.open', '<SCRIPT>', 'javascript\://','img src', 'img%20src','.jsp','ftp.exe',
                         'xp_enumdsn', 'xp_availablemedia', 'xp_filelist', 'xp_cmdshell', 'nc.exe', '.htpasswd',
                         'servlet', '/etc/passwd', 'wwwacl', '~root', '~ftp', '.js', '.jsp', 'admin_', '.history',
                         'bash_history', '.bash_history', '~nobody', 'server-info', 'server-status', 'reboot%20', 'halt%20',
                         'powerdown%20', '/home/ftp', '/home/www', 'secure_site, ok', 'chunked', 'org.apache', '/servlet/con',
                         '<script', '/robot.txt' ,'/perl' ,'mod_gzip_status', 'db_mysql.inc', '.inc', 'select%20from',
                         'select from', 'drop%20', '.system', 'getenv', 'http_', '_php', 'php_', 'phpinfo()', '<?php', '?>', 'sql=');
      
        $checkworm = str_replace($wormprotector, '*', $cracktrack);
      
        if ($cracktrack != $checkworm)
          {
            $cremotead = $_SERVER['REMOTE_ADDR'];
            $cuseragent = $_SERVER['HTTP_USER_AGENT'];
      
            die( "Attack detected! <br /><br /><b>Dieser Angriff wurde erkannt und blockiert:</b><br />$cremotead - $cuseragent" );
          }
      
      //
      // End CrackerTracker StandAlone
      //


      P.S.: excuse my bad English
      P.P.S.: may be I should post it to the German section in German - that would be easier for me grin
        Konrad
        • 25663 MODX Staff
        • 12,272 Posts
        Konrad thanks for sharing. Can you coordinate with Netnoise who can get this to us in the proper place in our SVN repository, please. Thanks!
          Ryan Thrash, MODX Co-Founder
          Follow me on Twitter at @rthrash or catch my occasional unofficial thoughts at thrash.me
          • 16189
          • 5 Posts
          np, PN is otw. wink
            Konrad
            • 21255
            • 215 Posts
            I don’t think the "Cracker Tracker" above would make sense for MODx. I’m quite sure there is not any line in the code where GPC goes into a shell-exec. -> Still investigating... But Konrad had PM’ed me some more suggestions especially regarding the "register_globals=on"-problem that are quite interesting for MODx.
              • 32241
              • 1,495 Posts
              Nice.
              I just know about all this thing. I might need to double check all my old home-based system again.

              Thanks to both of you guys for taking care MODx security wink
                Wendy Novianto
                [font=Verdana]PT DJAMOER Technology Media
                [font=Verdana]Xituz Media
                • 21255
                • 215 Posts
                Here’s a revised version of my first hack that should now be a bit more strict and secure. Additionally it unregisters globals if register_globals is set to on (thanks to Konrad). It needs testing, so if you can, give it a try wink

                <?php
                // secure variables from outside
                // Modified 2006-04-27
                
                // Unregister globals if needed
                if (@ini_get('register_globals')) {
                  foreach ($_REQUEST as $key => $value) {
                    unset($$key);
                  }
                }
                
                // Sanitize client vars
                foreach(array('HTTP_REFERER','HTTP_USER_AGENT') as $outside) {
                  $_SERVER[$outside] = isset($_SERVER[$outside]) ? preg_replace("/[^A-Za-z0-9_\-\,\.\/\s]/", "", $_SERVER[$outside]): '';
                  if(strlen($_SERVER[$outside])>255) $_SERVER[$outside] = substr(0,255,$_SERVER[$outside]);
                }
                
                // Sanitize alias request
                if(isset($_GET['q'])) $_GET['q'] = preg_replace("/[^A-Za-z0-9_\-\.\/]/", "", $_GET['q']);
                
                // Remove modx-tags from GPC
                $modxtags = array('@<script[^>]*?>.*?</script>@si',
                                  '@&#(\d+);@e',
                                  '@\[\[(.*?)\]\]@si',
                                  '@\[!(.*?)!\]@si',
                                  '@\[\~(.*?)\~\]@si',
                                  '@\[\((.*?)\)\]@si',
                                  '@{{(.*?)}}@si',
                                  '@\[\*(.*?)\*\]@si');
                foreach(array('_GET','_POST','_COOKIE') as $gpc) {
                  foreach(${$gpc} as $key => $value) {
                    if(in_array($value,array('GLOBALS','_COOKIE','_ENV','_FILES','_GET','_POST','_REQUEST','_SERVER','_SESSION'))) {
                      unset(${$gpc}[$key]);
                    }
                    $value = str_replace(array(chr(0),chr(13)),'',urldecode($value));
                    $value = preg_replace($modxtags,'', $value);
                    ${$gpc}[$key] = $value;
                    $_REQUEST[$key] = ${$gpc}[$key];
                  }
                }
                
                ?>
                


                The <?php-tags were added for syntax highlighting only (obiously doesn’t work as it should ;-)
                  • 23879
                  • 18 Posts
                  The unregister globals part is insecure. If I call the code with, say, index.php?modx=0 and register globals was on. Then the code just deleted our $modx variable.

                  Ow, and the cleanup function is still prone to XSS. If, for example, a GPC value would contain <a onmouseover="doEvilDeeds()"> the script would fail, and I’d still be able to inject your site. (At least, as far as I can tell by looking at the code).
                    • 28042 ☆ A M B ☆
                    • 24,524 Posts
                    I do believe that the $_GET variables are still available, they are just no longer in the $_GLOBALS array.
                      Studying MODX in the desert - http://sottwell.com
                      Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
                      Join the Slack Community - http://modx.org
                      • 23879
                      • 18 Posts
                      Quote from: sottwell at Apr 27, 2006, 10:07 AM

                      I do believe that the $_GET variables are still available, they are just no longer in the $_GLOBALS array.
                      I’m boldy asuming that’s in reply to my post, so I’ll try to clear it up.

                      call with index.php?myvariable=15: (in a register_globals = on setup)
                      $myvariable = "Not 15"; // register_globals = on doesn't override this variable
                      
                      // Unregister globals if needed
                      if (@ini_get('register_globals')) {
                        foreach ($_REQUEST as $key => $value) {
                          unset($$key);
                        }
                      }
                      
                      echo $myvariable; // Should output "Not 15", output is ""