PHP一些基础知识

参考文章:

CTF-PHP黑魔法 | wh1te (lddp.github.io)

php黑魔法 | 安小琪's blog (npfs06.top)

PHP特性总结 - MuRKuo - 博客园 (cnblogs.com)

谈一谈PHP中关于非法参数名传参问题_arr4y非法传参-CSDN博客

PHP原生类及其利用_php原生类读取文件-CSDN博客

CTF题型总结例题篇_Z3r4y的博客-CSDN博客

PHP中$_SERVER["QUERY_STRING"]函数 - 洒洒 - 博客园 (cnblogs.com)

正则表达式学习笔记(超级详细!!!)| 有用的小知识-CSDN博客


PHP解析特性

php需要将所有参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事:

1.删除空白符

2.将某些字符转换为下划线(点、空格)

原变量名PHP转换后变量名
e_v.a.le_v_a_l
e[v_a.le_v_a.l
e v_a.le_v_a_l
e.v.a.le_v_a_l
e+v_a.le+v_a_l
e]v_a.le]v_a_l

当PHP版本小于8时,如果参数中出现中括号[,中括号会被转换成下划线_,但是会出现转换错误,导致接下来如果该参数名中还有非法字符并不会转换成下划线_。即中括号只能替换一次。

PHP原生类

PHP原生类就是PHP中自带的类。

查找文件的原生类

DirectoryIterator

Directorylterator(glob://*flag*)

FilesystemIterator

这个继承了DirectoryIterator类,利用方法同上。

GlobIterator

无需借助glob://伪协议

 GlobIterator(*flag*)

读取文件的原生类

SplFileObject

该类不支持通配符,所以必须先获取到完整文件名称才行。但是直接加入文件的话,它只会返回文件的第一行字符,如果想要返回文件全部内容的话,需借助php://filter伪协议

SplFileObject(flag.php)

PHP伪协议

php伪协议有file://、php://、glob://、http://、zlib://、ftp://、data://

php://

访问各个输入/输出流(I/O streams),在CTF中经常使用的是php://filter和php://input,php://filter用于读取源码并进行base64编码输出,php://input用于执行php代码。

php://filter中的各种过滤器

字符串过滤器:string.*

压缩过滤器:zlib.*

加密过滤器:mcrypt.*和mdecrypt.*

转换过滤器:

convert.base64-encode和convert.base64-decode
?filename=php://filter/convert.base64-encode/resource=index.php
?filename=php://filter/read=convert.base64-encode/resource=index.php

这样做的好处就是如果不进行编码,文件包含后就不会有输出结果,而是当做php文件执行了,而通过编码后则可以读取文件源码。而使用的convert.base64-encode,就是一种过滤器。

上面两者效果一样,只是read读取需要开启allow_url_open,不需要开启allow_url_include

convert.iconv.<input-encoding>.<output-encoding>

<input-encoding><output-encoding>就是编码方式,有如下几种:

UCS-4*
UCS-4BE
UCS-4LE*
UCS-2
UCS-2BE
UCS-2LE
UTF-32*
UTF-32BE*
UTF-32LE*
UTF-16*
UTF-16BE*
UTF-16LE*
UTF-7
UTF7-IMAP
UTF-8*
ASCII*
EUC-JP*
SJIS*
eucJP-win*
SJIS-win*
ISO-2022-JP
ISO-2022-JP-MS
CP932
CP51932
SJIS-mac (alias: MacJapanese)
SJIS-Mobile#DOCOMO (alias: SJIS-DOCOMO)
SJIS-Mobile#KDDI (alias: SJIS-KDDI)
SJIS-Mobile#SOFTBANK (alias: SJIS-SOFTBANK)
UTF-8-Mobile#DOCOMO (alias: UTF-8-DOCOMO)
UTF-8-Mobile#KDDI-A
UTF-8-Mobile#KDDI-B (alias: UTF-8-KDDI)
UTF-8-Mobile#SOFTBANK (alias: UTF-8-SOFTBANK)
ISO-2022-JP-MOBILE#KDDI (alias: ISO-2022-JP-KDDI)
JIS
JIS-ms
CP50220
CP50220raw
CP50221
CP50222
ISO-8859-1*
ISO-8859-2*
ISO-8859-3*
ISO-8859-4*
ISO-8859-5*
ISO-8859-6*
ISO-8859-7*
ISO-8859-8*
ISO-8859-9*
ISO-8859-10*
ISO-8859-13*
ISO-8859-14*
ISO-8859-15*
ISO-8859-16*
byte2be
byte2le
byte4be
byte4le
BASE64
HTML-ENTITIES (alias: HTML)
7bit
8bit
EUC-CN*
CP936
GB18030
HZ
EUC-TW*
CP950
BIG-5*
EUC-KR*
UHC (alias: CP949)
ISO-2022-KR
Windows-1251 (alias: CP1251)
Windows-1252 (alias: CP1252)
CP866 (alias: IBM866)
KOI8-R*
KOI8-U*
ArmSCII-8 (alias: ArmSCII8)

php://input

php://input用于执行php代码,请求方式为post,可以用来写入一句话木马,例如:

http://127.0.0.1/include.php?file=php://input
[POST DATA部分]
<?php phpinfo(); ?>

data://

<?php
// 打印 "I love PHP"
echo file_get_contents('data://text/plain;base64,SSBsb3ZlIFBIUAo=');
?>

PHP九大全局变量

PHP九大全局变量:$_POST、$_GET、$_FILES、$_COOKIE、$_SESSION、$_REQUEST、$_SERVER、$_GLOBALS、$_ENV

$_SERVER存储当前服务器信息

       $_SERVER["QUERY_STRING"] 获取查询语句,实例中可知,获取的是?后面的值

  $_SERVER["REQUEST_URI"] 获取http://www.xxx.com后面的值,包括/

  $_SERVER["SCRIPT_NAME"] 获取当前脚本的路径,如:index.php

  $_SERVER["PHP_SELF"] 当前正在执行脚本的文件名

$_REQUEST默认情况下包含了 $_GET,$_POST 和 $_COOKIE 的数组。

要求变量原值不同但MD5或sha1相同

1.如果是用==判断:用0e开头的哈希值变量

原理:PHP在处理哈希字符串时,会利用"!="或"=="来对哈希值进行比较,它把每一个以“0e"开头的哈希值都解释为0,所以如果两个不同的字符串经过哈希以后,其哈希值都是以”0e“开头的,那么PHP将会认为他们相同,都是0

原字符串MD5值(32个十六进制,共128位)
s878926199a0e545993274517709034328855841020
s155964671a0e342768416822451524974117254469
s214587387a0e848240448830537924465865611904
s214587387a0e848240448830537924465865611904
原字符串Sha1(40个十六进制,共160位)
109324351120e07766915004133176347055865026311692244
aaroZmOk0e66507019969427134894567494305185566735
aaK1STfY0e76658526655756207688271159624026011393
aaO8zKZF0e89257456677279068558073954252716165668
aa3OFF9m0e36977786278517984959260394024281014729

2.如果是用===判断,利用数组绕过 

当MD5函数与sha1函数对参数进行加密处理时,如果碰到一个数组,MD5和sha1都会返回null,而null===null返回true,所以可以绕过判断。

如果不能输入数组,只能输入字符串,就是真实的MD5碰撞,以下两个字符串在经过URL解码后进行hash计算MD5值会相同。

a=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%00%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%55%5d%83%60%fb%5f%07%fe%a2
&b=%4d%c9%68%ff%0e%e3%5c%20%95%72%d4%77%7b%72%15%87%d3%6f%a7%b2%1b%dc%56%b7%4a%3d%c0%78%3e%7b%95%18%af%bf%a2%02%a8%28%4b%f3%6e%8e%4b%55%b3%5f%42%75%93%d8%49%67%6d%a0%d1%d5%5d%83%60%fb%5f%07%fe%a2

数字比较

NULL,0,‘0’,array()使用==和false比较时,都是会返回true的。

若字符串以数字开头,则取开头数字作为转换结果,若无则输出0

函数缺陷和绕过 

strcmp函数 

        strcmp(str1,str2)如果str1小于str2返回小于0;如果str1大于str2返回大于0;如果两者相等,返回0。

        在php5.3之前,若传入的是一个非字符串类型数据,比如数组和对象,这个函数将发生错误,显示了报错的警告信息后,将返回0。传入一个数组会返回NULL,NULL==0是返回true,这样就成功绕过。 

is_numeric函数

该函数用于检测变量是否为数字或数字字符串。如果指定的变量是数字和数字字符串则返回true,否则返回false。但是函数的范围比较广泛,不仅仅是十进制的数字,它还可以识别其他进制的数字字符串,以及科学计数法表示的数字等。

当在使用sql语句前,用is_numberic函数判断变量是否为数字,然后带入数据库查询

insert into test(type) values(0x31206f722031)

如果再重新查询这个表的字段出来,不做过滤带入另一个sql语句,将会造成2次注入。

preg_match函数 

preg_math用于执行一个正则表达式匹配,匹配到了就会返回true,没匹配到就返回false

1.数组绕过

2.利用PCRE回溯次数限制绕过

让回溯次数超过最大限制就可以使preg_match返回false,从而绕过限制,中文的回溯次数在100万次就会超过。

3.换行符%0a绕过

正则表达式学习

正则表达式学习笔记(超级详细!!!)| 有用的小知识-CSDN博客

正则表达式练习网站

正则表达式主要依赖于元字符。元字符不代表他们本身的字面意思,他们都有特殊的含义。一些元字符写在方括号中的时候有一些特殊的意思

元字符描述
.匹配任意单个字符,但不匹配换行符。
[ ]字符种类。匹配方括号内的任意字符。
[^ ]^ 表示一个字符串的开头,但它用在一个方括号的开头的时候,它表示这个字符集是否定的。
*匹配>=0个重复的在*号之前的字符。
+匹配>=1个重复的+号前的字符
?标记在符号前面的字符为可选,即出现 0 或 1 次
{n,m}匹配num个大括号之前的字符或字符集(n<=num<=m)
(xyz)匹配与xyz完全相等的字符串
|或运算符,匹配符号前或后的字符
\用于指定 { } [ ] / \ + * . $ ^ | ? 这些特殊字符。如果想要匹配这些特殊字符则要在其前面加上反斜线 \。
^从开始行开始匹配
$从末端开始匹配
简写描述
\w匹配所有字母数字,等同于[a-zA-Z0-9_]
\W匹配所有非字母数字,等同于:[^\w]
\d匹配数字:[0-9]
\D匹配非数字:[^\d]
\s匹配所有空格字符,等同于:[\t\n\f\r\p{Z}]
\S匹配所有非空格字符:[^\s]
\f匹配一个换页符
\n匹配一个换行符
\r匹配一个回车符
\t匹配一个制表符
\p匹配CR/LF(等同于\r\n),用来匹配DOS行终止符
标志描述
i忽略大小写
g全局搜索,即(不仅仅返回第一个匹配的,而是返回全部)
m多行修饰符:锚点元字符^&工作范围在每行的起始

变量覆盖

1.变量覆盖漏洞介绍:

        变量覆盖就是通过外部输入将某个变量的值给覆盖掉。将自定义的参数值替换掉原有变量值的情况就是变量覆盖漏洞。

2.常见的可导致变量覆盖的函数或者因素有:

  • register_globals
  • extract()
  • parse_str()
  • mb_parse_str()
  • import_request_variables()
  • $$

3.$_REQUEST的覆盖顺序是EGPCS

EGPCS是Environment,Get,Post,Cookie,Server,

对应的超级变量是$_ENV,$_GET,$_POST,$_COOKIE,$_SERVER

即对应同一个变量,后面的post的值会覆盖get的值

  • 20
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值