Initial
This commit is contained in:
commit
bd2d73ef4f
13
CMakeLists.txt
Normal file
13
CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.28.0-rc5 FATAL_ERROR)
|
||||||
|
|
||||||
|
project(Plugin)
|
||||||
|
|
||||||
|
include(ZeekPlugin)
|
||||||
|
|
||||||
|
zeek_plugin_begin(Zeek TDS)
|
||||||
|
zeek_plugin_cc(src/TDS.cc src/Plugin.cc)
|
||||||
|
zeek_plugin_bif(src/events.bif)
|
||||||
|
zeek_plugin_pac(src/tds.pac src/tds-analyzer.pac src/tds-protocol.pac)
|
||||||
|
zeek_plugin_dist_files(README CHANGES COPYING VERSION)
|
||||||
|
zeek_plugin_end()
|
||||||
4
CODE_OF_CONDUCT.md
Normal file
4
CODE_OF_CONDUCT.md
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
## Code of Conduct
|
||||||
|
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
|
||||||
|
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
|
||||||
|
opensource-codeofconduct@amazon.com with any additional questions or comments.
|
||||||
61
CONTRIBUTING.md
Normal file
61
CONTRIBUTING.md
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
# Contributing Guidelines
|
||||||
|
|
||||||
|
Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional
|
||||||
|
documentation, we greatly value feedback and contributions from our community.
|
||||||
|
|
||||||
|
Please read through this document before submitting any issues or pull requests to ensure we have all the necessary
|
||||||
|
information to effectively respond to your bug report or contribution.
|
||||||
|
|
||||||
|
|
||||||
|
## Reporting Bugs/Feature Requests
|
||||||
|
|
||||||
|
We welcome you to use the GitHub issue tracker to report bugs or suggest features.
|
||||||
|
|
||||||
|
When filing an issue, please check [existing open](https://github.com/amzn/zeek-plugin-tds/issues), or [recently closed](https://github.com/amzn/zeek-plugin-tds/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already
|
||||||
|
reported the issue. Please try to include as much information as you can. Details like these are incredibly useful:
|
||||||
|
|
||||||
|
* A reproducible test case or series of steps
|
||||||
|
* The version of our code being used
|
||||||
|
* Any modifications you've made relevant to the bug
|
||||||
|
* Anything unusual about your environment or deployment
|
||||||
|
|
||||||
|
|
||||||
|
## Contributing via Pull Requests
|
||||||
|
Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that:
|
||||||
|
|
||||||
|
1. You are working against the latest source on the *master* branch.
|
||||||
|
2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already.
|
||||||
|
3. You open an issue to discuss any significant work - we would hate for your time to be wasted.
|
||||||
|
|
||||||
|
To send us a pull request, please:
|
||||||
|
|
||||||
|
1. Fork the repository.
|
||||||
|
2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change.
|
||||||
|
3. Ensure local tests pass.
|
||||||
|
4. Commit to your fork using clear commit messages.
|
||||||
|
5. Send us a pull request, answering any default questions in the pull request interface.
|
||||||
|
6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation.
|
||||||
|
|
||||||
|
GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and
|
||||||
|
[creating a pull request](https://help.github.com/articles/creating-a-pull-request/).
|
||||||
|
|
||||||
|
|
||||||
|
## Finding contributions to work on
|
||||||
|
Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/amzn/zeek-plugin-tds/labels/help%20wanted) issues is a great place to start.
|
||||||
|
|
||||||
|
|
||||||
|
## Code of Conduct
|
||||||
|
This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct).
|
||||||
|
For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact
|
||||||
|
opensource-codeofconduct@amazon.com with any additional questions or comments.
|
||||||
|
|
||||||
|
|
||||||
|
## Security issue notifications
|
||||||
|
If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
|
||||||
|
|
||||||
|
|
||||||
|
## Licensing
|
||||||
|
|
||||||
|
See the [LICENSE](https://github.com/amzn/zeek-plugin-tds/blob/master/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution.
|
||||||
|
|
||||||
|
We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes.
|
||||||
49
Dockerfile
Normal file
49
Dockerfile
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
FROM public.ecr.aws/amazonlinux/amazonlinux:latest
|
||||||
|
MAINTAINER https://github.com/amzn/
|
||||||
|
|
||||||
|
# Metadata
|
||||||
|
LABEL program=zeek
|
||||||
|
|
||||||
|
# Specify program
|
||||||
|
ENV PROG zeek
|
||||||
|
# Specify source extension
|
||||||
|
ENV EXT tar.gz
|
||||||
|
# Specify Zeek version to download and install (e.g. 3.0.0)
|
||||||
|
ENV VERS 3.2.4
|
||||||
|
|
||||||
|
# Specify Cmake version
|
||||||
|
ENV CMAKEVERSMAIN 3.10
|
||||||
|
ENV CMAKEVERSSUB .0
|
||||||
|
|
||||||
|
# Install directory
|
||||||
|
ENV PREFIX /opt/zeek
|
||||||
|
# Path should include prefix
|
||||||
|
ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PREFIX/bin
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
RUN yum -y update
|
||||||
|
RUN yum -y install cronie epel-release gcc gcc-c++ make libpcap-devel openssl-devel bind-devel zlib-devel git perl libcurl-devel GeoIP-devel python-devel jemalloc-devel swig libpcap bind-libs zlib bash python3 libcurl gawk GeoIP jemalloc wget flex bison python3-pip tar iproute procps-ng kernel-devel clang gdb && yum clean all
|
||||||
|
|
||||||
|
# Zeek 3.1.0 needs Cmake 3.0 or higher
|
||||||
|
WORKDIR /tmp
|
||||||
|
RUN wget https://cmake.org/files/v$CMAKEVERSMAIN/cmake-$CMAKEVERSMAIN$CMAKEVERSSUB.tar.gz
|
||||||
|
RUN tar -xvzf cmake-$CMAKEVERSMAIN$CMAKEVERSSUB.tar.gz
|
||||||
|
WORKDIR /tmp/cmake-$CMAKEVERSMAIN$CMAKEVERSSUB
|
||||||
|
RUN /tmp/cmake-$CMAKEVERSMAIN$CMAKEVERSSUB/bootstrap
|
||||||
|
RUN make -j$((`nproc`-1))
|
||||||
|
RUN make install
|
||||||
|
|
||||||
|
# Compile and install Zeek
|
||||||
|
WORKDIR /tmp
|
||||||
|
RUN wget https://old.zeek.org/downloads/$PROG-$VERS.$EXT && tar -xzf $PROG-$VERS.$EXT
|
||||||
|
WORKDIR /tmp/$PROG-$VERS
|
||||||
|
RUN ./configure --build-type=RelWithDebInfo --prefix=$PREFIX --disable-python
|
||||||
|
RUN make -j$((`nproc`-1))
|
||||||
|
RUN make install
|
||||||
|
|
||||||
|
USER root
|
||||||
|
RUN pip3 install zkg
|
||||||
|
RUN zkg autoconfig
|
||||||
|
COPY [--chown=bro:bro] . /tmp/zeek-plugin-tds
|
||||||
|
WORKDIR /tmp/zeek-plugin-tds
|
||||||
|
RUN zkg install --force .
|
||||||
23
LICENSE
Normal file
23
LICENSE
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
Copyright 2019 Amazon.com, Inc. or its affiliates. All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the copyright holder nor the
|
||||||
|
names of its contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
|
||||||
|
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
29
Makefile
Normal file
29
Makefile
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#
|
||||||
|
# Convenience Makefile providing a few common top-level targets.
|
||||||
|
#
|
||||||
|
|
||||||
|
cmake_build_dir=build
|
||||||
|
arch=`uname -s | tr A-Z a-z`-`uname -m`
|
||||||
|
|
||||||
|
all: build-it
|
||||||
|
|
||||||
|
build-it:
|
||||||
|
@test -e $(cmake_build_dir)/config.status || ./configure
|
||||||
|
-@test -e $(cmake_build_dir)/CMakeCache.txt && \
|
||||||
|
test $(cmake_build_dir)/CMakeCache.txt -ot `cat $(cmake_build_dir)/CMakeCache.txt | grep ZEEK_DIST | cut -d '=' -f 2`/build/CMakeCache.txt && \
|
||||||
|
echo Updating stale CMake cache && \
|
||||||
|
touch $(cmake_build_dir)/CMakeCache.txt
|
||||||
|
|
||||||
|
( cd $(cmake_build_dir) && make )
|
||||||
|
|
||||||
|
install:
|
||||||
|
( cd $(cmake_build_dir) && make install )
|
||||||
|
|
||||||
|
clean:
|
||||||
|
( cd $(cmake_build_dir) && make clean )
|
||||||
|
|
||||||
|
distclean:
|
||||||
|
rm -rf $(cmake_build_dir)
|
||||||
|
|
||||||
|
test:
|
||||||
|
if [ -f build/lib/Zeek-* ]; then make -C tests; else echo "Plugin not built."; fi
|
||||||
11
README.md
Normal file
11
README.md
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
## Zeek Plugin TDS
|
||||||
|
|
||||||
|
When running as part of your Zeek installation this plugin will produce three log files containing metadata extracted from any [Tabular Data Stream](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/b46a581a-39de-4745-b076-ec4dbb7d13ec) (TDS) traffic observed on TCP port 1433.
|
||||||
|
|
||||||
|
## Installation and Usage
|
||||||
|
|
||||||
|
`zeek-plugin-tds` is distributed as a Zeek package and is compatible with the [`zkg`](https://docs.zeek.org/projects/package-manager/en/stable/zkg.html) command line tool.
|
||||||
|
|
||||||
|
## Sharing and Contributing
|
||||||
|
|
||||||
|
This code is made available under the [BSD-3-Clause license](https://github.com/amzn/zeek-plugin-tds/blob/master/LICENSE). [Guidelines for contributing](https://github.com/amzn/zeek-plugin-tds/blob/master/CONTRIBUTING.md) are available as well as a [pull request template](https://github.com/amzn/zeek-plugin-tds/blob/master/.github/PULL_REQUEST_TEMPLATE.md). A [Dockerfile](https://github.com/amzn/zeek-plugin-tds/blob/master/Dockerfile) has been included in the repository to assist with setting up an environment for testing any changes to the plugin.
|
||||||
188
configure
vendored
Executable file
188
configure
vendored
Executable file
@ -0,0 +1,188 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Wrapper for viewing/setting options that the plugin's CMake
|
||||||
|
# scripts will recognize.
|
||||||
|
#
|
||||||
|
# Don't edit this. Edit configure.plugin to add plugin-specific options.
|
||||||
|
#
|
||||||
|
|
||||||
|
set -e
|
||||||
|
command="$0 $*"
|
||||||
|
|
||||||
|
if [ -e `dirname $0`/configure.plugin ]; then
|
||||||
|
# Include custom additions.
|
||||||
|
. `dirname $0`/configure.plugin
|
||||||
|
fi
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
|
||||||
|
cat 1>&2 <<EOF
|
||||||
|
Usage: $0 [OPTIONS]
|
||||||
|
|
||||||
|
Plugin Options:
|
||||||
|
--cmake=PATH Path to CMake binary
|
||||||
|
--zeek-dist=DIR Path to Zeek source tree
|
||||||
|
--install-root=DIR Path where to install plugin into
|
||||||
|
--with-binpac=DIR Path to BinPAC installation root
|
||||||
|
--with-broker=DIR Path to Broker installation root
|
||||||
|
--with-caf=DIR Path to CAF installation root
|
||||||
|
--with-bifcl=PATH Path to bifcl executable
|
||||||
|
--enable-debug Compile in debugging mode
|
||||||
|
EOF
|
||||||
|
|
||||||
|
if type plugin_usage >/dev/null 2>&1; then
|
||||||
|
plugin_usage 1>&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to append a CMake cache entry definition to the
|
||||||
|
# CMakeCacheEntries variable
|
||||||
|
# $1 is the cache entry variable name
|
||||||
|
# $2 is the cache entry variable type
|
||||||
|
# $3 is the cache entry variable value
|
||||||
|
append_cache_entry () {
|
||||||
|
CMakeCacheEntries="$CMakeCacheEntries -D $1:$2=$3"
|
||||||
|
}
|
||||||
|
|
||||||
|
# set defaults
|
||||||
|
builddir=build
|
||||||
|
zeekdist=""
|
||||||
|
installroot="default"
|
||||||
|
CMakeCacheEntries=""
|
||||||
|
|
||||||
|
while [ $# -ne 0 ]; do
|
||||||
|
case "$1" in
|
||||||
|
-*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
|
||||||
|
*) optarg= ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
--help|-h)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
|
||||||
|
--cmake=*)
|
||||||
|
CMakeCommand=$optarg
|
||||||
|
;;
|
||||||
|
|
||||||
|
--zeek-dist=*)
|
||||||
|
zeekdist=`cd $optarg && pwd`
|
||||||
|
;;
|
||||||
|
|
||||||
|
--install-root=*)
|
||||||
|
installroot=$optarg
|
||||||
|
;;
|
||||||
|
|
||||||
|
--with-binpac=*)
|
||||||
|
append_cache_entry BinPAC_ROOT_DIR PATH $optarg
|
||||||
|
binpac_root=$optarg
|
||||||
|
;;
|
||||||
|
|
||||||
|
--with-broker=*)
|
||||||
|
append_cache_entry BROKER_ROOT_DIR PATH $optarg
|
||||||
|
broker_root=$optarg
|
||||||
|
;;
|
||||||
|
|
||||||
|
--with-caf=*)
|
||||||
|
append_cache_entry CAF_ROOT_DIR PATH $optarg
|
||||||
|
caf_root=$optarg
|
||||||
|
;;
|
||||||
|
|
||||||
|
--with-bifcl=*)
|
||||||
|
append_cache_entry BifCl_EXE PATH $optarg
|
||||||
|
;;
|
||||||
|
|
||||||
|
--enable-debug)
|
||||||
|
append_cache_entry BRO_PLUGIN_ENABLE_DEBUG BOOL true
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
if type plugin_option >/dev/null 2>&1; then
|
||||||
|
plugin_option $1 && shift && continue;
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Invalid option '$1'. Try $0 --help to see available options."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ -z "$CMakeCommand" ]; then
|
||||||
|
# prefer cmake3 over "regular" cmake (cmake == cmake2 on RHEL)
|
||||||
|
if command -v cmake3 >/dev/null 2>&1 ; then
|
||||||
|
CMakeCommand="cmake3"
|
||||||
|
elif command -v cmake >/dev/null 2>&1 ; then
|
||||||
|
CMakeCommand="cmake"
|
||||||
|
else
|
||||||
|
echo "This package requires CMake, please install it first."
|
||||||
|
echo "Then you may use this script to configure the CMake build."
|
||||||
|
echo "Note: pass --cmake=PATH to use cmake in non-standard locations."
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$zeekdist" ]; then
|
||||||
|
if type zeek-config >/dev/null 2>&1; then
|
||||||
|
zeek_config="zeek-config"
|
||||||
|
else
|
||||||
|
echo "Either 'zeek-config' must be in PATH or '--zeek-dist=<path>' used"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
append_cache_entry BRO_CONFIG_PREFIX PATH `${zeek_config} --prefix`
|
||||||
|
append_cache_entry BRO_CONFIG_INCLUDE_DIR PATH `${zeek_config} --include_dir`
|
||||||
|
append_cache_entry BRO_CONFIG_PLUGIN_DIR PATH `${zeek_config} --plugin_dir`
|
||||||
|
append_cache_entry BRO_CONFIG_CMAKE_DIR PATH `${zeek_config} --cmake_dir`
|
||||||
|
append_cache_entry CMAKE_MODULE_PATH PATH `${zeek_config} --cmake_dir`
|
||||||
|
|
||||||
|
build_type=`${zeek_config} --build_type`
|
||||||
|
|
||||||
|
if [ "$build_type" = "debug" ]; then
|
||||||
|
append_cache_entry BRO_PLUGIN_ENABLE_DEBUG BOOL true
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$binpac_root" ]; then
|
||||||
|
append_cache_entry BinPAC_ROOT_DIR PATH `${zeek_config} --binpac_root`
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$broker_root" ]; then
|
||||||
|
append_cache_entry BROKER_ROOT_DIR PATH `${zeek_config} --broker_root`
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$caf_root" ]; then
|
||||||
|
append_cache_entry CAF_ROOT_DIR PATH `${zeek_config} --caf_root`
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ ! -e "$zeekdist/zeek-path-dev.in" ]; then
|
||||||
|
echo "$zeekdist does not appear to be a valid Zeek source tree."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# BRO_DIST is the canonical/historical name used by plugin CMake scripts
|
||||||
|
# ZEEK_DIST doesn't serve a function at the moment, but set/provided anyway
|
||||||
|
append_cache_entry BRO_DIST PATH $zeekdist
|
||||||
|
append_cache_entry ZEEK_DIST PATH $zeekdist
|
||||||
|
append_cache_entry CMAKE_MODULE_PATH PATH $zeekdist/cmake
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$installroot" != "default" ]; then
|
||||||
|
mkdir -p $installroot
|
||||||
|
append_cache_entry BRO_PLUGIN_INSTALL_ROOT PATH $installroot
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Build Directory : $builddir"
|
||||||
|
echo "Zeek Source Directory : $zeekdist"
|
||||||
|
|
||||||
|
mkdir -p $builddir
|
||||||
|
cd $builddir
|
||||||
|
|
||||||
|
"$CMakeCommand" $CMakeCacheEntries ..
|
||||||
|
|
||||||
|
echo "# This is the command used to configure this build" > config.status
|
||||||
|
echo $command >> config.status
|
||||||
|
chmod u+x config.status
|
||||||
26
configure.plugin
Normal file
26
configure.plugin
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Hooks to add custom options to the configure script.
|
||||||
|
#
|
||||||
|
|
||||||
|
plugin_usage()
|
||||||
|
{
|
||||||
|
: # Do nothing
|
||||||
|
# cat <<EOF
|
||||||
|
# --with-foo=DIR Path to foo
|
||||||
|
# EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin_option()
|
||||||
|
{
|
||||||
|
case "$1" in
|
||||||
|
# --with-foo=*)
|
||||||
|
# append_cache_entry FOO_DIR PATH $optarg
|
||||||
|
# return 0
|
||||||
|
# ;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
return 1;
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
3
scripts/TDS/__load__.zeek
Normal file
3
scripts/TDS/__load__.zeek
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
@load ./consts.zeek
|
||||||
|
@load ./main.zeek
|
||||||
|
|
||||||
30
scripts/TDS/consts.zeek
Normal file
30
scripts/TDS/consts.zeek
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
## Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
## SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
module TDS;
|
||||||
|
|
||||||
|
export {
|
||||||
|
## TDS default commands
|
||||||
|
const commands = {
|
||||||
|
[0x00] = "NOP",
|
||||||
|
[0x01] = "SQL Batch",
|
||||||
|
[0x02] = "Pre TDS7 Login",
|
||||||
|
[0x03] = "Remote Procedure Call",
|
||||||
|
[0x04] = "SQL Batch Server Response",
|
||||||
|
[0x05] = "Unused",
|
||||||
|
[0x06] = "Attention Request",
|
||||||
|
[0x07] = "Bulk Load Data",
|
||||||
|
[0x0E] = "Transcation Manager Request",
|
||||||
|
[0x0F] = "TDS5 Query",
|
||||||
|
[0x10] = "TDS7 Login",
|
||||||
|
[0x11] = "SSPI Message",
|
||||||
|
[0x12] = "Pre-Login Request",
|
||||||
|
} &default=function(i: count):string { return fmt("command (%d)", i); } &redef;
|
||||||
|
|
||||||
|
## TDS header types
|
||||||
|
const header_types = {
|
||||||
|
[0x0000] = "NOP",
|
||||||
|
[0x0001] = "Query notifications",
|
||||||
|
[0x0002] = "Transaction Descriptor",
|
||||||
|
} &default=function(i: count):string { return fmt("command (%d)", i); } &redef;
|
||||||
|
}
|
||||||
217
scripts/TDS/main.zeek
Normal file
217
scripts/TDS/main.zeek
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
##! Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
##! SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
##! Implements base functionality for TDS analysis.
|
||||||
|
##! Generates the tds.log file, containing some information about the TDS headers.
|
||||||
|
##! Generates the tds_rpc.log file, containing some information about rpc data.
|
||||||
|
##! Generates the tds_sql_batch.log file, containing some information about sql batch data.
|
||||||
|
|
||||||
|
module TDS;
|
||||||
|
|
||||||
|
export {
|
||||||
|
redef enum Log::ID += {
|
||||||
|
Log_TDS,
|
||||||
|
Log_TDS_RPC,
|
||||||
|
Log_TDS_SQL_Batch
|
||||||
|
};
|
||||||
|
|
||||||
|
## header info
|
||||||
|
type TDS: record {
|
||||||
|
ts : time &log; ## Timestamp for when the event happened.
|
||||||
|
uid : string &log; ## Unique ID for the connection.
|
||||||
|
id : conn_id &log; ## The connection's 4-tuple of endpoint addresses/ports.
|
||||||
|
|
||||||
|
command : string &optional &log; ## Name of the sent TDS command.
|
||||||
|
};
|
||||||
|
## Event that can be handled to access the tds record as it is sent to the loggin framework.
|
||||||
|
global log_tds: event(rec: TDS);
|
||||||
|
|
||||||
|
## Remote Procedure Call
|
||||||
|
type TDS_RPC: record {
|
||||||
|
ts : time &log; ## Timestamp for when the event happened.
|
||||||
|
uid : string &log; ## Unique ID for the connection.
|
||||||
|
id : conn_id &log; ## The connection's 4-tuple of endpoint addresses/ports.
|
||||||
|
|
||||||
|
procedure_name : string &optional &log;
|
||||||
|
parameters : string_vec &optional &log;
|
||||||
|
};
|
||||||
|
## Event that can be handled to access the tds record as it is sent to the loggin framework.
|
||||||
|
global log_tds_rpc: event(rec: TDS_RPC);
|
||||||
|
|
||||||
|
## SQL Batch
|
||||||
|
type TDS_SQL_Batch: record {
|
||||||
|
ts : time &log; ## Timestamp for when the event happened.
|
||||||
|
uid : string &log; ## Unique ID for the connection.
|
||||||
|
id : conn_id &log; ## The connection's 4-tuple of endpoint addresses/ports.
|
||||||
|
|
||||||
|
header_type : string &optional &log;
|
||||||
|
query : string &optional &log;
|
||||||
|
};
|
||||||
|
## Event that can be handled to access the tds record as it is sent to the loggin framework.
|
||||||
|
global log_tds_sql_batch: event(rec: TDS_SQL_Batch);
|
||||||
|
}
|
||||||
|
|
||||||
|
redef record connection += {
|
||||||
|
tds : TDS &optional;
|
||||||
|
tds_rpc : TDS_RPC &optional;
|
||||||
|
tds_sql_batch : TDS_SQL_Batch &optional;
|
||||||
|
};
|
||||||
|
|
||||||
|
## define listening ports
|
||||||
|
const ports = {
|
||||||
|
1433/tcp
|
||||||
|
};
|
||||||
|
redef likely_server_ports += {
|
||||||
|
ports
|
||||||
|
};
|
||||||
|
|
||||||
|
event zeek_init() &priority=5 {
|
||||||
|
Log::create_stream(TDS::Log_TDS,
|
||||||
|
[$columns=TDS,
|
||||||
|
$ev=log_tds,
|
||||||
|
$path="tds"]);
|
||||||
|
Log::create_stream(TDS::Log_TDS_RPC,
|
||||||
|
[$columns=TDS_RPC,
|
||||||
|
$ev=log_tds_rpc,
|
||||||
|
$path="tds_rpc"]);
|
||||||
|
Log::create_stream(TDS::Log_TDS_SQL_Batch,
|
||||||
|
[$columns=TDS_SQL_Batch,
|
||||||
|
$ev=log_tds_sql_batch,
|
||||||
|
$path="tds_sql_batch"]);
|
||||||
|
Analyzer::register_for_ports(Analyzer::ANALYZER_TDS, ports);
|
||||||
|
}
|
||||||
|
|
||||||
|
##! general tds header
|
||||||
|
event tds(c: connection, is_orig: bool, command: count) {
|
||||||
|
if(!c?$tds) {
|
||||||
|
c$tds = [$ts=network_time(), $uid=c$uid, $id=c$id];
|
||||||
|
}
|
||||||
|
|
||||||
|
c$tds$ts = network_time();
|
||||||
|
c$tds$command = commands[command];
|
||||||
|
|
||||||
|
Log::write(Log_TDS, c$tds);
|
||||||
|
delete c$tds;
|
||||||
|
}
|
||||||
|
|
||||||
|
##! general tds rpc
|
||||||
|
event tds_rpc(c: connection, is_orig: bool,
|
||||||
|
procedure_name: string,
|
||||||
|
parameters: string) {
|
||||||
|
if(!c?$tds_rpc) {
|
||||||
|
c$tds_rpc = [$ts=network_time(), $uid=c$uid, $id=c$id];
|
||||||
|
}
|
||||||
|
|
||||||
|
c$tds_rpc$ts = network_time();
|
||||||
|
c$tds_rpc$procedure_name = subst_string(procedure_name, "\x00", "");
|
||||||
|
local params_size: count = |parameters|;
|
||||||
|
if (params_size > 0) {
|
||||||
|
local params: string_vec;
|
||||||
|
local params_index: count=0;
|
||||||
|
local param_index: count=0;
|
||||||
|
local param_name: string="";
|
||||||
|
local param_type: count=0;
|
||||||
|
local param_data: string;
|
||||||
|
local param_len: count=0;
|
||||||
|
while (param_index < params_size) {
|
||||||
|
param_len = bytestring_to_count(parameters[param_index])*2;
|
||||||
|
param_index += 1;
|
||||||
|
param_name = subst_string(parameters[param_index: param_index+param_len], "\x00", "");
|
||||||
|
param_index += param_len;
|
||||||
|
param_index += 1; ##! status
|
||||||
|
param_type = bytestring_to_count(parameters[param_index]);
|
||||||
|
param_index += 1;
|
||||||
|
param_data = "";
|
||||||
|
switch (param_type) {
|
||||||
|
case 0x24, ##! GUID
|
||||||
|
0x26, ##! int
|
||||||
|
0x68, ##! bit
|
||||||
|
0x6d, ##! float
|
||||||
|
0x6f: ##! DateTime
|
||||||
|
param_index += 1; ##! max length
|
||||||
|
param_len = bytestring_to_count(parameters[param_index]);
|
||||||
|
param_index += 1;
|
||||||
|
switch (param_type) {
|
||||||
|
case 0x24: ##! GUID
|
||||||
|
param_data = bytestring_to_hexstr(parameters[param_index+3]);
|
||||||
|
param_data += bytestring_to_hexstr(parameters[param_index+2]);
|
||||||
|
param_data += bytestring_to_hexstr(parameters[param_index+1]);
|
||||||
|
param_data += bytestring_to_hexstr(parameters[param_index]);
|
||||||
|
param_data += "-";
|
||||||
|
param_data += bytestring_to_hexstr(parameters[param_index+5]);
|
||||||
|
param_data += bytestring_to_hexstr(parameters[param_index+4]);
|
||||||
|
param_data += "-";
|
||||||
|
param_data += bytestring_to_hexstr(parameters[param_index+7]);
|
||||||
|
param_data += bytestring_to_hexstr(parameters[param_index+6]);
|
||||||
|
param_data += "-";
|
||||||
|
param_data += bytestring_to_hexstr(parameters[param_index+8:param_index+10]);
|
||||||
|
param_data += "-";
|
||||||
|
param_data += bytestring_to_hexstr(parameters[param_index+10:param_index+param_len]);
|
||||||
|
break;
|
||||||
|
case 0x68: ##! bit
|
||||||
|
if (bytestring_to_count(parameters[param_index]) == 1) {
|
||||||
|
param_data = "True";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
param_data = "False";
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x6d: ##! float
|
||||||
|
param_data = fmt("%f", bytestring_to_double(parameters[param_index:param_index+param_len]));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (param_index >= params_size) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
param_data = fmt("%d", bytestring_to_count(parameters[param_index:param_index+param_len], T));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
param_index += param_len;
|
||||||
|
params[params_index] = fmt("%s=%s", param_name, param_data);
|
||||||
|
params_index += 1;
|
||||||
|
break;
|
||||||
|
case 0xa7, ##! VarChar
|
||||||
|
0xe7: ##! NVarChar
|
||||||
|
param_index += 2; ##! max length
|
||||||
|
param_index += 5; ##! collation
|
||||||
|
param_len = bytestring_to_count(parameters[param_index:param_index+2], T);
|
||||||
|
param_index += 2;
|
||||||
|
##! NULL is 65535
|
||||||
|
if (param_len > 0 && param_len < 65535) {
|
||||||
|
param_data = subst_string(parameters[param_index:param_index+param_len], "\x00", "");
|
||||||
|
param_index += param_len;
|
||||||
|
}
|
||||||
|
params[params_index] = fmt("%s=%s", param_name, param_data);
|
||||||
|
params_index += 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
c$tds_rpc$parameters = params;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::write(Log_TDS_RPC, c$tds_rpc);
|
||||||
|
delete c$tds_rpc;
|
||||||
|
}
|
||||||
|
|
||||||
|
event tds_sql_batch(c: connection, is_orig: bool,
|
||||||
|
header_type: count,
|
||||||
|
query: string) {
|
||||||
|
if(!c?$tds_sql_batch) {
|
||||||
|
c$tds_sql_batch = [$ts=network_time(), $uid=c$uid, $id=c$id];
|
||||||
|
}
|
||||||
|
|
||||||
|
c$tds_sql_batch$ts = network_time();
|
||||||
|
c$tds_sql_batch$header_type = header_types[header_type];
|
||||||
|
query = subst_string(query, "\x00", "");
|
||||||
|
c$tds_sql_batch$query = query;
|
||||||
|
|
||||||
|
Log::write(Log_TDS_SQL_Batch, c$tds_sql_batch);
|
||||||
|
delete c$tds_sql_batch;
|
||||||
|
}
|
||||||
|
|
||||||
|
event connection_state_remove(c: connection) &priority=-5 {
|
||||||
|
if(c?$tds) {
|
||||||
|
delete c$tds;
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/Plugin.cc
Normal file
19
src/Plugin.cc
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include "Plugin.h"
|
||||||
|
#include "zeek/analyzer/Component.h"
|
||||||
|
|
||||||
|
namespace plugin {
|
||||||
|
namespace Zeek_TDS {
|
||||||
|
Plugin plugin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
using namespace plugin::Zeek_TDS;
|
||||||
|
|
||||||
|
zeek::plugin::Configuration Plugin::Configure() {
|
||||||
|
AddComponent(new zeek::analyzer::Component("TDS", analyzer::tds::TDS_Analyzer::Instantiate));
|
||||||
|
|
||||||
|
zeek::plugin::Configuration config;
|
||||||
|
config.name = "Zeek::TDS";
|
||||||
|
config.description = "MS-SQL TDS protocol analyzer";
|
||||||
|
return config;
|
||||||
|
}
|
||||||
19
src/Plugin.h
Normal file
19
src/Plugin.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef ZEEK_PLUGIN_ZEEK_TDS
|
||||||
|
#define ZEEK_PLUGIN_ZEEK_TDS
|
||||||
|
|
||||||
|
#include <zeek/plugin/Plugin.h>
|
||||||
|
#include "TDS.h"
|
||||||
|
|
||||||
|
namespace plugin {
|
||||||
|
namespace Zeek_TDS {
|
||||||
|
class Plugin : public zeek::plugin::Plugin {
|
||||||
|
protected:
|
||||||
|
// Overridden from plugin::Plugin.
|
||||||
|
virtual zeek::plugin::Configuration Configure();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Plugin plugin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
50
src/TDS.cc
Normal file
50
src/TDS.cc
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#include "TDS.h"
|
||||||
|
#include <zeek/analyzer/protocol/tcp/TCP_Reassembler.h>
|
||||||
|
#include <zeek/Reporter.h>
|
||||||
|
#include "events.bif.h"
|
||||||
|
|
||||||
|
using namespace analyzer::tds;
|
||||||
|
|
||||||
|
TDS_Analyzer::TDS_Analyzer(zeek::Connection* c): zeek::analyzer::tcp::TCP_ApplicationAnalyzer("TDS", c) {
|
||||||
|
interp = new binpac::TDS::TDS_Conn(this);
|
||||||
|
had_gap = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TDS_Analyzer::~TDS_Analyzer() {
|
||||||
|
delete interp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TDS_Analyzer::Done() {
|
||||||
|
zeek::analyzer::tcp::TCP_ApplicationAnalyzer::Done();
|
||||||
|
interp->FlowEOF(true);
|
||||||
|
interp->FlowEOF(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TDS_Analyzer::EndpointEOF(bool is_orig) {
|
||||||
|
zeek::analyzer::tcp::TCP_ApplicationAnalyzer::EndpointEOF(is_orig);
|
||||||
|
interp->FlowEOF(is_orig);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TDS_Analyzer::DeliverStream(int len, const u_char* data, bool orig) {
|
||||||
|
zeek::analyzer::tcp::TCP_ApplicationAnalyzer::DeliverStream(len, data, orig);
|
||||||
|
assert(TCP());
|
||||||
|
//if(TCP()->IsPartial())
|
||||||
|
// return;
|
||||||
|
// If only one side had a content gap, we could still try to
|
||||||
|
// deliver data to the other side if the script layer can handle this.
|
||||||
|
if(had_gap)
|
||||||
|
return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
interp->NewData(orig, data, data + len);
|
||||||
|
}
|
||||||
|
catch(const binpac::Exception& e) {
|
||||||
|
AnalyzerViolation(zeek::util::fmt("Binpac exception: %s", e.c_msg()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TDS_Analyzer::Undelivered(uint64_t seq, int len, bool orig) {
|
||||||
|
zeek::analyzer::tcp::TCP_ApplicationAnalyzer::Undelivered(seq, len, orig);
|
||||||
|
had_gap = true;
|
||||||
|
interp->NewGap(orig, len);
|
||||||
|
}
|
||||||
31
src/TDS.h
Normal file
31
src/TDS.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#ifndef ANALYZER_PROTOCOL_TDS_H
|
||||||
|
#define ANALYZER_PROTOCOL_TDS_H
|
||||||
|
|
||||||
|
#include <zeek/analyzer/protocol/tcp/TCP.h>
|
||||||
|
#include "tds_pac.h"
|
||||||
|
|
||||||
|
namespace analyzer {
|
||||||
|
namespace tds {
|
||||||
|
class TDS_Analyzer : public zeek::analyzer::tcp::TCP_ApplicationAnalyzer {
|
||||||
|
public:
|
||||||
|
TDS_Analyzer(zeek::Connection* conn);
|
||||||
|
virtual ~TDS_Analyzer();
|
||||||
|
|
||||||
|
virtual void Done();
|
||||||
|
virtual void DeliverStream(int len, const u_char* data, bool orig);
|
||||||
|
virtual void Undelivered(uint64_t seq, int len, bool orig);
|
||||||
|
|
||||||
|
virtual void EndpointEOF(bool is_orig);
|
||||||
|
|
||||||
|
static zeek::analyzer::Analyzer* Instantiate(zeek::Connection* conn) {
|
||||||
|
return new TDS_Analyzer(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
binpac::TDS::TDS_Conn* interp;
|
||||||
|
bool had_gap;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
40
src/events.bif
Normal file
40
src/events.bif
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
## Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
## SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
######################################
|
||||||
|
## Generated for all the TDS headers #
|
||||||
|
######################################
|
||||||
|
## c: The connection the TDS communication is part of.
|
||||||
|
## is_orig: True if this reflects originator-side activity.
|
||||||
|
## command: uint16 of either request/response
|
||||||
|
## index: index# of the packet.
|
||||||
|
##
|
||||||
|
event tds%(c: connection, is_orig: bool,
|
||||||
|
command: count
|
||||||
|
%);
|
||||||
|
|
||||||
|
############################################
|
||||||
|
## Generated for the remote procedure call #
|
||||||
|
############################################
|
||||||
|
## c: The connection the TDS communication is part of.
|
||||||
|
## is_orig: True if this reflects originator-side activity.
|
||||||
|
## product_name: product name.
|
||||||
|
## serial_number: serial number.
|
||||||
|
##
|
||||||
|
event tds_rpc%(c: connection, is_orig: bool,
|
||||||
|
procedure_name: string,
|
||||||
|
parameters: string
|
||||||
|
%);
|
||||||
|
|
||||||
|
####################################
|
||||||
|
## Generated for the identity info #
|
||||||
|
####################################
|
||||||
|
## c: The connection the TDS communication is part of.
|
||||||
|
## is_orig: True if this reflects originator-side activity.
|
||||||
|
## product_name: product name.
|
||||||
|
## serial_number: serial number.
|
||||||
|
##
|
||||||
|
event tds_sql_batch%(c: connection, is_orig: bool,
|
||||||
|
header_type: count,
|
||||||
|
query: string
|
||||||
|
%);
|
||||||
101
src/tds-analyzer.pac
Normal file
101
src/tds-analyzer.pac
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
## Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
## SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
connection TDS_Conn(zeek_analyzer: ZeekAnalyzer) {
|
||||||
|
upflow = TDS_Flow(true);
|
||||||
|
downflow = TDS_Flow(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
%header{
|
||||||
|
#define SQL_BATCH 0x01
|
||||||
|
#define PRE_TDS7_LOGIN 0x02
|
||||||
|
#define REMOTE_PROCEDURE_CALL 0x03
|
||||||
|
#define RESPONSE 0x04
|
||||||
|
#define UNUSED 0x05
|
||||||
|
#define ATTENTION_REQUEST 0x06
|
||||||
|
#define BULK_LOAD_DATA 0x07
|
||||||
|
#define TRANSACTION_MANAGER 0x0e
|
||||||
|
#define TDS5_QUERY 0x0F
|
||||||
|
#define TDS7_LOGIN 0x10
|
||||||
|
#define SSPI_MESSAGE 0x11
|
||||||
|
#define TDS7_PRELOGIN 0x12
|
||||||
|
|
||||||
|
#define QUERY_NOTIFICATIONS 0x0001
|
||||||
|
#define TRANSACTION_DESCRIPTOR 0x0002
|
||||||
|
%}
|
||||||
|
|
||||||
|
flow TDS_Flow(is_orig: bool) {
|
||||||
|
# flowunit ?
|
||||||
|
datagram = TDS_PDU(is_orig) withcontext(connection, this);
|
||||||
|
|
||||||
|
function tds(header: TDS): bool %{
|
||||||
|
if(::tds) {
|
||||||
|
if (${header.command} != SQL_BATCH &&
|
||||||
|
${header.command} != PRE_TDS7_LOGIN &&
|
||||||
|
${header.command} != REMOTE_PROCEDURE_CALL &&
|
||||||
|
${header.command} != RESPONSE &&
|
||||||
|
${header.command} != UNUSED &&
|
||||||
|
${header.command} != ATTENTION_REQUEST &&
|
||||||
|
${header.command} != BULK_LOAD_DATA &&
|
||||||
|
${header.command} != TRANSACTION_MANAGER &&
|
||||||
|
${header.command} != TDS5_QUERY &&
|
||||||
|
${header.command} != TDS7_LOGIN &&
|
||||||
|
${header.command} != SSPI_MESSAGE &&
|
||||||
|
${header.command} != TDS7_PRELOGIN) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
connection()->zeek_analyzer()->AnalyzerConfirmation();
|
||||||
|
zeek::BifEvent::enqueue_tds(connection()->zeek_analyzer(),
|
||||||
|
connection()->zeek_analyzer()->Conn(),
|
||||||
|
is_orig(),
|
||||||
|
${header.command}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
|
||||||
|
function tds_rpc(rpc: TDS_RPC): bool %{
|
||||||
|
if(::tds_rpc) {
|
||||||
|
connection()->zeek_analyzer()->AnalyzerConfirmation();
|
||||||
|
zeek::BifEvent::enqueue_tds_rpc(connection()->zeek_analyzer(),
|
||||||
|
connection()->zeek_analyzer()->Conn(),
|
||||||
|
is_orig(),
|
||||||
|
to_stringval(${rpc.procedure_name}),
|
||||||
|
to_stringval(${rpc.parameters})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
|
||||||
|
function tds_sql_batch(sqlBatch: TDS_SQL_BATCH): bool %{
|
||||||
|
if(::tds_sql_batch) {
|
||||||
|
if (${sqlBatch.stream_header.header_type} != QUERY_NOTIFICATIONS &&
|
||||||
|
${sqlBatch.stream_header.header_type} != TRANSACTION_DESCRIPTOR) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
connection()->zeek_analyzer()->AnalyzerConfirmation();
|
||||||
|
zeek::BifEvent::enqueue_tds_sql_batch(connection()->zeek_analyzer(),
|
||||||
|
connection()->zeek_analyzer()->Conn(),
|
||||||
|
is_orig(),
|
||||||
|
${sqlBatch.stream_header.header_type},
|
||||||
|
to_stringval(${sqlBatch.query})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
%}
|
||||||
|
};
|
||||||
|
|
||||||
|
refine typeattr TDS += &let {
|
||||||
|
tds: bool = $context.flow.tds(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
refine typeattr TDS_RPC += &let {
|
||||||
|
tds_rpc: bool = $context.flow.tds_rpc(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
refine typeattr TDS_SQL_BATCH += &let {
|
||||||
|
tds_sql_batch: bool = $context.flow.tds_sql_batch(this);
|
||||||
|
};
|
||||||
92
src/tds-protocol.pac
Normal file
92
src/tds-protocol.pac
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
## Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
|
## SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
#
|
||||||
|
# Binpac for Microsoft TDS analyser.
|
||||||
|
# More information from https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-tds/b46a581a-39de-4745-b076-ec4dbb7d13ec
|
||||||
|
#
|
||||||
|
|
||||||
|
##############################
|
||||||
|
# CONSTANTS #
|
||||||
|
##############################
|
||||||
|
|
||||||
|
enum cmd_codes {
|
||||||
|
SQL_BATCH = 0x01,
|
||||||
|
PRE_TDS7_LOGIN = 0x02,
|
||||||
|
REMOTE_PROCEDURE_CALL = 0x03,
|
||||||
|
RESPONSE = 0x04,
|
||||||
|
UNUSED = 0x05,
|
||||||
|
ATTENTION_REQUEST = 0x06,
|
||||||
|
BULK_LOAD_DATA = 0x07,
|
||||||
|
TRANSACTION_MANAGER = 0x0e,
|
||||||
|
TDS5_QUERY = 0x0F,
|
||||||
|
TDS7_LOGIN = 0x10,
|
||||||
|
SSPI_MESSAGE = 0x11,
|
||||||
|
TDS7_PRELOGIN = 0x12
|
||||||
|
};
|
||||||
|
|
||||||
|
##############################
|
||||||
|
## RECORD TYPES #
|
||||||
|
##############################
|
||||||
|
|
||||||
|
## All multiple byte fields are set in little endian order
|
||||||
|
## Packets are set in big endian order
|
||||||
|
|
||||||
|
type TDS_PDU(is_orig: bool) = case is_orig of {
|
||||||
|
true -> request : TDS_Request;
|
||||||
|
false -> response : TDS_Response;
|
||||||
|
} &byteorder=bigendian;
|
||||||
|
|
||||||
|
# switch for the request portion
|
||||||
|
type TDS_Request = record {
|
||||||
|
header: TDS;
|
||||||
|
data: case(header.command) of {
|
||||||
|
REMOTE_PROCEDURE_CALL -> remoteProcedureCall : TDS_RPC;
|
||||||
|
SQL_BATCH -> sqlBatch : TDS_SQL_BATCH;
|
||||||
|
default -> unknown : bytestring &restofdata;
|
||||||
|
};
|
||||||
|
} &byteorder=bigendian;
|
||||||
|
|
||||||
|
# switch for the response portion
|
||||||
|
type TDS_Response = record {
|
||||||
|
header: TDS;
|
||||||
|
data: case(header.command) of {
|
||||||
|
RESPONSE -> response : TDS_RESPONSE;
|
||||||
|
##! SQL_BATCH -> sqlBatch : TDS_SQL_BATCH;
|
||||||
|
default -> unknown : bytestring &restofdata;
|
||||||
|
};
|
||||||
|
} &byteorder=bigendian;
|
||||||
|
|
||||||
|
type TDS = record {
|
||||||
|
command : uint8;
|
||||||
|
status : uint8;
|
||||||
|
len : uint16;
|
||||||
|
channel : uint16;
|
||||||
|
packet_number : uint8;
|
||||||
|
window : uint8;
|
||||||
|
} &byteorder=bigendian;
|
||||||
|
|
||||||
|
type TDS_RPC = record {
|
||||||
|
stream_header : Stream_Header;
|
||||||
|
name_len : uint16 &byteorder=littleendian;
|
||||||
|
procedure_name : bytestring &length=name_len*2;
|
||||||
|
option_flags : uint16 &byteorder=littleendian;
|
||||||
|
parameters : bytestring &restofdata;
|
||||||
|
} &byteorder=bigendian;
|
||||||
|
|
||||||
|
type TDS_SQL_BATCH = record {
|
||||||
|
stream_header : Stream_Header;
|
||||||
|
query : bytestring &restofdata;
|
||||||
|
} &byteorder=bigendian;
|
||||||
|
|
||||||
|
type Stream_Header = record {
|
||||||
|
total_len : uint32;
|
||||||
|
header_len : uint32;
|
||||||
|
header_type : uint16;
|
||||||
|
descriptor : uint64;
|
||||||
|
request_count : uint32;
|
||||||
|
} &byteorder=littleendian;
|
||||||
|
|
||||||
|
type TDS_RESPONSE = record {
|
||||||
|
tokens : bytestring &restofdata;
|
||||||
|
} &byteorder=bigendian;
|
||||||
14
src/tds.pac
Normal file
14
src/tds.pac
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
%include zeek/binpac.pac
|
||||||
|
%include zeek/zeek.pac
|
||||||
|
|
||||||
|
%extern{
|
||||||
|
#include "events.bif.h"
|
||||||
|
%}
|
||||||
|
|
||||||
|
analyzer TDS withcontext {
|
||||||
|
connection: TDS_Conn;
|
||||||
|
flow: TDS_Flow;
|
||||||
|
};
|
||||||
|
|
||||||
|
%include tds-protocol.pac
|
||||||
|
%include tds-analyzer.pac
|
||||||
Loading…
x
Reference in New Issue
Block a user