@1kbfree
2018-05-09T00:36:16.000000Z
字数 6964
阅读 10884
代码审计
不显示错误信息:error_reporting(0)
文件包含函数:include()、include_once()、require()、require_once()
开启session:session_start()
是否开启了gpc功能:if( !get_magic_quotes_gpc() ){}
过滤函数:addslashes()
入敏感的内容会被转义(\)
等号用处分类:
1、=:赋值,在逻辑运算时也有效;
2、==:等于运算,但是不比较值的类型;
3、===:完全等于运算,不仅比较值,而且还比较值的类型,只有两者一致才为真。
const用法:
<?php
const name='iamfree';
echo name;
/*
输出:iamfree
*/
?>
htmlspecialchars()函数:
字符 | 替换后 |
---|---|
& (& 符号) | & |
" (双引号) | " ,除非设置了 ENT_NOQUOTES |
' (单引号) | 设置了 ENT_QUOTES 后, ' (如果是 ENT_HTML401) ,或者 ' (如果是 ENT_XML1、ENT_XHTML 或 ENT_HTML5)。 |
< (小于) | < |
> (大于) | > |
extract()函数:
parse_str():
<?php
parse_str('name=iamfree'); //把name变成变量名,iamfree变成变量值
echo $name;//输出iamfree
?>
import_request_variables():
此函数把GET、POST、COOKIE的参数注册为变量,一般不建议开启
注意,只在
PHP4.1
到PHP5.4
之间可用
<?php
$name = 'whoami';
import_request_variables('GP'); //G表示GET、P表示POST如果有C表示COOKIE;这里的GP表示注册GET和POST请求的参数为变量
echo $name;
?>
效果:
array_key_exists():
array_key_exists ( $key , $array )
数组里有键 key 时,array_key_exists() 返回 TRUE。 key 可以是任何能作为数组索引的值。
str_ireplace过滤sql语句:
此函数用法:
将 whoami? 中的 whoami 被 iamfree 替换,也就是说把whoami?里的whoami替换成iamfree所以结果就是iamfree?
这里其实是可以绕过的,比如:
变量覆盖:
难一点的:
<?php
foreach (array( '_GET','_POST' ) as $key => $value) {
foreach ($$value as $_key => $_value){
echo $_key.':'.$_value;
echo "<br >";
}
}
?>
执行后的结果:
define()用法:
<?php
define('t',time()); //把time()的返回值定义为常量(t)
echo t;
?>
三元表达式:
<?php
$name = !empty($_GET['name']) ? $_GET['name'] : '此人无名'; //表示如果$_GET['name']不为空的话就返回$_GET['name']如果为空就返回 此人无名。
echo $name;
?>
还可以有一种判断方法:
<?php
echo 1;
isset($_GET['name']) && exit('exit'); //如果isset($_GET['name'])为真也就是name这个参数存在的时候,会执行exit('exit'),相反,不存在的时候不会执行exit('exit')
echo 2;
?>
name参数不存在时:
name参数存在时:
nl2br()函数:
eval()函数:
代码
<?php
$string = 'cup';
$name = 'coffee';
$str = 'This is a $string with my $name in it.';
echo $str. "\n";
eval("\$str = \"$str\";");
echo $str. "\n";
?>
输出:
This is a $string with my $name in it.
This is a cup with my coffee in it.
explode()函数:
也就是拆分
copy()函数:
copy(source,destination)
参数 | 描述 |
---|---|
source | 必需。规定要复制的文件。 |
destination | 必需。规定复制文件的目的地。 |
将文件从 source 拷贝到 destination。如果成功则返回 TRUE,否则返回 FALSE。
trim()函数:
移除字符串两侧的空格等特殊字符
strcasecmp()函数:
preg_match()函数:
匹配一下i
:
*这里的//
是定界符 ,之需要二处字符一样就可以,比如== -- ?? 等等
但是有些不能做定位符 比如a到z、A到Z、0到9、空格、*
匹配全部英文字母(包括大写):
替换匹配到的内容:
define()函数:
define(name,value,case_insensitive)
参数 | 描叙 |
---|---|
name | 必需。规定常量的名称。 |
value | 必需。规定常量的值。 |
case_insensitive | 可选。规定常量的名称是否对大小写敏感。 |
若设置为 true,则对变量名大小写不敏感。默认是 false(大小写敏感)。
dirname()函数:
dirname(path)
参数 | 描述 |
---|---|
path | 必需。规定要检查的路径。 |
该函数返回去掉文件名后的目录名
iconv()函数:
iconv ( in_charset , out_charset , str )
将字符串 str 从 in_charset 转换编码到 out_charset。
intval()函数:
还可以当防止SQL注入:
reset()函数:
$$变量覆盖:
还有一个很有趣的:
<?php
$g = '_GET';
$g = $$g; //这个时候$$g的第二个$与$g的值拼接了变成了$_GET,第一个$变成了$g,所以$g=$_GET
echo $g['name'];
?>
isset()函数:检测变量是否已设置并且非 NULL
unset()函数:释放给定的变量
parse_ini_file() 解析一个配置文件。
array parse_ini_file ( string $filename [, bool $process_sections = false [, int $scanner_mode = INI_SCANNER_NORMAL ]] )
载入一个由 filename 指定的 ini 文件,并将其中的设置作为一个联合数组返回。
参数 | 用法 |
---|---|
filename | 要解析的 ini 文件的文件名。 |
process_sections | 如果将最后的 process_sections 参数设为 TRUE,将得到一个多维数组,包括了配置文件中每一节的名称和设置。process_sections 的默认值是 FALSE。 |
scanner_mode | Can either be INI_SCANNER_NORMAL (default) or INI_SCANNER_RAW. If INI_SCANNER_RAW is supplied, then option values will not be parsed. |
返回值: 成功时以关联数组 array 返回设置,失败时返回 FALSE。
urldecode()函数,可能会造成urldecode二次注入:
$_FILES用法:
is_numeric()函数:
判断是否为数字,是返回1,不是返回空
dvwa的sql注入的impossible等级源码(dvwa的impossible不存在sql注入):
当然 我看不懂这几行:
$data = $db->prepare( 'SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;' );
$data->bindParam( ':id', $id, PDO::PARAM_INT );
substr()函数:
<?php
$rest = substr("abcdef", -1); // 返回 "f"
$rest = substr("abcdef", -2); // 返回 "ef"
$rest = substr("abcdef", -3, 1); // 返回 "d"
$rest = substr("abcdef", 0, -1); // 返回 "abcde"
$rest = substr("abcdef", 2, -1); // 返回 "cde"
$rest = substr("abcdef", 4, -4); // 返回 ""
$rest = substr("abcdef", -3, -1); // 返回 "de"
?>
strrpos()函数:
<?php
$foo = "0123456789a123456789b123456789c";
var_dump(strrpos($foo, '7', -5)); // 从尾部第 5 个位置开始查找
// 结果: int(17)
var_dump(strrpos($foo, '7', 20)); // 从第 20 个位置开始查找
// 结果: int(27)
var_dump(strrpos($foo, '7', 28)); // 结果: bool(false)
?>
extract()函数:
常见语法:
if(empty($a)) $a = 'hello world'; //如果$a为空,那么它的值为hello world
$s = 'sys'.'tem';
$s('whoami'); //返回desktop-a0iqkh2\iamfree
/*这里就是执行了whoami的命令*/
匿名函数:
$C_F = create_function('$name','return $name;'); //$name的位置是传递什么参数,第二个参数是函数里执行什么代码
echo $C_F('iamfree'); //输出iamfree
回调函数:
function Func($name){
echo "hello $name";
}
call_user_func('Func','iamfree');
/*输出:hello iamfree*/
call_user_func('system','whoami');
/*输出:desktop-a0iqkh2\iamfree*/
命令执行函数:
文件操作函数:
任意文件读取、写入、删除往往是上面几个函数受到了控制(当然还有其他的函数)。
不同的函数在不同的场景有不同的作用和不同的利用手法。
读取:可以读取配置等文件,拿到key
写入:可以写入shell代码相关的内容
删除:可以删除.lock文件而可以重新安装覆盖
bool phpinfo ([ int $what = INFO_ALL ] )
输出 PHP 当前状态的大量信息,包含了PHP编译选项、启用的扩展、PHP版本、服务器信息和环境变量(如果编译为一个模块的话)、PHP环境变量、操作系统版本信息、path变量、配置选项的本地值和主值、HTTP头和PHP授权信息(License)。
bool symlink ( string $target , string $link )
symlink()
对于已有的 target 建立一个名为 link 的符号连接。
string readlink ( string $path )
readlink()
和同名的 C 函数做同样的事,返回符号连接的内容。
string getenv ( string $varname )
获取一个环境变量的值。
bool putenv ( string $setting )
添加 setting 到服务器环境变量。 环境变量仅存活于当前请求期间。 在请求结束时环境会恢复到初始状态。
bool dl ( string $library )
载入指定参数 library 的 PHP 扩展。
配置相关
string ini_get ( string $varname )
成功时返回配置选项的值。
string ini_set ( string $varname , string $newvalue )
string ini_alter ( string $varname , string $newvalue )
设置指定配置选项的值。这个选项会在脚本运行时保持新的值,并在脚本结束时恢复。
void ini_restore ( string $varname )
恢复指定的配置选项到它的原始值。
数字判断
bool is_numeric ( mixed $var )
如果 var 是数字和数字字符串则返回 TRUE,否则返回 FALSE。
仅用is_numeric判断而不用intval转换就有可能插入16进制的字符串到数据库,进而可能导致sql二次注入。
数组相关
bool in_array ( mixed $needle , array $haystack [, bool $strict = FALSE ] )
在 haystack 中搜索 needle,如果没有设置 strict 则使用宽松的比较。
该函数有一个特性,比较之前会进行自动类型转换。
in_array($str,$arr)判断$str是否在$arr数组里
如果 str 是 URL 传递入的查询字符串(query string),则将它解析为变量并设置到当前作用域:
void parse_str ( string $str [, array &$arr ] )
本函数用来将变量从数组中导入到当前的符号表中。检查每个键名看是否可以作为一个合法的变量名,同时也检查和符号表中已有的变量名的冲突:
int extract ( array &$var_array [, int $extract_type = EXTR_OVERWRITE [, string $prefix = NULL ]] )
bool mb_parse_str ( string $encoded_string [, array &$result ] )
解析 GET/POST/COOKIE
数据并设置全局变量。 由于 PHP 不提供原始 POST/COOKIE 数据,目前它仅能够
用于 GET 数据。 它解析了 URL 编码过的数据,检测其编码,并转换编码为内部编码,然后设置其值为 array
的 result 或者全局变量。
bool import_request_variables ( string $types [, string $prefix ] )
将 GET/POST/Cookie
变量导入到全局作用域中。如果你禁止了 register_globals
,但又想用到一些全局变
量,那么此函数就很有用。
<?php
$str = "first=value&arr[]=foo+bar&arr[]=baz";
// 推荐用法
parse_str($str, $output);
echo $output['first']; // value
echo $output['arr'][0]; // foo bar
echo $output['arr'][40]; // baz
// 不建议这么用
parse_str($str);
echo $first; // value
echo $arr[0]; // foo bar
echo $arr[1]; // baz
?>
array glob ( string $pattern [, int $flags = 0 ] )
glob() 函数依照 libc glob() 函数使用的规则寻找所有与 pattern 匹配的文件路径,类似于一般shell所用的规则一样。不进行缩写扩展或参数替代。
var_dump(glob('c*.php')); //列出c开头的PHP文件
返回一个包含所有已定义变量列表的多维数组,这些变量包括环境变量、服务器变量和用户定义的变量:
array get_defined_vars ( void )
返回当前所有已定义的常量名和值。 这包含 define() 函数所创建的,也包含了所有扩展所创建的:
array get_defined_constants ([ bool $categorize = false ] )
返回一个包含所有已定义函数列表的多维数组:
array get_defined_functions ( void )
返回所有被 include、 include_once、 require 和 require_once:
array get_included_files ( void )
rand()函数:
$_REQUEST用法:
file_exists()函数:
检查文件或目录是否存在
exit用法:
多处用在install.php
里,因为成功安装一次之后就能再一次运行安装了,除非将exit删除了。