Sqli-labs 查看源代码 21-30

  • Less-21
    • POST - cookie注入 - base46 编码
  • Less-22
    • POST - cookie注入 - base46 编码
  • Less-23
    • GET - 注释符绕过
  • Less-24
    • post - 二次注入
  • Less-25
    • GET - 绕过or 和 and - 字符型
  • Less-26
    • GET - 过滤空格 - 字符型
  • Less-27
    • GET - 过滤UNION和SELECT - 字符型
  • Less-28
    • GET - UNION 和 SELECT大小写- 字符型
  • Less-29
    • GET - 基于错误 - 单引号 - WAF防护
  • Less-30


Less-21:

POST - cookie注入 - base46 编码

  • POST
if(isset($_POST['uname']) && isset($_POST['passwd']))
        {

        $uname = check_input($_POST['uname']);
        $passwd = check_input($_POST['passwd']);
    }   
  • cookie注入
$sql="SELECT * FROM users WHERE username=('$cookee') LIMIT 0,1";

$result=mysql_query($sql);
  • base46 编码
setcookie('uname', base64_encode($row1['username']), time()+3600); 

$cookee = base64_decode($cookee);   
setcookie('uname', base64_encode($row1['username']), time()-3600);
  • base64_encode():
    Encodes data with MIME base64

  • base64_decode():
    Decodes data encoded with MIME base64


Less-22:

POST - cookie注入 - base46 编码

  • POST
    同上

  • cookie注入
    同Less-21比有轻微不同

$sql="SELECT * FROM users WHERE username=$cookee1 LIMIT 0,1";
  • base46 编码
    同上

Less-23:

GET - 注释符绕过

  • GET
    省略

  • 注释符绕过

//filter the comments out so as to comments should not work
//   / 只是在某些语言中作为正则的边界符, //中的就表示是正则表达式.

$reg = "/#/";   // 匹配#
$reg1 = "/--/";    // 匹配--
$replace = "";
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);//preg_replace()函数查找有没匹配$reg的,然后用$replace替代掉

//这一段的作用就是过滤掉输入数据中的注释符

一般注释符用来注释掉最后面一个单引号,这个时候就要换个思路。
用普通 的or 或 and 带上单引号去闭合。

旧思路:
测试语句:input = 1' or 1=1 #
实际运行语句:$sql = select username,password from users where id='1' or 1=1 #'
报错,存在语法错误

新思路:
测试语句:input = 1' or '1'='1
实际运行语句:$sql = select username,password from users where id='1' or '1'='1'


Less-24:

post - 二次注入

  • post

  • 二次注入

  • index.php


session_start();//启动会话 

//Session 的工作机制是:为每个访问者创建一个唯一的 id (UID),并基于这个 UID 来存储变量。

//UID 存储在 cookie 中,亦或通过 URL 进行传导。

if (isset($_SESSION['username']) && isset($_COOKIE['Auth'])) {
//检查是否已经登录过
   header('Location: logged-in.php');//重定向到logged-in.php

}
?>

//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
?>

<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<title>Less-24 - Second Degree Injections title>
head>
<body bgcolor="#000000">

<div style="text-align:center">
<form name="login" method="POST" action="login.php">

//将表单post到login.php中去处理


<h2 style="text-align:center;background-image:url('../images/Less-24.jpg');background-repeat:no-repeat;background-position:center center">
<div style="padding-top:300px;text-align:center;color:#FFFF00;"> echo $form_title_in; ?>div>
h2>

<div align="center">
<table style="margin-top:50px;">
<tr>
<td style="text-align:right">
<font size="3" color="#FFFF00">
<strong>Username:strong>
td>
<td style="text-align:left">
<input name="login_user" id="login_user" type="text" value="" />
td>
tr>
<tr>
<td style="text-align:right">
<font size="3" color="#FFFF00">
<strong>Password:strong>
td>
<td style="text-align:left">
<input name="login_password" id="login_password" type="password" value="" />
td>
tr>
<tr>
<td colspan="2" style="text-align:right">
<input name="mysubmit" id="mysubmit" type="submit" value="Login" /><br/><br/>

<a style="font-size:.8em;color:#FFFF00" href="forgot_password.php">Forgot your password?a><font size="3" color="#FFFF00">
||font>
<a style="font-size:.8em;color:#FFFF00" href="new_user.php">New User click here?a>
td>
tr>

table>
div>
form>
div>
body>
html>
  • logged-in.php


session_start();
if (!isset($_COOKIE["Auth"]))//检查是否登录过
{
    if (!isset($_SESSION["username"])) 
    {
        header('Location: index.php');
    }
    header('Location: index.php');
}
?>

//省略一大段代码

已登录过的请求头

  • failed.php

session_start();
if (!isset($_COOKIE["Auth"]))//检查是否登录过
{
    if (!isset($_SESSION["username"])) 
    {
        header('Location: index.php');
    }
    header('Location: index.php');
}
?>
//省略一大段代码
  • forgot_password.php

  • login.php



session_start();//开始会话
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");


