Gentle_knife's Studio.

Perl 文件上传—— [CSAWQual 2016]I_Got_ID

Word count: 466Reading time: 1 min
2025/07/28
loading

因为Perl File Upload 这里上传文件会原样输出,所以大佬猜测源码是这样的:

[CSAW 2016] I Got Id – Web200

img

1
2
3
4
5
6
7
8
9
use strict;
use warnings;
use CGI;

my $cgi= CGI->new;
if ( $cgi->upload( 'file' ) )
{
my $file= $cgi->param( 'file' );
while ( <$file> ) { print "$_"; } }

这里$cgi接受上传的 file,然后复制给$file,再把这个文件内容逐行读出并显示在页面上。

<$file> 被 Perl 解释成 <ARGV><ARGV>是特殊的,这是漏洞的来源。

如果我们这里上传的不是文件,而是一个 叫 "ARGV" 的纯文本字符串,那么$file就是 ARGV,<$file> 就是<ARGV>

Perl 中<ARGV>可以类比于 Python 里的sys.argv,也就是说当你在命令行里输入perl demo.pl /etc/passwd的时候/etc/passwd就会填补在<ARGV>

虽然我们题目里没有命令行,但是 Perl里的CGI模块很聪明,如果你访问的是:upload.pl?file=/etc/passwd,那么 CGI 模块会自动把这个参数放进 @ARGV 里。

这正好被 <ARGV> 使用,所以你传进去的参数 /etc/passwd 就会被当作文件名打开。

这里我看网上 wp 说的是,param是可以接受多个值的,只有第一个文件会被放入到下面的file变量中。所以我们抓包上传请求,在我们上传的文件前面添加一个 ARGV,在命令行添加系统命令就可以实现命令执行。

这里如果把下面的文件删掉,读不出来。也就是说我们无法只上传一个内容是字符串ARGVfile来读取。

有可能是上传的第二个文件是文件,保证是服务器会当成文件来读,我们单独上传 ARGV时识别的是字符串。

img

img

CATALOG
  1. 1.