深入分析Citrix ADC远程代码执行(RCE)漏洞CVE-2019-19781
字数 1433 2025-08-18 11:39:26
Citrix ADC远程代码执行漏洞(CVE-2019-19781)深度分析与利用指南
漏洞概述
CVE-2019-19781是Citrix ADC(原NetScaler)和Citrix Gateway中存在的一个高危远程代码执行漏洞。该漏洞于2019年底被发现并报告,具有以下关键特征:
- 漏洞类型:远程代码执行(RCE)
- 影响范围:Citrix ADC和Citrix Gateway设备
- 利用条件:无需身份验证
- CVSS评分:9.8(严重)
- 发现者:Positive Technologies和Paddy Power Betfair安全团队
漏洞分析
漏洞定位
从Citrix官方缓解措施中可以推断漏洞路径为/vpns/,可能是一个目录遍历漏洞。通过分析httpd.conf文件,发现NetScaler::Portal::Handler Perl Module (Handler.pm)模块在/vpn/portal/scripts/目录下负责生成方法定义。
漏洞根源
漏洞主要存在于UsersPrefs脚本中的csd方法:
sub csd {
my $self = shift;
my $skip_read = shift || "";
# Santity Check
my $cgi = new CGI;
print "Content-type: text/html\n\n";
# Username variable initialized by the NSC_USER HTTP Header
my $username = Encode::decode('utf8', $ENV{'HTTP_NSC_USER'}) || errorpage("Missing NSC_USER header.");
$self->{username} = $username;
...
$self->{session} = %session;
# Constructing the path from the username.
$self->{filename} = NetScaler::Portal::Config::c->{bookmark_dir} . Encode::encode('utf8', $username) . '.xml';
if($skip_read eq 1) {
return;
}
关键问题:
- 从
NSC_USERHTTP头获取用户名 - 直接使用用户名构造文件路径,无任何安全校验
- 导致目录遍历漏洞
漏洞利用链
- 文件写入点:
newbm.pl脚本- 创建包含各种参数信息的数组
- 调用
filewrite方法将信息写入XML文件
my $cgi = new CGI;
print "Content-type: text/html\n\n";
my $user = NetScaler::Portal::UserPrefs->new();
my $doc = $user->csd();
...
my $newurl = Encode::decode('utf8', $cgi->param('url'));
my $newtitle = Encode::decode('utf8', $cgi->param('title'));
my $newdesc = Encode::decode('utf8', $cgi->param('desc'));
my $UI_inuse = Encode::decode('utf8', $cgi->param('UI_inuse'));
...
my $newBM = {
url => $newurl,
title => $newtitle,
descr => $newdesc,
UI_inuse => $UI_inuse,
};
...
if ($newBM->{url} push @{$doc->{filesystems}->{filesystem}}, $newBM;
} else {
# bookmark
push @{$doc->{bookmarks}->{bookmark}}, $newBM;
}
# Writing XML file to disk
$user->filewrite($doc);
-
模板注入:利用Perl Template Toolkit模板引擎
- 在XML文件中插入特定指令
- 当模板引擎解析时触发命令执行
-
模板解析触发点:
Handler.pm$tmplfile变量从HTTP请求路径构建- 处理该变量文件时会生成新模板
漏洞利用方法
方法一:模板注入实现RCE
利用BLOCK模板注入实现任意Perl代码执行:
- 通过
Template::Document类中的new方法 - 该方法会获取BLOCK模板参数并调用
eval
sub new {
my ($class, $doc) = @_;
my ($block, $defblocks, $variables, $metadata) = @$doc{ qw( BLOCK DEFBLOCKS VARIABLES METADATA ) };
$defblocks $metadata
# evaluate Perl code in $block to create sub-routine reference if necessary
unless (ref $block) {
local $SIG{__WARN__} = \&catch_warnings;
$COMPERR = '';
# DON'T LOOK NOW! - blindly untainting can make you go blind!
$block = each %{ { $block => undef } } if ${^TAINT}; #untaint
$block = eval $block;
return $class->error($@) unless defined $block;
}
方法二:DATAFILE插件命令注入
利用不安全的open函数实现命令注入:
sub new {
my ($class, $context, $filename, $params) = @_;
my ($delim, $line, @fields, @data, @results);
my $self = [ ];
local *FD;
local $/ = "\n";
$params $delim = $params->{'delim' $delim = quotemeta($delim);
return $class->fail("No filename specified") unless $filename;
open(FD, $filename) || return $class->fail("$filename: $!");
# first line of file should contain field definitions
while (! $line || $line $line = <FD>;
chomp $line;
$line =~ s/\r$//;
}
利用方式:
- 控制
$filename变量 - 使用管道命令
|构造恶意文件名 - 导致任意命令执行
漏洞利用步骤
- 利用目录遍历:通过构造恶意
NSC_USER头,在模板目录下写入特制XML文件 - 插入恶意模板指令:在XML文件中插入Perl Template Toolkit指令
- 触发模板解析:访问写入的XML文件,触发模板引擎解析
- 实现代码执行:成功执行XML文件中嵌入的恶意代码
漏洞修复建议
- 官方补丁:及时应用Citrix官方发布的修复补丁
- 缓解措施:
- 按照Citrix公布的详细缓解步骤操作
- 监控包含
/vpns/和/../样式的POST请求 - 监控对xml文件的GET请求
- 安全配置:
- 禁用不必要的特性配置
- 限制对
/vpns/路径的访问
注意事项
- 某些Payload可能导致Citrix NetScaler过度记录错误,填满
/var分区 - 公开的Exploit可能对系统稳定性造成影响,使用前需谨慎评估
- 该漏洞已被多个安全团队武器化,需优先修复
参考资源
- Citrix官方漏洞公告
- Positive Technologies研究报告
- Craig Yong《关于CVE-2019-19781你需要知道的》
- Perl Template Toolkit GitHub仓库
- FreeBuf漏洞分析文章