@1kbfree
        
        2018-05-08T16:36:16.000000Z
        字数 6964
        阅读 11142
    代码审计
不显示错误信息:error_reporting(0)
文件包含函数:include()、include_once()、require()、require_once()
开启session:session_start()
是否开启了gpc功能:if( !get_magic_quotes_gpc() ){}
过滤函数:addslashes()入敏感的内容会被转义(\)
等号用处分类:
1、=:赋值,在逻辑运算时也有效;2、==:等于运算,但是不比较值的类型;3、===:完全等于运算,不仅比较值,而且还比较值的类型,只有两者一致才为真。
const用法:
<?phpconst name='iamfree';echo name;/*输出:iamfree*/?>
htmlspecialchars()函数: 

| 字符 | 替换后 | 
|---|---|
| & (& 符号) | & | 
| " (双引号) | ",除非设置了 ENT_NOQUOTES | 
| ' (单引号) | 设置了 ENT_QUOTES 后, ' (如果是 ENT_HTML401) ,或者 ' (如果是 ENT_XML1、ENT_XHTML 或 ENT_HTML5)。 | 
| < (小于) | < | 
| > (大于) | > | 
extract()函数: 

parse_str():
<?phpparse_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?
这里其实是可以绕过的,比如: 

变量覆盖: 
 

难一点的:
<?phpforeach (array( '_GET','_POST' ) as $key => $value) {foreach ($$value as $_key => $_value){echo $_key.':'.$_value;echo "<br >";}}?>
执行后的结果: 

define()用法:
<?phpdefine('t',time()); //把time()的返回值定义为常量(t)echo t;?>

三元表达式:
<?php$name = !empty($_GET['name']) ? $_GET['name'] : '此人无名'; //表示如果$_GET['name']不为空的话就返回$_GET['name']如果为空就返回 此人无名。echo $name;?>
还可以有一种判断方法:
<?phpecho 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=$_GETecho $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']; // valueecho $output['arr'][0]; // foo barecho $output['arr'][40]; // baz// 不建议这么用parse_str($str);echo $first; // valueecho $arr[0]; // foo barecho $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删除了。