//函数作用:查询数据,查得到返回数据,查不到数据Or出错返回0
function sqllogin(){
$username = mysql_real_escape_string($_POST["login_user"]);

//mysql_real_escape_string()转义 SQL 语句中使用的字符串中的特殊字符,并考虑到连接的当前字符集,使其可以安全用于mysql_query

$password = mysql_real_escape_string($_POST["login_password"]);
   $sql = "SELECT * FROM users WHERE username='$username' and password='$password'";

   $res = mysql_query($sql) or die('You tried to be real smart, Try harder!!!! :( ');
   $row = mysql_fetch_row($res);


   if ($row[1]) {
            return $row[1];
   } else {
            return 0;
   }

}


$login = sqllogin();
if (!$login== 0) //查到数据了
{
    $_SESSION["username"] = $login;
    setcookie("Auth", 1, time()+3600);  /* expire in 15 Minutes */     

    //设置cookie
    header('Location: logged-in.php');

    //重定向到logged-in.php页面

} 
else
{
?>
<tr><td colspan="2" style="text-align:center;"><br/><p style="color:#FF0000;">
<center>
<img src="../images/slap1.jpg">
center>
p>td>tr>
  • login_create.php
    创建用户的页面
if (isset($_POST['submit']))
{


# Validating the user input........


    $username=  mysql_escape_string($_POST['username']) ;
    $pass= mysql_escape_string($_POST['password']);
    $re_pass= mysql_escape_string($_POST['re_password']);

    echo "";
    $sql = "select count(*) from users where username='$username'"; 
    $res = mysql_query($sql) or die('You tried to be smart, Try harder!!!! :( ');
    $row = mysql_fetch_row($res);

    //查询是否有同名

    if (!$row[0]== 0) 
        {
        ?> //存在同名
        ;
        
        header('refresh:1, url=new_user.php');
        } 
        else 
        {
            if ($pass==$re_pass)
            {   //两次输入的密码一致
                # Building up the query........

                $sql = "insert into users ( username, password) values(\"$username\", \"$pass\")";
                mysql_query($sql) or die('Error Creating your user account,  : '.mysql_error());

                    echo "
Redirecting you to login page in 5 sec................"
; echo ""; echo "
If it does not redirect, click the home button on top right"
; header('refresh:5, url=index.php'); //5秒后刷新,并跳转到index.php } else { ?> header('refresh:1, url=new_user.php'); } } }
  • new_user.php
    形成表单,并将数据post到login_create.php中去处理
<form name="mylogin" method="POST" action="login_create.php">
  • pass_change.php

session_start();    //开启会话
if (!isset($_COOKIE["Auth"]))//查看是否登陆过
{
    if (!isset($_SESSION["username"])) 
    {
        header('Location: index.php');
    }
    header('Location: index.php');
}
?>
<div align="right">
<a style="font-size:.8em;color:#FFFF00" href='index.php'><img src="../images/Home.png" height='45'; width='45'>br>HOMEa>
div>


//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");



if (isset($_POST['submit']))  
{
    # Validating the user input........
    $username= $_SESSION["username"];

    //过滤数据,使合法
    //唯独只有username直接从session中获取,没有进行过滤

    $curr_pass= mysql_real_escape_string($_POST['current_password']);
    $pass= mysql_real_escape_string($_POST['password']);
    $re_pass= mysql_real_escape_string($_POST['re_password']);

    if($pass==$re_pass)//新密码与旧密码相同
    {   
        $sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";

        // 更新数据

        $res = mysql_query($sql) or die('You tried to be smart, Try harder!!!! :( ');
        $row = mysql_affected_rows();
        echo '';
        echo '
'; if($row==1) { echo "Password successfully updated"; } else { header('Location: failed.php'); //echo 'You tried to be smart, Try harder!!!! :( '; } } else { echo '
'; echo "Make sure New Password and Retype Password fields have same value"; header('refresh:2, url=index.php'); //两秒后刷新,并重定向到index.php } } ?> if(isset($_POST['submit1'])) { session_destroy(); //Destroys all data registered to a session setcookie('Auth', 1 , time()-3600); //设置cookie过期 header ('Location: index.php'); } ?>
  • tips:
    看了源代码之后,才发现为什么我在第一次登录成功后想再次查看其它页面都不行,因为每个页面一开始都会检查我是否登录过,如果登录过则重定向到index.php。Oh,有空还是要多看源代码。

Less-25:

GET - 绕过or 和 and - 字符型

  • GET
    省略

  • 绕过or 和 and - 字符型

function blacklist($id)
{
    $id= preg_replace('/or/i',"", $id);          //strip out OR (non case sensitive)
    $id= preg_replace('/AND/i',"", $id);      //Strip out AND (non case sensitive)

    return $id;
}

Less-26:

GET - 过滤空格 - 字符型

  • GET
    省略

  • 过滤空格 - 字符型

function blacklist($id)
{
    $id= preg_replace('/or/i',"", $id);          //strip out OR (non case sensitive)
    $id= preg_replace('/and/i',"", $id);      //Strip out AND (non case sensitive)
    $id= preg_replace('/[\/\*]/',"", $id);      //strip out /*
    $id= preg_replace('/[--]/',"", $id);      //Strip out --
    $id= preg_replace('/[#]/',"", $id);          //Strip out #
    $id= preg_replace('/[\s]/',"", $id);      //Strip out spaces
    $id= preg_replace('/[\/\\\\]/',"", $id);      //Strip out slashes
    return $id;
}

Less-27:

GET - 过滤UNION和SELECT - 字符型

  • GET
    省略

  • 过滤UNION和SELECT - 字符型


function blacklist($id)
{//黑名单策略过滤危险字符
$id= preg_replace('/[\/\*]/',"", $id);      //strip out /*
$id= preg_replace('/[--]/',"", $id);      //Strip out --.
$id= preg_replace('/[#]/',"", $id);          //Strip out #.
$id= preg_replace('/[ +]/',"", $id);      //Strip out spaces.
$id= preg_replace('/select/m',"", $id);      //Strip out spaces.
$id= preg_replace('/[ +]/',"", $id);      //Strip out spaces.
$id= preg_replace('/union/s',"", $id);      //Strip out union
$id= preg_replace('/select/s',"", $id);      //Strip out select
$id= preg_replace('/UNION/s',"", $id);      //Strip out UNION
$id= preg_replace('/SELECT/s',"", $id);      //Strip out SELECT
$id= preg_replace('/Union/s',"", $id);      //Strip out Union
$id= preg_replace('/Select/s',"", $id);      //Strip out select
return $id;
}

Less-28:

GET - UNION 和 SELECT(大小写)- 字符型

  • GET
    省略

  • UNION 和 SELECT(大小写)- 字符型



function blacklist($id)
{
$id= preg_replace('/[\/\*]/',"", $id);              //strip out /*
$id= preg_replace('/[--]/',"", $id);              //Strip out --.
$id= preg_replace('/[#]/',"", $id);                  //Strip out #.
$id= preg_replace('/[ +]/',"", $id);              //Strip out spaces.
//$id= preg_replace('/select/m',"", $id);                //Strip out spaces.
$id= preg_replace('/[ +]/',"", $id);              //Strip out spaces.
$id= preg_replace('/union\s+select/i',"", $id);      //Strip out UNION & SELECT.
return $id;
}

Less-29:

GET - 基于错误 - 单引号 - WAF防护

  • GET
    省略

  • 基于错误
    省略

  • 单引号 - WAF防护

//WAF implimentation with a whitelist approach..... only allows input to be Numeric.
//只允许数字型数字
function whitelist($input)
{
    $match = preg_match("/^\d+$/", $input);
    //  正则表达式:/^\d+$/
    //  ^匹配输入字符串的开始位置。
    //  \d任意一个数字,0~9 中的任意一个[0-9]
    // +修饰匹配次数为至少 1 次。
    // $匹配输入字符串的结尾位置

    if($match)//如果匹配,用户输入了数字的话,就允许继续
    {
        //echo "you are good";
        //return $match;
    }
    else
    {   
        header('Location: hacked.php');//重定向
        //echo "you are bad";
    }
}



// The function below immitates the behavior of parameters when subject to HPP (HTTP Parameter Pollution).

function java_implimentation($query_string)
{
    $q_s = $query_string;
    $qs_array= explode("&",$q_s);
//  explode()作用:把字符串打散为数组
//如果输入一个?id=1&id=2&id=3,就会分割成{id=1,id=2,id=3}这样的数组

    foreach($qs_array as $key => $value)
    {
        $val=substr($value,0,2);//截断字符id=1,取前面id
        if($val=="id")
        {
            $id_value=substr($value,3,30); //取id后面的数字
            return $id_value;

            break;
        }

    }

}

foreach()有两种用法:

1foreach(array_name as $value){ 
        statement;
    }

这里的array_name是你要遍历的数组名,每次循环中,array_name数组的当前元素的值被赋给$value,并且数组内部的下标向下移一步,也就是下次循环回得到下一个元素。

2foreach(array_name as $key => $value){        
       statement;     
    }   

这里跟第一种方法的区别就是多了个 key, value外,当前元素的键值也会在每次循环中被赋给变量$key。键值可以是下标值,也可以是字符串。比如book[0]=1中的“0”,book[id]=”001”中的“id”.

来看看第二种格式,第二种格式除了能像第一种格式一样得到数组内元素的值外,还能得到元素的索引值,并保存到$key变量中,如果数组的索引值未经过人工设定,则返回系统默认的设定值,


Less-29中根据其中代码逻辑,WAF 会检测 id 是否为数字,如果不是一律转向 hacked.php。但是程序 没有考虑当 id 多次赋值的情况,它只对第一次的 id 进行了测试,如果传入多个 id,那么后 面的 id 则存在注入漏洞


Less-30:

跟29差不多,故省略


你可能感兴趣的:(Sqli-labs 查看源代码 21-30)