Natas30 Writeup(sql注入)
Posted zhengna
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Natas30 Writeup(sql注入)相关的知识,希望对你有一定的参考价值。
Natas30:
本关是一个登录页面,查看源码,可以发现关键代码。
if (\'POST\' eq request_method && param(\'username\') && param(\'password\')){ my $dbh = DBI->connect( "DBI:mysql:natas30","natas30", "<censored>", {\'RaiseError\' => 1}); my $query="Select * FROM users where username =".$dbh->quote(param(\'username\')) . " and password =".$dbh->quote(param(\'password\')); my $sth = $dbh->prepare($query); $sth->execute(); my $ver = $sth->fetch(); if ($ver){ print "win!<br>"; print "here is your result:<br>"; print @$ver; } else{ print "fail :("; } $sth->finish(); $dbh->disconnect(); }
问题出在$dbh->quote(param(\'password\'))这里。
在Perl中,可以使用param(\'name\')方法获取post表单中name参数的值,但是这个方法有一个特点,那就是
当我们输入name=foo时,param(\'name\')方法返回的是name的值foo;
当我们输入name=foo&name=bar时,param(\'name\')方法返回的是name的值列表["foo","bar"]。
在Perl中,quote()方法的传参类型可以为列表,如果将列表传递给该方法,则quote()会将其解释为单独的参数。比如
@list = ("a", "b") quote(@list)
相当于
quote("a", "b")
Perl的quote($string)方法被用来“转义”包含在string中的任何特殊字符并增加所需的外部的引号。这里使用quote方法的本意是将用户的输入放在引号中以防止sql注入。但是当quote()可以接收两个参数时,它的用法变为:第一个参数表示将要被quote的数据,第二个参数表示一个SQL数据类型,决定如何quote。如果第二个参数是非字符串类型(如NUMERIC),则quote将传递其第一个参数,而不带任何引号。这就构成了SQL注入的机会。
所以,如果调用quote(param(\'password\')方法,我们可以通过抓包并给password赋两个值的方法来给quote()传入两个参数值。其中第二个参数为1个数字(比如2),使第一个参数值不带任何引号直接注入到SQL中,从而得到flag。
构造POST:username=natas31&password=\'xxx\' or 1=1 &password=2
flag:hay7aecuungiuKaezuathuk9biin0pu1
参考:
https://security.stackexchange.com/questions/175703/is-this-perl-database-connection-vulnerable-to-sql-injection/175872#175872
https://stackoverflow.com/questions/40273267/is-perl-function-dbh-quote-still-secure/40275686#40275686
https://blog.csdn.net/baidu_35297930/article/details/99974886?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task
以上是关于Natas30 Writeup(sql注入)的主要内容,如果未能解决你的问题,请参考以下文章