adi003user Posted February 17, 2011 Report Posted February 17, 2011 WordPress User Photo Component Remote File Upload VulnerabilityProduct Name: User PhotoVendor: WordPress › User Photo WordPress PluginsVersions Affected: 0.9.4 and probably previous versionsSeverity: HighCredit: Sebastien Andrivet, Flora Bottaccio, ADVtools.comWebsite: ADVtools - Les experts en sécurité informatiqueContact: advisories () advtools comDate: 2011-02-17I. Product DescriptionUser Photo is a WordPress component that allows a user to associate aphoto with her account and for this photo to be displayed in postsand comments.II. Vulnerability descriptionWhen a photo is uploaded, it is only partially validated and it ispossible to upload a backdoor on the server hosting WordPress. Thisbackdoor can be called (executed) even if the photo has not been yetapproved.III. Analysis1. Image type validationWhen a file is uploaded, its type is validated. Only the followingtypes are accepted: $userphoto_validtypes = array( "image/jpeg" => true, "image/pjpeg" => true, "image/gif" => true, "image/png" => true, "image/x-png" => true );The type is validated by the following code: if(@!$userphoto_validtypes[$_FILES['userphoto_image_file']['type']]) $error = sprintf(__("The uploaded file type “%s” is notallowed.", 'user-photo'), $_FILES['userphoto_image_file']['type']);This code verifies the MIME type of the uploaded file. A navigatorinfers the MIME type from the file itself or from its extension but itis possible to intercept the HTTP request and change it (using a proxysuch as WebScarab). This way, any file can be uploaded as if it werean image. The HTTP header to change is Content-type:Content-type: image/gif2. Image resizingWhen a photo (an image) is uploaded, its size is checked. If it is toobig, it is resized. To avoid this resizing, the uploaded file has tolook like a small image. The verification of the size of the image isdone with code such as: $imageinfo = getimagesize($tmppath);In the case of GIF, this PHP function simply looks at the beginning ofthe GIF header and extracts the size of the image. A GIF header startswith:Offset Length Contents 0 3 bytes "GIF" 3 3 bytes "87a" or "89a" 6 2 bytes <Logical screen width in little-endian byte order> 8 2 bytes <Logical screen height in little-endian byte order>getimagesize ignores the remaining of the binary data. It is thus easyto create a file that looks like a small GIF image but that is in factsomething else.3. PHP fileA PHP file can contain binary data. This data are reflected on theoutput steam without interpretation. Only data between <?php and ?>are interpreted as PHP code (seePHP: Escaping from HTML - Manual). Usingthis characteristic and the previous point, it is thus possible toconstruct a file that looks like a small GIF image but that is in facta PHP file. For example (in hexadecimal): 47 49 46 38 39 61 14 00 14 00 3C 3F 70 68 70 20 70 68 70 69 6E 66 6F28 29 3B 20 3F 3EThis file is recognized as a GIF image with a width and a height of 20pixels and also as a PHP file containing a call to phpinfo(). Usingthe same technic, it is possible to upload a backdoor.4. UploadingOnce uploaded, the PHP file is always located at the same place: wp-content/uploads/userphoto/alice.phpwhere alice is the login name (nickname) of the user uploading the file.Important: This file is present even if it has not yet been approvedby the moderator.5. LimitationSince the PHP file begins with a fake GIF header, this header will beoutput for every response. In practice, this is not really a problem:it can be simply ignored (in the case of a backdoor outputting HTML)or manually removed (in the case of the downloading of file). In somecases (for example when images are dynamically returned), a backdoorhas to be slightly modified to avoid outputting two GIF headers.6. Special caseIn some installations, PHP files are interpreted as Unicode (16 bits).Since the beginning of the GIF header is 16-bit aligned, it is not anissue. The PHP code has to be written in Unicode.7. Other concernsThis component contains also a XSS vulnerability located in the samelines of code.IV. Versions affectedVersion 0.9.4 (latest version as of January 2011).Other versions were not tested.V. ImpactThe exact impact depends of the configuration of the web server and ofthe operating system:- In the worst case, if Apache is running as root or as anAdministrator, the server is compromised (owned).- If the Apache server is running as a dedicated low privilege user,the backdoor will have limited access. Most of the time, the backdoorwill have read access but no write access except in very specificplaces. To compromise the server, another vulnerability is necessary(escalation).VI. Proof of concept / ExploitSee part III.VII. Mitigation, Workaround and fixThe hardening of the web server will limit the impact.VIII. Disclosure time-line2010.07 First researches, vulnerability discovered2011.01.24 Proof of concept2011.01.27 Vendor notified2011.02.17 Public disclosureIX. ReferencesGraphics Interchange FormatGraphics Interchange Format - Wikipedia, the free encyclopediaGIF specificationhttp://www.w3.org/Graphics/GIF/spec-gif89a.txtPHP Escaping from HTMLPHP: Escaping from HTML - ManualPassing Malicious PHP Through getimagesize()Passing Malicious PHP Through getimagesize() ha.ckers.org web application security labPHP Exploit Code in a GIFPHP Exploit Code in a GIF_______________________________________________Full-Disclosure - We believe in it.Charter: [Full-Disclosure] Mailing List CharterHosted and sponsored by Secunia - Secunia.com Quote