題目:php是世界上最好的語言1
介紹:php是世界上最好的語言網址,(http://way.nuptzj.cn/php/index.php)
1,我們打開頁面,說是 Can you authenticate to this website? index.txt,把index.php改成index.txt,然后我們可以看到了php代碼。
2,php代碼:<?php if(eregi("hackerDJ",$_GET[id])) { echo("<p>not allowed!</p>"); exit(); } $_GET[id] = urldecode($_GET[id]); if($_GET[id] == "hackerDJ") { echo "<p>Access granted!</p>"; echo "<p>flag: *****************} </p>"; } ?> ,這道題目的問題在於urldecode(),我們可能認為傳遞過來的$_GET[id]沒有進行url編碼,但是實際上已經經過了url的編碼。那么這道題目只需要將id=hackerDJ進行兩次url編碼即可。
題目:php是世界上最好的語言2
介紹:php是世界上最好的語言,這道題考察php弱類型,網址(http://45.63.58.62:8088/xedni.php)
1,首先我們查看源代碼,可惡意看到php代碼:<?php if(isset($_GET["password"]) && md5($_GET["password"]) == "0") echo file_get_contents("/opt/flag.txt"); else echo file_get_contents("xedni.php"); ?> ,我們看到是兩個 == ,(在php里面 ==
比較只比較值,不同類型會轉換為同一類型比較。要比較類型用 ===
,必須值和類型都一樣才為true)
2,然后就是md5怎么得到0的問題,我們知道這個知識點下面就知道怎么做了,我們直接在百度上面找(s878926199a、240610708、QNKCDZO、aabg7XSs、aabC9RqS這幾個是我找的,可以用),現在都解決了,
3,我們在原頁面輸入:?password=s878926199a,這樣就能夠得到flag了。
接着再給你們來幾個這樣的題
題目:天網管理系統
介紹:網址(http://ctf5.shiyanbar.com/10/web1/)
1,打開網址后,里面用戶名和密碼都是admin,點擊“登入系統”也沒用。做web的php題如果知道源代碼就事半功倍,先右鍵查看源代碼,得到先查看源代碼,發現<!-- $test=$_GET['username']; $test=md5($test); if($test=='0') -->,
2,這里要求我們輸入一個字符串,經過md5后等於0,這是考驗php弱類型。這里我提供4個都可以通過的值:240610708、QNKCDZO、aabg7XSs、aabC9RqS
3,只要在用戶名那里輸入上面4個值中的任意一個,就會得到提示:/user.php?fame=hjkleffifer4,毫無疑問,我們訪問一下,可以看到代碼:$unserialize_str = $_POST['password']; $data_unserialize = unserialize($unserialize_str); if($data_unserialize['user'] == '???' && $data_unserialize['pass']=='???'){ print_r($flag); } #偉大的科學家php方言道:成也布爾,敗也布爾。 回去吧騷年, 這代碼不難懂,就是把post提交的password值經過"反序列化"(不懂的百度吧,搜一下php手冊關於unserialize()函數的知識)得到一個數組,要求數組里的user和pass都滿足就打印flag,這里由於我們不知道兩處???到底是什么,我們只得另辟途徑,從php弱類型入手,
5,bool類型的true跟任意字符串可以弱類型相等,而當代碼中存在unserialize()的時候,我們可以構造bool類型,來達到欺騙。現在我們要的是一個數組,2個元素,分別是user和pass,而且值都是bool類型的true,於是我們得到 a:2:{s:4:"user";b:1;s:4:"pass";b:1;},這是反序列化,這里我詳細解釋一下吧,
以后就不解釋了(a代表array,s代表string,b代表bool,而數字代表個數/長度),所以這里的a代表數組array,2代表有兩個參數 user和pass,s代表user是字符串,4,代表user字符串長度是4,b代表是bool類型的,1代表是真。這里面不同的類型用:和;分割開。6,返回最開始的網頁,輸入上面寫的賬號密碼,登入即可得到flag。
說到反序列化,我又想起來一個題
題目:PHP反序列化
介紹:網址(http://115.28.150.176/php1/index.php)(不知道這個網址現在怎么打不開了,你們知道題型就好)1,這個我們首先會看到代碼,<?php class just4fun { var $enter; var $secret; } if (isset($_GET['pass'])) { $pass = $_GET['pass']; if(get_magic_quotes_gpc()){ $pass=stripslashes($pass); } $o = unserialize($pass); if ($o) { $o->secret = "*"; if ($o->secret === $o->enter) echo "Congratulation! Here is my secret: ".$o->secret; else echo "Oh no... You can't fool me"; } else echo "are you trolling?"; } ?>
聲明了一個類,這個類里面包含有$enter
,$secret
兩個成員,先把傳入的$pass參數反序列化,並傳參給$o。如果$o->secret === $o->enter
,那么久輸出所謂的秘密,也就是o->secret。
2,首先獲取我們傳入的參數,進行反序列化;給$o中的secret賦值;比較$o->secret和$o->enter是否相等。注意這里是 '==='。3,在 PHP 中普通的傳值賦值行為有個例外就是碰到對象 object 時,在 PHP 5 中是以引用賦值的,除非明確使用了 clone 關鍵字來拷貝,PHP 支持引用賦值,使用“$var = &$othervar;”語法。引用賦值意味着兩個變量指向了同一個數據,沒有拷貝任何東西。4,知道上面所說的,我們就可以把上面的代碼改一下了:<?php class just4fun { var $enter; var $secret; } $o = new just4fun(); $o->enter = &$o->secret; //這里是重點。我們使用引用傳參的特點,讓$o->secret的值和$o->enter的值,這樣兩個變量就永遠相等了 echo serialize($o); ?>
5,序列化字符串為: O:8:"just4fun":2:{s:5:"enter";N;s:6:"secret";R:2;},自己在本地運行代碼得到下面圖
6,然后把這些復制下來提交后得到flag:nctf{serialize_and_unserialize}。
ps:詳細請參考(http://115.159.210.46/archives/19.html),我也是參考的這個。