solveme challenge

偶然的情况下 看到了一个可供代码审计学习的平台,记录下学习的过程,有不对的地方,大佬们轻喷

challenge 1   链接 http://warmup.solveme.peng.kr


关键 php:echo base64_encode(hex2bin(strrev(bin2hex($flag))))

首先 flag 使用bin2hex bin2hex() 把 ASCII 字符的字符串转换为十六进制值。字符串可通过使用 pack() 函数解密

其次 反转字符串 strrev() 函数,再转换为字符串,最后base64得到加密后的flag

这里使用 python的转换 调用binascii.a2b_hex()函数

用python 解密

步骤分别为:base64 解密;将字符串转为16进制 ;字符串反转;16进制值转为字符串

import binascii
import base64


s = '1wMDEyY2U2YTY0M2NgMTEyZDQyMjAzNWczYjZgMWI4NTt3YWxmY='
s1 = base64.b64decode(s)
s2 = binascii.b2a_hex(s1)
s3 = s2[::-1]
s4 = binascii.a2b_hex(s3)
print (s4) #结果就出来了

challenge_2 : 链接:http://badcompare.solveme.peng.kr

题:

<?php
    error_reporting
(0);
    require 
__DIR__.'/lib.php';

    if(isset(
$_GET['answer'])){

        if(
$_GET['answer'] === '痤迈愈羼滋'){
            echo 
$flag;
        }else{
            echo 
'Wrong answer';
        }

        echo 
'<hr>';
    }

    
highlight_file(__FILE__);

这个是显示的乱码,推测应该是不同标准码的数据引起的乱码,截获数据包,查看16进制数据


以16进制提交尝试:在url 中 url编码转换 %f0%ee%c2%f5%d3%fa%e5%f1%d7%cc

这种方法比较笨,借鉴下别的方法,获取该页面数据,直接获取 这段乱码 源码

import requests
import urllib
url = "http://badcompare.solveme.peng.kr"
s = requests.get(url=url)
print(s.content)
s1 = b'\xf0\xee\xc2\xf5\xd3\xfa\xe5\xf1\xd7\xcc'
s2 = urllib.parse.quote(s1)
print (s2)
challenge 3 http://wintersleep.solveme.peng.kr
<?php
    error_reporting(0);
    require __DIR__.'/lib.php';

    if(isset($_GET['time'])){

        if(!is_numeric($_GET['time'])){
            echo 'The time must be number.';

        }else if($_GET['time'] < 60 * 60 * 24 * 30 * 2){
            echo 'This time is too short.';

        }else if($_GET['time'] > 60 * 60 * 24 * 30 * 3){
            echo 'This time is too long.';

        }else{
            sleep((int)$_GET['time']);
            echo $flag;
        }

        echo '<hr>';
    }

    highlight_file(__FILE__);

这里 判断要求sleep 时间 60 * 60 * 24 * 30 * 到 60 * 60 * 24 * 30 * 3之间,直接输入time的需要sleep的时间太长,这里考虑下判断的绕过

根据经验 有漏洞的函数is_numeric

php5 可绕过有科学计数法和0x  php7 就只有科学计数法了

使用 0x 时 The time must be number.,那只用用科学计数法了 在5184300 和7776000之间 即 time 为5.1843e6-7.776e6均可

http://wintersleep.solveme.peng.kr/?time=7.1e6 因php版本的原因,某些情况下不会触发,如在菜鸟上就 仍会sleep 7.1e6 

challenge 4:

<?php
    error_reporting(0);
    session_start();
    require __DIR__.'/lib.php';

    if(isset($_GET['username'], $_GET['password'])){

        if(isset($_SESSION['hard_login_check'])){
            echo 'Already logged in..';

        }else if(!isset($_GET['username']{3}) || strtolower($_GET['username']) != $hidden_username){
            echo 'Wrong username..';

        }else if(!isset($_GET['password']{7}) || $_GET['password'] != $hidden_password){
            echo 'Wrong password..';

        }else{
            $_SESSION['hard_login_check'] = true;
            echo 'Login success!';
            header('Location: ./');
        }

        echo '<hr>';
    }

    highlight_file(__FILE__);

分析下逻辑 在登录成功时 会调用header('Location: ./');进行跳转到当前目录,且没有其他验证。  那么直接访问当前目录,但是直接跳转,burp数据包分析



challenge 5:

<?php
    error_reporting(0);
    require __DIR__."/lib.php";

    $url = urldecode($_SERVER['REQUEST_URI']); // 请求的url 解码
    $url_query = parse_url($url, PHP_URL_QUERY);// 提取参数

    $params = explode("&", $url_query);
    foreach($params as $param){

        $idx_equal = strpos($param, "=");
        if($idx_equal === false){
            $key = $param;
            $value = "";
        }else{
            $key = substr($param, 0, $idx_equal);
            $value = substr($param, $idx_equal + 1);
        }

        if(strpos($key, "do_you_want_flag") !== false || strpos($value, "yes") !== false){
            die("no hack");
        }
    }

    if(isset($_GET['do_you_want_flag']) && $_GET['do_you_want_flag'] == "yes"){
        die($flag);
    }

    highlight_file(__FILE__);

urlfiltering.solveme.peng.kr

这个地方利用 parse_url 漏洞 学习于 一叶飘零详情请看 http://skysec.top/2017/12/15/parse-url函数小记/

在parse_url 接口处使用 如:"path"]=> string(28) "/php_bugs/parse_url.php 处使用  localhost////php_bugs/parse_url.php/?sql=select.

challenge 6: 

<?php
    error_reporting(0);
    require __DIR__.'/lib.php';

    if(isset($_GET['foo'], $_GET['bar'])){

        if(strlen($_GET['foo']) > 30 || strlen($_GET['bar']) > 30){
            die('Too long');
        }

        if($_GET['foo'] === $_GET['bar']){
            die('Same value');
        }

        if(hash('sha512', $_GET['foo']) !== hash('sha512', $_GET['bar'])){
            die('Different hash');
        }

        echo $flag, '<hr>';
    }

    highlight_file(__FILE__);

根据分析 这道题要求 foo 和bar 的长度不超过30;且两个值不同(全等于状态下 要求类型、值均相同);sha256的hash 值不同

php中sha1存在漏洞,不能处理 数组,会返回false,false===false 条件成立,则 foo[]=1&bar[]=2

在php中md5算法 同样存在这个问题;除此之外

hash('md5', $_GET['foo']) !== hash('md5', $_GET['bar'])改为hash('md5', $_GET['foo']) != hash('md5', $_GET['bar'])时

 可以使用php弱类型漏洞 http://localhost/php_bugs/hash_bug_md5.php/?foo[]=1&bar[]=a;

http://localhost/php_bugs/hash_bug_md5.php/?foo=QNKCDZO&bar=240610708;


PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0

payload:QNKCDZO 240610708 s878926199a s155964671a s214587387a s214587387a sha1(str) sha1('aaroZmOk') sha1('aaK1STfY') sha1('aaO8zKZF') sha1('aa3OFF9m') 学习于点击打开链接





















猜你喜欢

转载自blog.csdn.net/blackj_liuyun/article/details/79810362