======================================
个人收获:
1.SQL注入语句中用/**/代替空格 (虽然之前就知道)
=========================================
题目界面:
常规的点击连接查看页面看到接下来几个页面
没有什么特别的发现,同时也查看了网页的源码也没有什么发现。
然后拿出burp挂上代理看看 网页的详细访问内容
发现3个302跳转
我们都把他们发送到repeater里面重发一边看看详细内容
其中2个都一样没什么用,有用的是这个302
尝试修改name发送回去会返回以下内容
告诉你语句了,想让你SQL注入吧,然后我利用SQLMAP进行POST注入无果,自己手动进行测试
发现过滤了空格,过滤 ' 会转移为\' 同时对username的长度还进行了限制
但是幸运的#并没有被过滤掉,但是接下来还是没什么头绪
看了别人的writeup才知道还有个源码泄露 (回过头来看我想绕过SQL注入真的经验丰富的人可能直接得出flag)
然后我用源码泄露文件扫描脚本进行扫描
下载地址:https://github.com/langzi98/scan-backup-langzi-
是一个svn泄露
然后我们用利用工具把它的源文件弄出来
利用工具下载地址:
https://github.com/kost/dvcs-ripper
放在kali中进行恢复
然后就恢复出这些文件
然后对他们进行源代码审计
首先我看到这个
isset检查session是否为设置,不为空在判断session是否是green是的话就输出绿帽子,不是的话就输出黑帽和flag
那我们在找找什么位置设置session
然后我们在login.php中找到这段设置session代码
首先看下str_replace函数
然后我们就知道name参数先被waf函数处理 再用trim去除两边的空格 再通过str_replace函数把文字中的单引号都去掉
然后我们在看看waf函数
是正则表达式 我就把 网上正则的只是拿过来吧
\b:
.+:就是匹配.+两边的字符一个当开头一个当结尾 【https://www.cnblogs.com/zhangmiaomiao/p/6013091.html】
|:其实跟或的意思一样 例如 a|b 就说明可以是a也可以是b
.?+:
.+?表示最小匹配
举例说明.+?与.+的区别
<a href="xxx"><span>
如果用<.+>匹配,则匹配结果是
<a href="xxx"><span>
如果用<.+?>匹配,则匹配结果是
<a href="xxx">
也就是.+?只要匹配就返回了,不会再接着往下找了
/is: i 匹配大小写 ss 模式中的圆点元字符(.)匹配所有的字符,包括换行符
/:顺斜杠是表示表达式的开始和结束的“定界符”
preg_match函数: http://php.net/manual/zh/function.preg-match.php
preg_match()返回 pattern 的匹配次数,它的值将是0次(不匹配)或1次,因为preg_match()在第一次匹配后 将会停止搜索。
所以当返回值==1的时候说明发现匹配的字符串,就直接输出
die("found a hacker");
否则直接在通过str_replace函数把数据里面的空格去除,然后进行返回
分析完之后我们在回到login.php分析主要部分
name长度不能超过11,否则输出 name too long
mysql_query() 函数执行一条 MySQL 查询。
mysql_fetch_array() 函数从结果集中取得一行作为关联数组,或数字数组,或二者兼有
返回根据从结果集取得的行生成的数组,如果没有更多行则返回 false。
if($_rows[0]) //如果$_rows[0]存在
就是说输入的name查询结果返回值不能为空
我们只要利用 or 1=1就能让结果不为空了
最后name构造为:or/**/1=1#'
用/**/代替空格 然后通过or 1=1以及#注释掉后面的语句让整个语句恒真即可