Command Injection low
然后尝试执行
原理分析 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?php if ( isset ( $_POST [ 'Submit' ] ) ) { $target = $_REQUEST [ 'ip' ]; if ( stristr ( php_uname ( 's' ), 'Windows NT' ) ) { $cmd = shell_exec ( 'ping ' . $target ); } else { $cmd = shell_exec ( 'ping -c 4 ' . $target ); } echo "<pre>{$cmd} </pre>" ; }?>
这个代码没有做任何措施,直接插入命令就可以直接访问成功
stristr(string,search,before_search) :返回 haystack
字符串从 needle
第一次出现的位置开始到结尾的字符串。stristr — strstr() 函数的忽略大小写版本
stristr(string,search,before_search) :搜索字符串在另一字符串中的第一次出现,返回字符串的剩余部分(从匹配点),如果未找到所搜索的字符串,则返回 FALSE
string 必需。规定被搜索的字符串
search 必需。规定要搜索的字符串 如果该参数是数字,则搜索匹配该数字对应的 ASCII 值的字符
before_search 可选。默认值为 “false” 的布尔值 如果设置为 “true”,它将返回 search 参数第一次出现之前的字符串部分
注意 :
php_uname ($mode) :返回运行 PHP 的系统的有关信息,也就是返回运行 PHP 的操作系统的描述 $mode 是单个字符,用于定义要返回什么信息: ‘a’:此为默认。包含序列 “s n r v m” 里的所有模式 ‘s’:操作系统名称。例如: FreeBSD ‘n’:主机名。例如:DESKTOP-XXXXXXX ‘r’:版本名称,例如: 5.1.2-RELEASE ‘v’:版本信息。操作系统之间有很大的不同 ‘m’:机器类型。例如:i386
array() :用于创建数组 在 PHP 中,有三种类型的数组: 索引数组 - 带有数字索引的数组 关联数组 - 带有指定的键的数组 多维数组 - 包含一个或多个数组的数组 说明: array() 创建数组,带有键和值。如果在规定数组时省略了键,则生成一个整数键,这个 key 从 0 开始,然后以 1 进行递增
要用 array() 创建一个关联数组,可使用 => 来分隔键和值
要创建一个空数组,则不传递参数给 array(): $new = array();
str_replace(find,replace,string,count) :以其他字符替换字符串中的一些字符(区分大小写) find 必需。规定要查找的值 replace 必需。规定替换 find 中的值的值 string 必需。规定被搜索的字符串 count 可选。对替换数进行计数的变量
该函数必须遵循下列规则: 如果搜索的字符串是数组,那么它将返回数组 如果搜索的字符串是数组,那么它将对数组中的每个元素进行查找和替换 如果同时需要对数组进行查找和替换,并且需要执行替换的元素少于查找到的元素的数量,那么多余元素将用空字符串进行替换 如果查找的是数组,而替换的是字符串,那么替代字符串将对所有查找到的值起作用注意:
array_keys(array,value,strict) :返回包含数组中所有键名的一个新数组 array 必需。规定数组 value 可选。您可以指定键值,然后只有该键值对应的键名会被返回
strict 可选。与 value 参数一起使用。可能的值: true - 返回带有指定键值的键名。依赖类型,数字 5 与字符串 “5” 是不同的 false - 默认值。不依赖类型,数字 5 与字符串 “5” 是相同的
medium
127.0.0.1&whoami就能获取
原理分析 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 30 <?php if ( isset ( $_POST [ 'Submit' ] ) ) { $target = $_REQUEST [ 'ip' ]; $substitutions = array ( '&&' => '' , ';' => '' , ); $target = str_replace ( array_keys ( $substitutions ), $substitutions , $target ); if ( stristr ( php_uname ( 's' ), 'Windows NT' ) ) { $cmd = shell_exec ( 'ping ' . $target ); } else { $cmd = shell_exec ( 'ping -c 4 ' . $target ); } echo "<pre>{$cmd} </pre>" ; }?>
可以看的出来这个就是将&&
,;
替换了,我们使用其他的符号就可以了
high
127.0.0.1||whoami1
但是这里没有回显ping 的结果
原理分析 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 30 31 32 33 34 35 36 37 38 <?php if ( isset ( $_POST [ 'Submit' ] ) ) { $target = trim ($_REQUEST [ 'ip' ]); $substitutions = array ( '&' => '' , ';' => '' , '| ' => '' , '-' => '' , '$' => '' , '(' => '' , ')' => '' , '`' => '' , '||' => '' , ); $target = str_replace ( array_keys ( $substitutions ), $substitutions , $target ); if ( stristr ( php_uname ( 's' ), 'Windows NT' ) ) { $cmd = shell_exec ( 'ping ' . $target ); } else { $cmd = shell_exec ( 'ping -c 4 ' . $target ); } echo "<pre>{$cmd} </pre>" ; }?>
疑问为什么使用了过滤||
之后还是可以执行代码?
请注意这个替换的顺序,从上往下的替换,所以当执行到|
的时候,就已经将输入的命令变成了127.0.0.1|whoami
如果|
和||
交换了位置
请注意只有|
的后面是有一个空格的,所以这个时候只要使用127/0.0.1|whoami
就可以绕过去了
Impossible 代码分析 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 30 31 32 33 34 35 36 37 38 39 40 41 <?php if ( isset ( $_POST [ 'Submit' ] ) ) { checkToken ( $_REQUEST [ 'user_token' ], $_SESSION [ 'session_token' ], 'index.php' ); $target = $_REQUEST [ 'ip' ]; $target = stripslashes ( $target ); $octet = explode ( "." , $target ); if ( ( is_numeric ( $octet [0 ] ) ) && ( is_numeric ( $octet [1 ] ) ) && ( is_numeric ( $octet [2 ] ) ) && ( is_numeric ( $octet [3 ] ) ) && ( sizeof ( $octet ) == 4 ) ) { $target = $octet [0 ] . '.' . $octet [1 ] . '.' . $octet [2 ] . '.' . $octet [3 ]; if ( stristr ( php_uname ( 's' ), 'Windows NT' ) ) { $cmd = shell_exec ( 'ping ' . $target ); } else { $cmd = shell_exec ( 'ping -c 4 ' . $target ); } echo "<pre>{$cmd} </pre>" ; } else { echo '<pre>ERROR: You have entered an invalid IP.</pre>' ; } }generateSessionToken ();?>
XSS(DOM) low 直接插入
1 <script > alert ('asdf' )</script >
medium