进入题目一个登录框
对登录框做了一些常规的sql注入和fuzz发现都无果。然后在等级登录后跳转的search.php页面查看源代码发现一段编码。
MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5
发现其是一段base32编码,解码后发现又是一段base64编码。
c2VsZWN0ICogZnJvbSB1c2VyIHdoZXJlIHVzZXJuYW1lID0gJyRuYW1lJw==
然后base64解码
select * from user where username = '$name'
所以知道了sql语句为select * from user where username = '$name',然后用联合查询进行测试字段数。
两个字段发现报错
三个字段不报错,证明sql查询一共又三个字段。
根据提示可以知道是pass密码错误,所以是又admin这个账号的,那我们接下来测试用户这个字段到底在哪一个字段当中。
测试1' union select 'admin',2,3#发现user错误
测试1' union select 1,'admin',3#,发现是pass密码错误,所以知道第2个字段为user字段
然后这里卡了好久,不知到search.php到底是怎么写的,然后直接看了下search.php的源代码,做题的时候源代码应该是看不到的,这里是buuctf为标明题目出处放在这的。
<!--MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5-->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Do you know who am I?</title>
<?php
require "config.php";
require "flag.php";
// 去除转义
if (get_magic_quotes_gpc()) {
function stripslashes_deep($value)
{
$value = is_array($value) ?
array_map('stripslashes_deep', $value) :
stripslashes($value);
return $value;
}
$_POST = array_map('stripslashes_deep', $_POST);
$_GET = array_map('stripslashes_deep', $_GET);
$_COOKIE = array_map('stripslashes_deep', $_COOKIE);
$_REQUEST = array_map('stripslashes_deep', $_REQUEST);
}
mysqli_query($con,'SET NAMES UTF8');
$name = $_POST['name'];
$password = $_POST['pw'];
$t_pw = md5($password);
$sql = "select * from user where username = '".$name."'";
$result = mysqli_query($con, $sql);
if(preg_match("/\(|\)|\=|or/", $name)){
die("do not hack me!");
}
else{
if (!$result) {
printf("Error: %s\n", mysqli_error($con));
exit();
}
else{
$arr = mysqli_fetch_row($result);
if($arr[1] == "admin"){
if(md5($password) == $arr[2]){
echo $flag;
}
else{
die("wrong pass!");
}
}
else{
die("wrong user!");
}
}
}
?>
然后发现password有被MD5进行加密,他喵的,这题目出的,一点提示也没有。
if($arr[1] == "admin"){
if(md5($password) == $arr[2]){
echo $flag;
}
else{
die("wrong pass!");
}
}
else{
die("wrong user!");
知道了MD5加密了password后,那就是将查询出来的passwd和输入的密码的md5值比较,相等则登录得到flag不相等则wrong pass。
就是我们的sql语句执行时,password字段中的内容要==md5(我们密码栏输入的password)。接下里就是要绕过密码的md5验证,需要把我们输入的值和数据库里面存放的用户密码的md5值进行比较,那要怎么绕过呢?可以用联合查询语句用来生成虚拟的表数据。
学到了联合注入有个技巧。在联合查询并不存在的数据时,联合查询就会构造一个 虚拟的数据。 举个例子:
最初users表中只有一行数据,
我们通过union select查询就可以构造一行虚拟的数据,
如上图,我们在users表中利用联合查询创建了一行虚拟的数据。
我们的思路就来了,我们可以利用联合查询来创建一行admin账户的续集数据,混淆admin用户的密码,将我们自定义的admin用户的密码(123)加进去,这样我们不就可以登录admin用户了吗。
在用户名登录框输入1' union select 1,'admin','202cb962ac59075b964b07152d234b70'#其中202cb962ac59075b964b07152d234b70为123的MD5值,然后在密码登录框中输入123即可登录。
__EOF__