Hey, that's my first submission so don't expect anything spectacular. There are a few bugs in Easynews 1.5: Short Description: Easynews 1.5 - database and templates remotly modifieable, cross site scripting, local users gain admin pass, and stuff :) Found by: markus arndt<markus-arndt@web.de> Vendor: http://easyscripts.power-gaming.de/index.php?page=easynews Notified Vendor: Yepp Vulnerable: Webservers that run Easynews 1.5 (maybe older versions) Overview: 1. Modify Newsdatabase 2. Modify Templates 3. Cross site scripting attacks 4. Local Web path 1. Modify ".dat" files remotly through Easynews 1.5 In Easynews the visitors are able to leave comments refering to topics posted by the admin. Let's see how easynews saves this comment: ---cut--- function save($datei, $eintragen) { $fp = fopen($datei, "w"); fwrite($fp, $eintragen); fclose($fp); } if($name&&$email&&$kommentar) { $message = "<font face=\"Verdana, Arial, Sans-Serif\" size=\"2\"><center>Vielen Dank für Ihren Kommentar!<br><br><a href=\"$PHP_SELF?action=comments&id=$id&cid=$cid\">Zurück zu den Kommentaren</a><center></font>"; if(!file_exists("./kommentare/$cid.dat")) save("./kommentare/$cid.dat",""); $line = file("./kommentare/$cid.dat"); $line[sizeof($line)] = "$name,$email,$datum,$zeit,$kommentar\n"; save("./kommentare/$cid.dat",implode("",$line)); } ---cut--- $cid is normaly declared in the form that the user has to fill out: <form action="/index.php?action=comments&do=save&id=1&cid=1002526038" method="post"> This is V-E-R-Y B-A-D, because a remote user is then able to declare his own $cid (in the url)!! If we have "test" as a value for $cid, the script would save the comment in "./kommentare/test.dat". But if $cid is set to "../news" the script would write into "./kommentare/../news.dat" and this is the Newsdatabase of Easynews! Because the The url to make that would look like: http://[tar get]/index.php?action=comments&do=save&id=1&cid=../news&name=<date>&kommenta r=%20&email=<user>&zeit=<messagetext>,<time>,../news,<email>&datum=<headline > or http://[target]/index.php?action=comments&do=save&id=1&cid=../news&name=11/1 1/11&kommentar=%20&email=hax0r&zeit=you%20suck,11:11,../news,bugs@securityal ert.com&datum=easynews%20exploited The url may seem a bit strange (name=<date>), but this is because the newsdatabase has a different fomat then the files that store the comments. This way you can add posts to the newsdatabase (they will appear at the bottom). 2. Modify Template remotely The same as above, the difference is that the Templates are stored in "template.dat". If you undestand the above example you should be able to do this yourself. 2. Cross site scripting Let's go on.. Another securityhole is the cross site scripting. This can be done by createing a newspost as descriped in part 1 that contains javascript. e.g. : http://[target]/index.php?action=comments&do=save&id=1&cid=../news&name=11/1 1/11&kommentar=%20&email=hax0r&zeit=<img src=javascript:alert(document.title)>,11:11,../news,bugs@securityalert.com&d atum=easynews%20exploited This would add a post that popups an anarm message to a visitor. Attackers can create scripts that steal cookies that are meant for the vulnerable server (internet explorer 5.5/6.0), or create fake login forms, and so on... The only disadvantage for cross site scripting is that the script turns the symbold " and ' into \" and \' , so we can't do things like: alert("hi") because it would end up in alert(\"hi\") . 2. Local users may be able to find out the Easynews administration password The Administration Password is stored in "settings.php" in plain text(no encryption, nothing)!!! This means that local users may be able to view the administrators password. Another possibility to gain the pass is that users hosted on the same server read the file through cgi scripts. 4. Find out the servers webroot directory Well.. Let's come to the end. The last bug is that the script tells remote users what the servers web dir is. Let's see some code: ---cut--- if(!isset($number)) $number = 0; if(file_exists($datei)) { $line = file($datei); $linen = sizeof($line); for($i=$number;$i < $number+$maxentries;$i++) ---cut--- What does it do? It reads in the database stored in a text file declared in $datei and then starts a loop in order to print it out. The variable $number is contains the number of the first entry that will be shown (e.g. 0 for the first entry), and the variable $maxentrys contains the number of entrys to be shown (e.g. 10 to show 10 entrys on the page). The variable $number (also $maxentries) has to be declared by the remote user, but if he doesn't declare it in the url, it will be automaticly declared to 0. That's because the user should be able to set his own entry that that he wants to view first. If we put in some number the script will work fine, but what will happen if we put in something else like "Q" ? The script will get to this line: for($i=$number;$i < $number+$maxentries;$i++) It will then stop (of course it can't execute the loop Q times, because Q is not an integer) and after the timeout (usually 30 secs) it will quit with an error message containing the server's web directory: Fatal error: Maximum execution time of 30 seconds exceeded in /home/httpd/vhosts/our_target/index.php on line 141 That's all folks :) Markus Arndt markus-arndt@web.de