login
(破解人數(shù):12)
描述:登陸后有驚喜
http://218.76.35.75:20115
關(guān)鍵代碼在于 :
<?php
$login=@$_POST['login'];
$password=@$_POST['password'];
if(@$login=="admin" && sha1(@$password)==$pwhash){
include('flag.txt');
}else if (@$login&&@$password&&@$_GET['debug']) {
echo "Login error, login credentials has been saved to ./log/".htmlentities($login).".log";
$logfile = "./log/".$login.".log";
file_put_contents($logfile, $login."\n".$password);
}
?>
<center>
login<br/><br/>
<form action="" method="POST">
<input name="login" placeholder="login"><br/>
<input name="password" placeholder="password"><br/><br/>
<input type="submit" value="Go!">
</form>
</center>
可以看到這里會(huì)將登錄失敗的用戶名和密碼以以下的形式寫入到日志文件中
file_put_contents($logfile, $login."\n".$password);
在文件包含的時(shí)候在 include 的參數(shù)后添加了 .php
這種情況在php版本高于 5.3 的時(shí)候是無法使用 %00 來截?cái)嗟?br>
因此只能通過一些 php 的擴(kuò)展協(xié)議來構(gòu)造結(jié)尾為 .php 的包含參數(shù)
if(@$_GET['page'] != 'index'){
include((@$_GET['page']?$_GET['page'].".php":"main.php"));
}
思考 :
如果這個(gè)題目的寫文件的代碼是這樣的 , 能否繼續(xù) get shell :
file_put_contents($logfile, $login." => (Login Failed) => ".$password);
分析 :
區(qū)別在于 , 原本用戶名和密碼之間添加了一個(gè)換行符 , 然后構(gòu)造成文件內(nèi)容再寫入文件
但是現(xiàn)在并不是一個(gè)簡(jiǎn)單的單字符 , 而是一個(gè)字符串
我想到了一個(gè)方法 , 前提是已知日志文件的構(gòu)造方式
如果我們可以拿到日志文件的結(jié)構(gòu) , 也就是已知
=> (Login Failed) =>
然后我們可以構(gòu)造一個(gè)壓縮包 , 這個(gè)壓縮包里面一個(gè)文件是這個(gè)字符串的內(nèi)容 , 另一個(gè)文件的內(nèi)容即為 webshell
測(cè)試 :
# 目錄結(jié)構(gòu)
upload ?? tree
.
├── include.php
├── index.php
├── test
│ ├── content
│ ├── c.php
│ └── c.zip
└── upload
2 directories, 5 files
// index.php
<?php
$prefix = $_GET['prefix'];
$suffix = $_GET['suffix'];
$file = $_GET['file'];
$content = $prefix.' => (Login Failed) => '.$suffi;
echo $content;
file_put_contents('upload/'.$file, $content);
// include.php
<?php
include($_GET['file']);
接下來構(gòu)造 zip 包
可以看到如果使用 zip 去無密碼壓縮一個(gè)文本文件 , 這個(gè)文本文件的內(nèi)容是直接明文存儲(chǔ)的
因此我們只需要截取用戶名為字符串
%50%4b%03%04%0a%00%02%00%00%00%f7%75%0f%4b%78%64%d6%08%17%00%00%00%17%00%00%00%07%00%1c%00%63%6f%6e%74%65%6e%74%55%54%09%00%03%12%99%92%59%16%99%92%59%75%78%0b%00%01%04%00%00%00%00%04%00%00%00%00
之前的部分
然后密碼為之后的部分就可以了
其實(shí)基本上思路和之前的 WriteUP 類似
正常使用 zip 協(xié)議去包含這個(gè)文件即可
其實(shí)可以看到這里文件名的明文數(shù)據(jù)也是直接在 zip 文件里面的
那么事實(shí)上文件名也可以作為分隔符
最后經(jīng)過測(cè)試發(fā)現(xiàn) , 其實(shí)這個(gè)文件內(nèi)容并不需要和之前日志文件的分隔符相同 , 只需要內(nèi)容長(zhǎng)度相同即可
具體還需要了解 zip 壓縮文件的格式
成功寫入日志文件以后 , 如果日志文件 web 可以直接下載 , 可以下載下來測(cè)試一下
如果可以正常解壓 , 即可直接包含得到 shell
漏洞限制 :
總結(jié)一下這個(gè)漏洞利用的條件
1. 日志文件路徑已知
2. 日志文件首尾可控
3. 首尾長(zhǎng)度無限制
4. 文件內(nèi)容中不可控的區(qū)域長(zhǎng)度已知
參考資料 :
應(yīng)該還有很多的 php 協(xié)議可以用來繞過這些限制
等以后有時(shí)間再慢慢研究