The Perl Jam - Exploiting a 20 Year-old Vulnerability ãã
Perlãæ®æ®µããæ¸ãã¦ãã人ã«ã¨ã£ã¦ã¯å¸¸èã§ã¯ããããããã§ã¯ãªã人ã®ããã«æ¸ãã¦ããã
ãªã¹ãã¨é å
Perlã«ãããããªã¹ããã¨ã¯ä½ãã¨ããã®ã確èªãã¦ãããã¾ããPerlã«ã¯ã³ã³ããã¹ãã¨ããä»ã®ããã°ã©ãã³ã°è¨èªã«ã¯ãªãæ¦å¿µããããåæ°(ã¹ã«ã©ã¼)ã¨è¤æ°(ãªã¹ã)ãåºå¥ããã
# é å my @a = ('a', 'b', 'c'); # ãªã¹ãã³ã³ããã¹ã # é åããªã¹ãã³ã³ããã¹ãã§è©ä¾¡ print @a; #=> abc # ãªã¹ãããªã¹ãã³ã³ããã¹ãã§è©ä¾¡ print ('a', 'b', 'c'); #=> abc # ã¹ã«ã©ã¼ã³ã³ããã¹ã # é åã®è¦ç´ ã¯ã¹ã«ã©ã¼ print $a[0]; #=> a # é åãã¹ã«ã©ã¼ã³ã³ããã¹ãã§è©ä¾¡ print scalar @a; #=> 3 # ãªã¹ããã¹ã«ã©ã¼ã³ã³ããã¹ãã§è©ä¾¡ print scalar ('a', 'b', 'c'); #=> c # Useless use of a constant ("a") in void context # Useless use of a constant ("b") in void context
ã³ã³ããã¹ãã«ãã£ã¦è¿ãããå¤ãéããã¨ãåããã
- ã¹ã«ã©ã¼ã³ã³ããã¹ã
- é åâè¦ç´ æ°
- ãªã¹ãâæå¾ã®è¦ç´
ãªã¹ãã¨é
åã¯å¥ç©ããªã¹ãã@aã¨ããå¤æ°ã«å
¥ãããã¨ã§é
åã«ãªãã*1
ãã ããé
åã¯ãªã¹ãã³ã³ããã¹ãã§è©ä¾¡ãããã
sub foo { my ($arg1, $arg2, $arg3) = @_; # $arg1, $arg2, $arg3 ã«ã¯ã©ã®ãããªå¤ãä»£å ¥ãããã } foo(1, 2, 3); #=> (1, 2, 3) my @a = (1, 2); foo(@a, 3); #=> (1, 2, 3) my @b = (2, 3); foo(1, $b[0], 3); #=> (1, 2, 3) foo(1, @b[0, 1]); #=> (1, 2, 3) foo(1, @b); #=> (1, 2, 3) # array reference foo(1, \@b); #=> (1, [2, 3])
wantarray
wantarray
ã使ãã¨ãã³ã³ããã¹ã(åæ°ãåãåãå ´é¢ãè¤æ°ãåãåãå ´é¢)ã«ãã£ã¦é¢æ°ã®æ¯ãèããå¤ãããã¨ãã§ãããããããããã使ãã¨ã³ã¼ããè¦ãã ãã§ã¯åä½ãåãããªããªã£ã¦ãã¾ããã¨ããããããé »ç¹ã«ã¯ä½¿ããã¦ããªãã使ãããä¾ã示ãã¨ããã°ãCGI.pmã®param
é¢æ°ãããã
use CGI; my $cgi = CGI->new; # a=1&a=2&a=3 my @values = $cgi->param('a'); # (1, 2, 3) my $value = $cgi->param('a'); # 1
ãã ããCGI.pm 4.08ããã¯multi_param
ã使ããã¨ããæ¨å¥¨ããã¦ããããªã¹ãã³ã³ããã¹ãã§param
ã使ããã¨ããã¨è¦åãåºãã
my @values = $cgi->multi_param('a'); # (1, 2, 3)
å¤é¨ããã®ãã©ã¡ã¼ã¿ãå¼æ°ã¨ãã¦æ¸¡ãã¨ãããã®ä»æ§ã大ããåé¡ã¨ãªããæ示çã«scalar
ã«ãã£ã¦ã¹ã«ã©ã¼ã³ã³ããã¹ãã§è©ä¾¡ããªãéãããªã¹ãã³ã³ããã¹ãã§è©ä¾¡ãããã
New Class of Vulnerability in Perl Web Applications | Hacking for Christ ã§ã¯ä»¥ä¸ã®ãããªã³ã¼ãã«èå¼±æ§ãããã¨è¨åããã¦ããã
my $otheruser = Bugzilla::User->create({ login_name => $login_name, realname => $cgi->param('realname'), cryptpassword => $password});
$cgi->param('realname')
ã¯ãªã¹ãã³ã³ããã¹ãã§è©ä¾¡ããããããrealnameãã©ã¡ã¼ã¿ãè¤æ°æå®ããã¦ããå ´åã«ãå¼æ°ã®æ¹ç«ãã§ããã
realname=aaa&realname=login_name&realname=admin
ã¨realnameã«å¯¾ãã¦è¤æ°ã®ãã©ã¡ã¼ã¿ãæå®ãããã¨ã§ä»¥ä¸ã®ããã«login_nameã®æ¹ç«ãã§ããã
{ login_name => $login_name, realname => 'aaa', login_name => 'admin', cryptpassword => $password, }
ãã®ããã«æ¸ãã®ãæ£ããã
my $otheruser = Bugzilla::User->create({ login_name => $login_name, realname => scalar $cgi->param('realname'), cryptpassword => $password});
ãããã¯
my $realname = $cgi->param('realname'); my $otheruser = Bugzilla::User->create({ login_name => $login_name, realname => $realname, cryptpassword => $password});
ãã®åé¡ã¯脆弱なアプリを書く技術 // Speaker Deckã§ãè¨åãã¦ãããAdvent Calendar CTF 2014ã®13æ¥ç®ã®åé¡ã¨ãã¦åºé¡ãããPerlã®ããã·ã¥ã¯key/valueã対ã«ãªã£ã¦ããªãã¦ã(è¦ç´ æ°ãå¥æ°)ãè¦åã¯åºããåãããä¸è¨ã®ä¾ã§ããã°cryptpasswordãæ¸ãæãããã¨ãã§ããã詳ããã¯ã¹ã©ã¤ãåç §ã
ä½è«ã§ã¯ããããMojolicious 5.48ããã¯Mojo::Parametersã®paramã®æ¯ãèããå¤æ´ããã以åã¯CGI.pmã¨åãæåããã¦ããããwantarray
ã«ããã³ã³ããã¹ãå¥ã®æåã¯å®å
¨ã«å»æ¢ãããè¤æ°ã®ãã©ã¡ã¼ã¿ãåãåãã«ã¯every_paramã使ãããã«ãªã£ãã
è足
ã§ããã ãå®å
¨ã«ã³ã³ããã¹ããæ±ãã«ã¯scalar
ã§ã¹ã«ã©ã¼ã³ã³ããã¹ãã§è©ä¾¡ããã®ãæ示çã«æ¸ãå¿
è¦ããããããããscalar
ã¨æ¯åã¿ã¤ãããã«ã¯äººçã¯çãããã
Perl5ã§ã¯åé
æ¼ç®åã¨ãã¦ã®+
ã¯æå³ã®ãªããã®ã¨ãã¦æ±ããcode blockã¨hash referenceãåºå¥ãããã®ã¨ãã¦ä½¿ããããã¨ããããPerl6ã§ã¯+
åé
æ¼ç®ãscalarã¨ãã¦æ±ãããããã«ãªã£ãã
ããã§ã¯Perl5ã®+
ãscalarã®ä»£ããã«ãªãããã«è¨èªããã¯ããã¦ã¿ããblead-perlã«ä»¥ä¸ã®ããããå½ã¦ãã
diff --git a/perly.y b/perly.y index 4b73977..ec0cdf6 100644 --- a/perly.y +++ b/perly.y @@ -824,7 +824,13 @@ termbinop: term ASSIGNOP term /* $x = $y */ termunop : '-' term %prec UMINUS /* -$x */ { $$ = newUNOP(OP_NEGATE, 0, scalar($2)); } | '+' term %prec UMINUS /* +$x */ - { $$ = $2; } + { + if (FEATURE_UNARYSCALAR_IS_ENABLED) { + $$ = scalar($2); + } else { + $$ = $2; + } + } | '!' term /* !$x */ { $$ = newUNOP(OP_NOT, 0, scalar($2)); } diff --git a/regen/feature.pl b/regen/feature.pl index 6733e3c..c784691 100755 --- a/regen/feature.pl +++ b/regen/feature.pl @@ -37,6 +37,7 @@ my %feature = ( unicode_strings => 'unicode', fc => 'fc', signatures => 'signatures', + unaryscalar => 'unaryscalar', ); # NOTE: If a feature is ever enabled in a non-contiguous range of Perl
% perl regen/feature.pl % perl regen_perly.pl % perl -MPerl::Build -e'Perl::Build->install(src_path => ".", dst_path => "/opt/blead-perl", configure_options => ["-Dusedevel", "-de"])'
% bin/perl5.21.10 -e'print localtime()' 657152711155570 % bin/perl5.21.10 -e'print scalar localtime()' Fri Feb 27 15:57:09 2015 % bin/perl5.21.10 -Mfeature=unaryscalar -e'print +localtime()' Fri Feb 27 15:57:11 2015
ãããã¦ä¸çãã¾ãã²ã¨ã¤å¹³åã«è¿ã¥ããã¨ã ;)