扫描 GraphQL API 以查找漏洞

Andrew2020-11-06 11:57:39

自2020年6月以来,Acunetix支持日益流行的API查询语言– GraphQL。在本文中,想逐步向您展示如何扫描使用GraphQL定义的API。为此,您将首先创建一个故意易受攻击的API及其GraphQL定义,然后使用Acunetix对其进行扫描,消除使用Acunetix发现的严重漏洞,并确认已消除了这些漏洞。

阶段1:设置测试环境

为了能够进行此练习,在测试之前必须准备一个测试环境。在本练习中,我们将Windows操作系统与开源软件一起使用。

  1. 使用PHP和MySQL将Wamp64安装为本地Web服务器
  2. 将Windows路径环境变量设置为指向您的PHP和MySQL可执行文件:
    • 运行Windows可执行文件systempropertiesadvanced.exe
    • 转到高级选项卡
    • 单击环境变量
    • 将您的php.exe文件夹和mysql.exe文件夹添加到路径列表;要添加的典型值是:
      • c:\ wamp64 \ bin \ php \ php7.3.21
      • c:\ wamp64 \ bin \ mysql \ mysql5.7.31 \ bin
  3. 安装适用于PHP的Composer依赖性管理器

阶段2:建立简单的GraphQL API

要使用Acunetix扫描GraphQL API,您将构建一个简单的,易受攻击的API。要构建API,您需要执行以下步骤:

  1. 在Web服务器上创建数据库以存储数据
  2. 创建一个Web服务根文件夹并安装一些依赖库
  3. 创建一个GraphQL模式文件
  4. 创建一个GraphQL模式加载器文件
  5. 创建索引文件以处理GraphQL请求
  6. 创建一个解析器文件

步骤1:在Web服务器上创建数据库

