本文承接上文PHP代码审计-萌新之路(一),由于博主也是萌新,自然也有不会做的题目,当然等博主技术足够之后是会补充回来的。
error_reporting(0);
if (!isset($_POST['uname']) || !isset($_POST['pwd'])) {
echo '."
";
echo ''."
";
echo ''."
";
echo ''."
";
echo ''."
";
echo ''."
";
die;
}
function AttackFilter($StrKey,$StrValue,$ArrReq){
if (is_array($StrValue)){
//检测变量是否是数组
$StrValue=implode($StrValue);
//返回由数组元素组合成的字符串
}
if (preg_match("/".$ArrReq."/is",$StrValue)==1){
//匹配成功一次后就会停止匹配
print "水可载舟,亦可赛艇!";
exit();
}
}
$filter = "and|select|from|where|union|join|sleep|benchmark|,|\(|\)";
foreach($_POST as $key=>$value){
//遍历数组
AttackFilter($key,$value,$filter);
}
$con = mysql_connect("XXXXXX","XXXXXX","XXXXXX");
if (!$con){
die('Could not connect: ' . mysql_error());
}
$db="XXXXXX";
mysql_select_db($db, $con);
//设置活动的 MySQL 数据库
$sql="SELECT * FROM interest WHERE uname = '{$_POST['uname']}'";
$query = mysql_query($sql);
//执行一条 MySQL 查询
if (mysql_num_rows($query) == 1) {
//返回结果集中行的数目
$key = mysql_fetch_array($query);
//返回根据从结果集取得的行生成的数组,如果没有更多行则返回 false
if($key['pwd'] == $_POST['pwd']) {
print "CTF{XXXXXX}";
}else{
print "亦可赛艇!";
}
}else{
print "一颗赛艇!";
}
mysql_close($con);
?>
待定
$flag = "flag";
if (isset ($_GET['password']))
{
if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE)
{
echo 'You password must be alphanumeric
';
}
else if (strlen($_GET['password']) < 8 && $_GET['password'] > 9999999)
{
if (strpos ($_GET['password'], '*-*') !== FALSE) //strpos — 查找字符串首次出现的位置
{
die('Flag: ' . $flag);
}
else
{
echo('*-* have not been found
');
}
}
else
{
echo 'Invalid password
';
}
}
?>
这里有四个判断,还是比较简单的
第一个判断,password参数是否存在
第二个判断ereg函数()用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字母的字符是大小写敏感的。(不敏感就是eregi函数)
也就是我们传入的password必须是字母和数字,好那么看到第三个判断
我们传入的数字位数得小于八位而且得大于9999999,这里我们可以构造科学计数法,也就是1e9
最后一个判断就是查找字符串在password参数里是否存在*—,存在即输出flag
这里第一种解法:
ereg正则%00截断(原理:ereg读到%00的时候,就截止了)
由于ereg只能传入数字和字母所以-*传入肯定是不行的,我们构造
\?password=1e9%00*-*
将*-给截断,ereg函数就不会读后面这个-*了
第二种解法:
传入一个password数组
\?password[]=1
ereg函数只能处理字符串,而password被我们传入了数组,所以返回值是null,全等不会进行类型转换,所以null!==false
而strops()函数也只能处理字符串,所以 NULL!==flase也成立,数组判断大小是直接返回true的。
$flag = "flag";
if (isset($_GET['a'])) {
if (strcmp($_GET['a'], $flag) == 0) //如果 str1 小于 str2 返回 < 0; 如果 str1大于 str2返回 > 0;如果两者相等,返回 0。
//比较两个字符串(区分大小写)
die('Flag: '.$flag);
else
print 'No';
}
?>
strcmp()函数判断数组也是返回NULL,而NULL==0 是 bool(true)的,可以自己var_dump试试
所以payload:
/?a[]=1
$flag = "flag";
if (isset($_GET['name']) and isset($_GET['password']))
{
if ($_GET['name'] == $_GET['password'])
echo 'Your password can not be your name!
';
else if (sha1($_GET['name']) === sha1($_GET['password']))
die('Flag: '.$flag);
else
echo 'Invalid password.
';
}
else
echo 'Login first!
';
?>
sha1这个函数也一样
举个例子
$a = array(1);
$b = array(2);
var_dump(sha1($a)===sha1($b));
遇事不决,var_dump
故此题payload:
/?name[]=1&password[]=2
$flag = "flag";
session_start();
if (isset ($_GET['password'])) {
if ($_GET['password'] == $_SESSION['password'])
die ('Flag: '.$flag);
else
print 'Wrong guess.
';
}
mt_srand((microtime() ^ rand(1, 10000)) % rand(1, 10000) + rand(1, 10000));
?>
当传入的password==session的password的时候输出flag
删除cookies或者删除cookies的值,然后将password值传为空就可以
/?password=
//配置数据库
if($_POST[user] && $_POST[pass]) {
$conn = mysql_connect("********, "*****", "********");
mysql_select_db("phpformysql") or die("Could not select database");
if ($conn->connect_error) {
die("Connection failed: " . mysql_error($conn));
}
//赋值
$user = $_POST[user];
$pass = md5($_POST[pass]);
//sql语句
// select pw from php where user='' union select 'e10adc3949ba59abbe56e057f20f883e' #
// ?user=' union select 'e10adc3949ba59abbe56e057f20f883e' #&pass=123456
$sql = "select pw from php where user='$user'";
$query = mysql_query($sql);
if (!$query) {
printf("Error: %s\n", mysql_error($conn));
exit();
}
$row = mysql_fetch_array($query, MYSQL_ASSOC);
//echo $row["pw"];
if (($row[pw]) && (!strcasecmp($pass, $row[pw]))) {
//如果 str1 小于 str2 返回 < 0; 如果 str1 大于 str2 返回 > 0;如果两者相等,返回 0。
echo "<p>Logged in! Key:************** </p>";
}
else {
echo("<p>Log in failure!</p>");
}
}
?>
待定
if(eregi("hackerDJ",$_GET[id])) {
echo("not allowed!
");
exit();
}
$_GET[id] = urldecode($_GET[id]);
if($_GET[id] == "hackerDJ")
{
echo "Access granted!
";
echo "flag: *****************}
";
}
?>
可以看到这里进行了一个urldecode操作,那么我们只需要将h进行两次url编码,然后将%进行url编码就可以绕过了,因为浏览器会进行一次url解码,构造id=%2568ackerDJ,%25会被解码为%和68进行拼接,然后经过urldecode就是h和后面ackerDJ拼接满足条件输出flag。
if($_POST[user] && $_POST[pass]) {
$conn = mysql_connect("*******", "****", "****");
mysql_select_db("****") or die("Could not select database");
if ($conn->connect_error) {
die("Connection failed: " . mysql_error($conn));
}
$user = $_POST[user];
$pass = md5($_POST[pass]);
//select user from php where (user='admin')#
//exp:admin')#
$sql = "select user from php where (user='$user') and (pw='$pass')";
$query = mysql_query($sql);
if (!$query) {
printf("Error: %s\n", mysql_error($conn));
exit();
}
$row = mysql_fetch_array($query, MYSQL_ASSOC);
//echo $row["pw"];
if($row['user']=="admin") {
echo "Logged in! Key: ***********
";
}
if($row['user'] != "admin") {
echo("You are not admin!
");
}
}
?>
可以看到,当$row[‘user’]=='admin’时,就会输出flag。
这里我们把几个操纵MySQL数据库的函数总结一下
mysql_connect() 函数打开非持久的 MySQL 连接。
mysql_select_db() 函数设置活动的 MySQL 数据库。
mysql_query() 函数执行一条 MySQL 查询。
mysql_fetch_array() 函数从结果集中取得一行作为关联数组
看看这条sql语句
select user from php where (user='$user') and (pw='$pass')
也就是说,我们可以post传入user变量为
admin') #
就可以成功使$row['user']=='admin'
即可获取flag
放心,还会有续集的,点赞和评论将会作为我写作最大动力,虽说白嫖很香,但是点赞和评论应该不算很麻烦,当然前提是您觉得我这篇文章写的不错,对您有用。如果觉得写的还行,请动动小手给我一个小小的赞,谢谢