其他的请读者自行尝试。
超级全局常量
常量值被定义后,在脚本的其他任何地方都不能被改变。
PHP 超级全局变量列表:
- $GLOBALS
$GLOBALS 是一个包含了全部变量的全局组合数组,变量的名字就是数组的键,在一个PHP脚本的全部作用域中都可以访问。
$GLOBALS["___mysqli_ston"]
- $_SERVER
$_SERVER 是一个包含了诸如头信息(header)、路径(path)、以及脚本位置(script locations)等等信息的数组。这个数组中的项目由 Web 服务器创建。
元素/代码 | 描述 |
---|---|
$_SERVER[‘PHP_SELF’] | 当前执行脚本的文件名,与 document root 有关。例如,在地址为 http://example.com/test.php/foo.bar 的脚本中使用 $_SERVER[‘PHP_SELF’] 将得到 /test.php/foo.bar。__FILE__ 常量包含当前(例如包含)文件的完整路径和文件名。 从 PHP 4.3.0 版本开始,如果 PHP 以命令行模式运行,这个变量将包含脚本名。之前的版本该变量不可用。 |
$_SERVER[‘GATEWAY_INTERFACE’] | 服务器使用的 CGI 规范的版本;例如,“CGI/1.1”。 |
$_SERVER[‘SERVER_ADDR’] | 当前运行脚本所在的服务器的 IP 地址。 |
$_SERVER[‘SERVER_NAME’] | 当前运行脚本所在的服务器的主机名。如果脚本运行于虚拟主机中,该名称是由那个虚拟主机所设置的值决定。 |
$_SERVER[‘SERVER_SOFTWARE’] | 服务器标识字符串,在响应请求时的头信息中给出。 (如:Apache/2.2.24) |
$_SERVER[‘SERVER_PROTOCOL’] | 请求页面时通信协议的名称和版本。例如,“HTTP/1.0”。 |
$_SERVER[‘REQUEST_METHOD’] | 访问页面使用的请求方法;例如,“GET”, “HEAD”,“POST”,“PUT”。 |
$_SERVER[‘REQUEST_TIME’] | 请求开始时的时间戳。从 PHP 5.1.0 起可用。 (如:1377687496) |
$_SERVER[‘QUERY_STRING’] | query string(查询字符串),如果有的话,通过它进行页面访问。 |
$_SERVER[‘HTTP_ACCEPT’] | 当前请求头中 Accept: 项的内容,如果存在的话。 |
$_SERVER[‘HTTP_ACCEPT_CHARSET’] | 当前请求头中 Accept-Charset: 项的内容,如果存在的话。例如:“iso-8859-1,*,utf-8”。 |
$_SERVER[‘HTTP_HOST’] | 当前请求头中 Host: 项的内容,如果存在的话。 |
$_SERVER[‘HTTP_REFERER’] | 引导用户代理到当前页的前一页的地址(如果存在)。由 user agent 设置决定。并不是所有的用户代理都会设置该项,有的还提供了修改 HTTP_REFERER 的功能。简言之,该值并不可信。) |
$_SERVER[‘HTTPS’] | 如果脚本是通过 HTTPS 协议被访问,则被设为一个非空的值。 |
$_SERVER[‘REMOTE_ADDR’] | 浏览当前页面的用户的 IP 地址。 |
$_SERVER[‘REMOTE_HOST’] | 浏览当前页面的用户的主机名。DNS 反向解析不依赖于用户的 REMOTE_ADDR。 |
$_SERVER[‘REMOTE_PORT’] | 用户机器上连接到 Web 服务器所使用的端口号。 |
$_SERVER[‘SCRIPT_FILENAME’] | 当前执行脚本的绝对路径。 |
$_SERVER[‘SERVER_ADMIN’] | 该值指明了 Apache 服务器配置文件中的 SERVER_ADMIN 参数。如果脚本运行在一个虚拟主机上,则该值是那个虚拟主机的值。 |
$_SERVER[‘SERVER_PORT’] | Web 服务器使用的端口。默认值为 “80”。如果使用 SSL 安全连接,则这个值为用户设置的 HTTP 端口。 |
$_SERVER[‘SERVER_SIGNATURE’] | 包含了服务器版本和虚拟主机名的字符串。 |
$_SERVER[‘PATH_TRANSLATED’] | 当前脚本所在文件系统(非文档根目录)的基本路径。这是在服务器进行虚拟到真实路径的映像后的结果。 |
$_SERVER[‘SCRIPT_NAME’] | 包含当前脚本的路径。这在页面需要指向自己时非常有用。__FILE__ 常量包含当前脚本(例如包含文件)的完整路径和文件名。 |
$_SERVER[‘SCRIPT_URI’] | URI 用来指定要访问的页面。例如 “/index.html”。 |
- $_REQUEST
用于收集HTML表单提交的数据。
- $_GET
HTML form标签的属性method="get"时,$_GET可以收集URL中发送的数据。
- $_POST
HTML form标签的属性method="post"时,$_POST可以收集表单中发送的数据。
- $_FILES
- $_ENV
- $_COOKIE
- $_SESSION
函数
常用
- array()
创建数组
- bool is_numeric ( mixed $var )
检测变量是否为数字或数字字符串,注意,可以是16进制,字符串转16进制可以绕过。is_numeric函数对于空字符%00,无论是%00放在前后都可以判断为非数值。
由于php是弱类型语言,会使用这个函数来判断一下。
- rand(min,max)
生成随机整数
- sleep(seconds)
延迟执行当前脚本若干秒
- bool isset ( mixed $var [, mixed $… ] )
检测变量是否已设置并且非 NULL
- die(message)
输出一条消息,并退出当前脚本。
- md5()
以下值在md5加密后以0E开头:
- QNKCDZO
- 240610708
- s878926199a
- s155964671a
- s214587387a
可以用于md5相等,但两值不相等的情况
base64_encode()、base64_decode()、sha1()
和 strcmp()
传入数组,返回NULL
字符串相关
正则表达式
- int preg_match ( string $pattern , string $subject)
执行一个正则表达式匹配
匹配
这里需要注意一下 i ,表示大小写不敏感,即php、PHP、PhP都会被过滤掉,有的时候没有写i,黑名单里面有select关键字时,我们可以使用SELECT来绕过。
- mb_substr ( string $str , int $start [, int $length = NULL [, string $encoding = mb_internal_encoding() ]] ) : string
返回字符串的一部分,字符串可以包含中文,substr函数是不能包含中文的。
子串
子字符串位置
- mb_strpos ( string
$haystack
, string$needle
[, int$offset
= 0 [, string$encoding
= mb_internal_encoding() ]] ) : int
查找字符串在另一个字符串中首次出现的位置(汉字占一个位置),如果没有找到字符串则返回 false。类似的还有:
- strpos()-查找字符串在另一字符串中第一次出现的位置(区分大小写,汉字占两个位置)
- strrpos()-查找字符串在另一字符串中最后一次出现的位置(区分大小写)
- stripos()-查找字符串在另一字符串中第一次出现的位置(不区分大小写)
- strripos()-查找字符串在另一字符串中最后一次出现的位置(不区分大小写)
安全问题
由于返回的是false,一旦使用==进行判断,我们可以构造第二个字符串是第一个的开始,即可绕过
<?php
$str1 = "abcd";
$str2 = "ab";
if(strpos($str1,$str2)==false)
{
echo "flag";
}
?>
绕过结果
- str_replace(find,replace,string,count)
替换字符串中的一些字符(区分大小写),注意,可以通过双写或者大小写进行绕过。
- mixed preg_filter ( mixed $pattern , mixed $replacement , mixed $subject [, int KaTeX parse error: Expected 'EOF', got '&' at position 19: …it = -1 [, int &̲count ]] )
执行一个正则表达式搜索和替换。这个就不太好弄了,可能需要编码绕过。
- htmlspecialchars(string,flags,character-set,double_encode)
把一些预定义的字符转换为 HTML 实体。
预定义的字符是:
- & (和号)成为 &
- " (双引号)成为 "
- ’ (单引号)成为 ’
- < (小于)成为 <
-
(大于)成为 >
故可以使用单引号的payload进行绕过。
- strip_tags(string,allow)
剥去字符串中的 HTML、XML 以及 PHP 的标签。
- addslashes(string)
返回在预定义的字符前添加反斜杠的字符串。
预定义字符是:
- 单引号(')
- 双引号(")
- 反斜杠(\)
- NULL
数据库相关
mysqli
- mysqli_connect(host,username,password,dbname,port,socket)
打开一个到 MySQL 服务器的新的连接。
- mysqli_error(connection)
返回最近调用函数的最后一个错误描述。
- mysqli_close(connection)
关闭先前打开的数据库连接。
- mysqli_query(connection,query,resultmode)
执行某个针对数据库的查询
- mysqli_fetch_assoc(result)
从结果集中取得一行作为关联数组
- mysqli_fetch_row(result)
从结果集中取得一行,并作为枚举数组返回
- mysqli_num_rows(result)
返回结果集中行的数量
- mysqli_real_escape_string(connection,escapestring)
转义在 SQL 语句中使用的字符串中的特殊字符,难道转义后我们就没有办法注入了?NO!!!
php官方函数参考手册中写到,会被进行转义的字符包括: NUL (ASCII 0),\n,\r,\,'," 和 Control-Z
.
也就是或如果是数字型注入,例如,payload是 1 and 1=1# ,那么这个函数没有用,因为payload中不包含以上字符。
另外,在调用 mysqli_real_escape_string() 函数之前, 必须先通过调用mysqli_set_charset()函数或者在 MySQL 服务器端设置字符集。如果字符集设置不当,可以通过宽字节注入来进行绕过。
pdo
PHP 数据对象 (PDO) 扩展为PHP访问数据库定义了一个轻量级的一致接口。
PDO 提供了一个数据访问抽象层,这意味着,不管使用哪种数据库,都可以用相同的函数(方法)来查询和获取数据。
- public PDOStatement PDO::prepare ( string $statement [, array $driver_options = array() ] )
为 PDOStatement::execute() 方法准备要执行的SQL语句,SQL语句可以包含零个或多个命名(:name)或问号(?)参数标记,参数在SQL执行时会被替换。这样就没法破坏sql语句的结构,不是拼接,也就是网络安全-SQL注入原理及防御SQL注入中提到的sql注入防御的第一种。
举例:
prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
你以为sql语句是
SELECT first_name, last_name FROM users WHERE user_id = id LIMIT 1;
于是使用 1 or 1=1#作为payload,认为下面的sql语句会被执行
SELECT first_name, last_name FROM users WHERE user_id =
1 or 1=1#
但实际上执行的是
SELECT first_name, last_name FROM users WHERE user_id =
1 or 1=1#LIMIT 1;
或者说 直接判断 1 or 1=1# 是不是数字型参数,不是的话根本就不会去执行,也就安全了。
- bool PDOStatement::bindParam ( mixed KaTeX parse error: Expected 'EOF', got '&' at position 19: …ameter , mixed &̲variable [, int $data_type = PDO::PARAM_STR [, int $length [, mixed $driver_options ]]] )
绑定一个PHP变量到用作预处理的SQL语句中的对应命名占位符或问号占位符。
例如(绑定变量id与prepare里的id):
bindParam( ':id', $id, PDO::PARAM_INT )
- bool PDOStatement::execute ([ array $input_parameters ] )
执行预处理过的语句。
mixed PDOStatement::fetch ([ int $fetch_style [, int $cursor_orientation = PDO::FETCH_ORI_NEXT [, int $cursor_offset = 0 ]]] )
从一个 PDOStatement 对象相关的结果集中获取下一行。
* ```
int PDOStatement::rowCount ( void )
返回上一个由对应的 PDOStatement 对象执行DELETE、 INSERT、或 UPDATE 语句受影响的行数。
伪协议相关
函数
伪协议方法
反序列化漏洞
PHP提供serialize和unserialize函数,将任意类型的数据转换成string类型或者相反。当unserialize函数的参数被用户控制的时候就会形成反序列化漏洞。
serialize函数
serialize() 函数用于序列化对象或数组,并返回一个字符串**,**序列化对象后,可以很方便的将它传递给其他需要它的地方,且其类型和结构不会改变。
string serialize ( mixed $value )
参数
$value: 要序列化的对象或数组。
返回
字符串
unserialize函数
学习路线:
这个方向初期比较容易入门一些,掌握一些基本技术,拿起各种现成的工具就可以开黑了。不过,要想从脚本小子变成黑客大神,这个方向越往后,需要学习和掌握的东西就会越来越多以下是网络渗透需要学习的内容:
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!