要在Wamp64 Web服务器上设置数据库,请执行以下操作

  1. 打开命令提示符

  2. 运行mysql -u root

  3. 在MySQL根目录提示符下运行以下命令:

    mysql> create user 'graphuser'@'localhost' identified by 'graphuserpass';
    mysql> create database graphusersdb;
    mysql> GRANT ALL PRIVILEGES ON graphusersdb.* TO 'graphuser'@'localhost';
    mysql> use graphusersdb;
    mysql> CREATE TABLE `users` (`id` int(11) NOT NULL AUTO_INCREMENT,`fname` varchar(255) NOT NULL, `lname` varchar(255) NOT NULL, `email` varchar(255) NOT NULL, `notes` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`));
    mysql> INSERT INTO users (fname, lname, email) VALUES ('John', 'Smith', 'john@example.com');
    mysql> INSERT INTO users (fname, lname, email) VALUES ('Jane', 'Doe', 'jane@example.com');
    

步骤2:创建Web服务根文件夹

要创建Web服务根文件夹,请执行以下操作:

  1. 打开命令提示符

  2. 运行以下命令为您的项目创建文件夹,包括PHP库依赖项:

    C:\>mkdir C:\wamp64\www\graphusers
    C:\>cd C:\wamp64\www\graphusers
    C:\wamp64\www\graphusers>composer require leocavalcante/siler
    C:\wamp64\www\graphusers>composer require overblog/dataloader-php
    C:\wamp64\www\graphusers>composer require webonyx/graphql-php
    

步骤3:创建一个GraphQL模式文件

创建具有以下内容的C:\ wamp64 \ www \ graphusers \ schema.graphql文件:

type Query {
  getUser(email: String): [User]
}

type Mutation {
  addUser(fname: String, lname: String, email: String, notes: String): [User]
  deluser(email: String): [User]
}

type User {
  id: Int
  fname: String
  lname: String
  email: String
  notes: String
}

步骤4:创建GraphQL模式加载器文件

创建具有以下内容的C:\ wamp64 \ www \ graphusers \ schema.php文件:

<?php

use Siler\Graphql;

$typeDefs = file_get_contents(__DIR__.'/schema.graphql');
$resolvers = include __DIR__.'/resolvers.php';

return Graphql\schema($typeDefs, $resolvers);

步骤5:创建索引文件以处理GraphQL请求

创建具有以下内容的C:\ wamp64 \ www \ graphusers \ index.php文件:

<?php

require_once 'vendor/autoload.php';

use Siler\Graphql;
use GraphQL\GraphQL as WGraphql;
use Siler\Http\Request;
use Siler\Http\Response;
use Overblog\DataLoader\DataLoader;
use Overblog\DataLoader\Promise\Adapter\Webonyx\GraphQL\SyncPromiseAdapter;
use Overblog\PromiseAdapter\Adapter\WebonyxGraphQLSyncPromiseAdapter;

try {
     $MyDB = new PDO("mysql:host=localhost;dbname=graphusersdb;charset=utf8mb4", "graphuser", "graphuserpass");
} catch (\PDOException $e) {
     throw new \PDOException($e->getMessage(), (int)$e->getCode());
}function select_sql($query, $sql_args) {
    global $MyDB;
    $stmt = $MyDB->prepare($query);
    $stmt->execute($sql_args);
    $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
    return $rows;
}function insert_sql($query, $sql_args) {
    global $MyDB;
    $stmt = $MyDB->prepare($query);
    return $stmt->execute($sql_args); // true if successful; false if not successful 
}function delete_sql($query, $sql_args) {
    global $MyDB;
    $stmt = $MyDB->prepare($query);
    return $stmt->execute($sql_args); // true if successful; false if not successful 
}

$graphQLSyncPromiseAdapter = new SyncPromiseAdapter();
$promiseAdapter = new WebonyxGraphQLSyncPromiseAdapter($graphQLSyncPromiseAdapter);

WGraphQL::setPromiseAdapter($graphQLSyncPromiseAdapter);

$context = [
    'select_sql' => function ($query, $sql_args) { return select_sql($query, $sql_args); },
    'insert_sql' => function ($query, $sql_args) { return insert_sql($query, $sql_args); },
    'delete_sql' => function ($query, $sql_args) { return delete_sql($query, $sql_args); },
];

if (Request\method_is('post')) {
    $schema = include __DIR__.'/schema.php';
    Graphql\init($schema, null, $context);
}

步骤6:创建解析器文件

创建具有以下内容的C:\ wamp64 \ www \ graphusers \ resolvers.php文件:

<?php

return [
  'Query' => [
    getUser' => function($root, $args, $context) {
    return $context['select_sql']("SELECT id, fname, lname, email, notes FROM users WHERE email=:email", ['email'=>$args['email']]);
        }
    ],
  'Mutation' => [
    'addUser' => function($root, $args, $context) {
      $dummy = $context['insert_sql']("INSERT INTO users (fname, lname, email, notes) VALUES ('" . $args['fname'] . "', '" . $args['lname'] . "', '" . $args['email'] . "', '" . $args['notes'] . "')", []);
      if ($dummy) {
        return $context['select_sql']("SELECT id, fname, lname, email, notes FROM users WHERE email=:email", ['email'=>$args['email']]);
      }
      return null;
    },
    'delUser' => function($root, $args, $context) {
      $delrecord = $context['select_sql']("SELECT id, fname, lname, email, notes FROM users WHERE email=:email", ['email'=>$args['email']]);
      $dummy = $context['delete_sql']("DELETE FROM users WHERE email=:email", ['email'=>$args['email']]);
      if ($dummy) {
        return $delrecord;
      }
      return null;
    }
  ]
];

阶段3:扫描您的GraphQL API

在此示例中,Web服务定义位于以下URL:http://localhost/graphusers/schema.graphql。要使用Acunetix扫描Web服务:

  1. 使用以下URL创建一个新目标http:// localhost / graphusers /

  2. 将修改后的模式文件导入到目标:

    • 从以下URL下载模式文件:http://localhost/graphusers/schema.graphql

    • 在文件顶部插入一行以指定GraphQL端点;该文件应如下所示:

      graphql_endpoint="/graphusers/";
      type Query {
        getUser(email: String): [User]
      }
      
      type Mutation {
        addUser(fname: String, lname: String, email: String, notes: String): [User]
        deluser(email: String): [User]
      }
      
      type User {
        id: Int
        fname: String
        lname: String
        email: String
        notes: String
      }
      
    • 找到目标配置的“导入文件”部分,然后导入修改后的架构文件

  3. 将PHP AcuSensor部署到您的Web服务

  4. 启动您的Web服务的完整扫描,然后等待其完成

阶段4:识别GraphQL API中的漏洞

检查要扫描的漏洞列表。在本练习中,我们将重点介绍SQL注入漏洞,因为它们都有相同的根本原因。


Acunetix显示了攻击详细信息— GraphQL API调用已向变量注入了延迟命令,并且Acunetix能够确认响应确实延迟了指定的秒数。这证实了该API调用容易受到SQL注入的攻击,从而使恶意黑客可以制作其他请求以可能检索大量数据。

阶段5:解决漏洞

快速浏览**resolvers.php类文件中的addUser变异函数可以揭示根本原因。该查询是使用字符串连接构建的:

$dummy = $context 'insert_sql' VALUES ('" . $args['fname'] . "', '" . $args['lname'] . "', '" . $args['email'] . "', '" . $args['notes'] . "')", []);
]

的$ args [“FNAME”]变量和其他变量被简单地连接起来无需任何验证查询字符串。我们可以使用参数化查询来调整代码。resolvers.php文件中新调整的行如下所示:

$dummy = $context'insert_sql' VALUES (:fname, :lname, :email, :notes)", ['fname'=>$args['fname'],  'lname'=>$args['lname'], 'email'=>$args['email'], 'notes'=>$args['notes']]);

阶段6:重新扫描以确认分辨率

转到扫描漏洞列表,然后选择刚刚解决的SQL注入漏洞。

单击“重新测试”按钮-这将创建一个新扫描,以再次测试所选漏洞。结果将表明您已经成功解决了这些漏洞。

graphqlmysql导入sql文件
本作品采用《CC 协议》,转载必须注明作者和本文链接
自2020年6月以来,Acunetix支持日益流行的API查询语言– GraphQL。为此,您将首先创建一个故意易受攻击的API及其GraphQL定义,然后使用Acunetix对其进行扫描,消除使用Acunetix发现的严重漏洞,并确认已消除了这些漏洞。阶段1:设置测试环境 为了能够进行此练习,在测试之前必须准备一个测试环境。在本练习中,我们将Windows操作系统与开源软件一起使用。
当收到项目邀请时,白帽小哥注意到该目标在BugCrowd上已经两年多了,到目前为止已经发现了250+个漏洞,并支付了赏金奖励。GraphQL查询中的SQL注入:目标范围很大,但子域不在范围内。目标域类似target.*,因为它涵盖了广泛的 ccTLD。因此,在搜索子域或 ccTLD 域时,应确保使用组织名称进行搜索。的结果,经过过滤后,大约只有 64 个目标。
F-vuln(全称:Find-Vulnerability)是为了自己工作方便专门编写的一款自动化工具,主要适用于日常安全服务、渗透测试人员和RedTeam红队人员,它集合的功能包括:存活IP探测、开放端口探测、web服务探测、web漏洞扫描、smb爆破、ssh爆破、ftp爆破、mssql爆破等其他数据库爆破工作以及大量web漏洞检测模块。
API安全的盲点:GraphQL
2023-02-24 14:35:55
GraphQL更灵活、可扩展,更易于开发人员使用,但这同时也给攻击者打开了一扇窗户。
BatchQL是一款功能强大的GraphQL的安全审计工具,可以通过执行Batch GraphQL查询和输入变异数据来了解目标GraphQL应用的安全情况。该工具基于Python开发,其实现代码并不复杂,因此欢迎社区的广大研究人员和开发人员贡献自己的代码。
本文将分享国外一位白帽子对于多重身份验证功能实施渗透测试时的一些经验,希望能对你有所启发。
CrackQL是一款功能强大的图形化密码爆破和模糊测试工具,在该工具的帮助下,广大研究人员可以针对密码安全和应用程序安全进行渗透测试。
这种安全能力差距令人担忧,因为随着新技术的采用,针对 API 的攻击正在增加。
云原生API安全:背景、态势与风险防护
Andrew
暂无描述