bugku代码审计
第一题
PHP extract() 函数:https://www.w3school.com.cn/php/func_array_extract.asp
解法:?shiyan=&flag
判断一个变量是否已经声明的时候 可以使用 isset 函数
判断一个变量是否已经赋予数据且不为空 可以用 empty 函数
判断 一个变量 存在且不为空 先isset 函数 再用 empty 函数
第二题
strcmp()函数漏洞 如strcmp ( string $str1 , string $str2 )
参数 str1第一个字符串。str2第二个字符串。如果 str1 小于 str2 返回 < 0;
如果 str1 大于 str2 返回 > 0;
如果两者相等,返回 0。
**当这个函数接受到了不符合的类型,这个函数将发生错误 将return 0 !!! 也就是虽然报了错,但却判定其相等了。
(在5.3之前的php可以用这个漏洞)
解法:只要传入一个非字符串类型的变量即可,一般情况下,我们我们传数组,所以payload为:?a[]=123
第三题
PHP 函数 eregi()
eregi(string pattern, string string, [array regs]);
eregi()函数在一个字符串搜索指定的模式的字符串。搜索不区分大小写
如果匹配成功返回true,否则,则返回false
URL编码查询地址https://www.w3school.com.cn/tags/html_ref_urlencode.html
解法:对 hackerDJ 这个字符串的任意字母进行二次url编码 构造
?id=hacker%2544J
第四题
1、md5不是加密算法,只是hash算法
2、md5碰撞(就是你说的值相同)几率非常非常非常低
3、一般的后台都不会直接密码一次md5,而是加盐后md5,甚至多次md5,防止脱库
(意思就是就算有人把整个数据库拿走,用户的密码明文都不会泄露)
md5(string,raw) raw可选,规定十六进制或二进制输出格式:TRUE - 原始 16 字符二进制格式,FALSE - 默认。32 字符十六进制数
本题解法:
①PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,
所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0
②简单搜索一下关于md5()的缺陷,发现,原来md5没有办法处理数组格式的 ?username[]=1&password[]=2
QNKCDZO
0e830400451993494058024219903391
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
第五题
这里ereg有两个漏洞:
①%00截断及遇到%00则默认为字符串的结束
②当变量为数组时它的返回值不是FALSE
PHP strpos() 函数
strpos() f函数查找字符串在另一字符串中第一次出现的位置(区分大小写)。
查找 “php” 在字符串中第一次出现的位置:
<?php
echo strpos("I love php, I love php too!","php");
?>
结果 7
解法:本题只要构造?password[]=–
第六题
PHP is_numeric() 函数
is_numeric() 函数用于检测变量是否为数字或数字字符串(PHP 版本要求:PHP 4, PHP 5, PHP 7)
如果指定的变量是数字和数字字符串则返回 TRUE,否则返回 FALSE。
is_numeric函数对于空字符%00,无论是%00放在前后都可以判断为非数值,而%20空格字符只能放在数值后。
所以,查看函数发现该函数对对于第一个空格字符会跳过空格字符判断,接着后面的判断!
关于此函数sql注入漏洞https://www.cnblogs.com/windclouds/p/5413115.html
本题解法三种:
?password=9999%00 ?password[]=1 ?password=9999a
第七题
①var_dump() 函数用于输出变量的相关信息。
var_dump() 函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。
PHP 版本要求: PHP 4, PHP 5, PHP 7
②PHP sha1() 函数
sha1() 函数计算字符串的 SHA-1 散列。
sha1(string,raw)
string :必需。规定要计算的字符串。
raw:可选,规定十六进制或二进制输出格式:TRUE - 原始 20 字符二进制格式 FALSE - 默认。40 字符十六进制数
解法:sha跟md5函数一样,可以用数组绕过 ?name[]&password[]=123123来绕过
第八题
代码中,
a
=
@
a=@
a=@_GET[“a”]; 其中的 @ 是为了防止没有 $_GET[‘a’]出现错误提示.
但是 @ 的代价过高, 一般都用 isset() 来判断一下.比较通俗的写法是:
if (isset($_GET['a'] ))
{
$a = $_GET['a'] ;
}else
{
$a = null;
}
比较简洁的写法是.
a
=
i
s
s
e
t
(
a = isset(
a=isset(_GET[‘a’]) ? $_GET[‘a’] : null ;
解法:?a=s214587387a
第九题
首先分析代码,函数要求变量
t
e
m
p
不
能
存
在
1
9
之
间
的
数
字
,
最
后
,
又
要
求
temp不能存在1~9之间的数字, 最后,又要求
temp不能存在1 9之间的数字,最后,又要求temp=3735929054;
这本来是自相矛盾的,但php在转码时会把16进制转化为十进制.于是把
3735929054转换成16进制为0xdeadc0de
解法 ?password=0xdeadc0de
第十题暂缺
第十一题
①利用数组绕过这两个函数
ereg() 只能处理字符串,而password是数组,所以返回的是null,三个等号的时候不会进行类型转换。所以null!==false。
strpos() 的参数同样不能够是数组,所以返回的依旧是null,null!==false也正确。?password[]=1
②判断是不是长度<8且>9999999,判断是不是有“-”?password=1e9%00*-*
第十二题
?ctf[]=1
第十三题
PHP preg_match() 函数
返回值如下
returns 1; // 如果匹配到.
returns 0; // 如果未匹配到.
returns FALSE; // 发生错误时.
int preg_match ( string $pattern , string KaTeX parse error: Expected 'EOF', got '&' at position 18: …bject [, array &̲matches [, int $flags = 0 [, int $offset = 0 ]]] )
$pattern: 要搜索的模式,字符串形式。
$subject: 输入字符串。
m
a
t
c
h
e
s
:
如
果
提
供
了
参
数
m
a
t
c
h
e
s
,
它
将
被
填
充
为
搜
索
结
果
matches: 如果提供了参数matches,它将被填充为搜索结果
matches:如果提供了参数matches,它将被填充为搜索结果matches[0]将包含完整模式匹配到的文本,$matches[1] 将包含第一个捕获子组匹配到的文本,以此类推。
$flags:flags 可以被设置为以下标记值:
①PREG_OFFSET_CAPTURE: 如果传递了这个标记,对于每一个出现的匹配返回时会附加字符串偏移量(相对于目标字符串的)。
注意:这会改变填充到matches参数的数组,使其每个元素成为一个由 第0个元素是匹配到的字符串,第1个元素是该匹配字符串 在目标字符串subject中的偏移量。
②offset: 通常,搜索从目标字符串的开始位置开始。可选参数 offset 用于 指定从目标字符串的某个未知开始搜索(单位是字节)。
本题解法:利用preg_match()函数不能处理数组进行构造payload:password[]=
第十四题暂缺
PHP中常见的函数
①PHP substr() 函数 substr(string,start,length)
substr() 函数返回字符串的一部分
string:必需。规定在字符串的何处开始。
start :必需,规定在字符串的何处开始。
正数 - 在字符串的指定位置开始
负数 - 在从字符串结尾开始的指定位置开始
0 - 在字符串中的第一个字符处开始
length: 可选,规定被返回字符串的长度。默认是直到字符串的结尾。
正数 - 从 start 参数所在的位置返回的长度
负数 - 从字符串末端返回的长度
②PHP file_get_contents() 函数 file_get_contents(path,include_path,context,start,max_length)
file_get_contents() 把整个文件读入一个字符串中。该函数是用于把文件的内容读入到一个字符串中的首选方法。
path:必需。规定要读取的文件。
include_path:可选。如果您还想在 include_path(在 php.ini 中)中搜索文件的话,请设置该参数为 ‘1’。
context :可选。规定文件句柄的环境。context 是一套可以修改流的行为的选项。若使用 NULL,则忽略。
start :可选。规定在文件中开始读取的位置。该参数是 PHP 5.1 中新增的。
max_length:可选。规定读取的字节数。该参数是 PHP 5.1 中新增的。