mirror of
https://github.com/owasp-modsecurity/ModSecurity.git
synced 2025-08-13 13:26:01 +03:00
Adds support to the server ID generation
The server ID is a sha-1 identifier generated from the mac address of the first ethernet device plus the server name. The process is the same used by ModSecurity 2.9
This commit is contained in:
parent
aadbacf854
commit
2109910848
@ -43,6 +43,7 @@ AM_CONDITIONAL([YAJL_VERSION], [test "$YAJL_VERSION" != ""])
|
||||
AC_HEADER_STDC
|
||||
AC_CHECK_HEADERS([string])
|
||||
AC_CHECK_HEADERS([iostream])
|
||||
AC_CHECK_HEADERS([sys/utsname.h])
|
||||
|
||||
|
||||
# ??
|
||||
|
@ -35,7 +35,7 @@ int main (int argc, char **argv)
|
||||
|
||||
assay = msc_new_assay(modsec, rules);
|
||||
|
||||
msc_process_connection(assay, "127.0.0.1");
|
||||
msc_process_connection(assay, "127.0.0.1", 12345, "127.0.0.1", 80);
|
||||
msc_process_uri(assay, "http://www.modsecurity.org/test?key1=value1&key2=value2&key3=value3&test=args&test=test");
|
||||
msc_process_request_headers(assay);
|
||||
msc_process_request_body(assay);
|
||||
|
@ -85,7 +85,8 @@ class Assay {
|
||||
~Assay();
|
||||
|
||||
/** TODO: Should be an structure that fits an IP address */
|
||||
int processConnection(const char *ip);
|
||||
int processConnection(const char *client, int cPort,
|
||||
const char *server, int sPort);
|
||||
int processURI(const char *uri);
|
||||
|
||||
|
||||
@ -135,7 +136,10 @@ class Assay {
|
||||
private:
|
||||
std::ofstream myfile;
|
||||
Rules *m_rules;
|
||||
const char *m_ipAddress;
|
||||
const char *m_clientIpAddress;
|
||||
const char *m_serverIpAddress;
|
||||
int m_clientPort;
|
||||
int m_serverPort;
|
||||
const char *m_uri;
|
||||
std::ostringstream m_requestBody;
|
||||
std::ostringstream m_responseBody;
|
||||
@ -153,7 +157,8 @@ extern "C" {
|
||||
Assay *msc_new_assay(ModSecurity *ms, Rules *rules);
|
||||
|
||||
/** @ingroup ModSecurity_C_API */
|
||||
int msc_process_connection(Assay *assay, const char *ip);
|
||||
int msc_process_connection(Assay *assay, const char *client, int cPort,
|
||||
const char *server, int sPort);
|
||||
|
||||
/** @ingroup ModSecurity_C_API */
|
||||
int msc_process_request_headers(Assay *assay);
|
||||
|
@ -74,6 +74,8 @@ ACTIONS = \
|
||||
actions/transformations/url_encode.cc \
|
||||
actions/transformations/utf8_to_unicode.cc
|
||||
|
||||
UTILS = \
|
||||
utils/sha1.cc
|
||||
|
||||
libmodsecurity_la_SOURCES = \
|
||||
parser/seclang-parser.yy \
|
||||
@ -89,6 +91,7 @@ libmodsecurity_la_SOURCES = \
|
||||
utils.cc \
|
||||
debug_log.cc \
|
||||
rule.cc \
|
||||
unique_id.cc \
|
||||
variable.cc \
|
||||
operators/operator.cc \
|
||||
operators/detect_sqli.cc \
|
||||
@ -127,7 +130,8 @@ libmodsecurity_la_SOURCES = \
|
||||
operators/str_eq.cc \
|
||||
operators/str_match.cc \
|
||||
operators/begins_with.cc \
|
||||
${ACTIONS}
|
||||
${ACTIONS} \
|
||||
${UTILS}
|
||||
|
||||
|
||||
|
||||
|
35
src/assay.cc
35
src/assay.cc
@ -61,7 +61,7 @@ namespace ModSecurity {
|
||||
* rules->loadFromUri(rules_file);
|
||||
*
|
||||
* Assay *modsecAssay = new Assay(modsec, rules);
|
||||
* modsecAssay->processConnection("127.0.0.1");
|
||||
* modsecAssay->processConnection("127.0.0.1", 33333, "127.0.0.1", 8080);
|
||||
*
|
||||
* if (modsecAssay->intervention()) {
|
||||
* std::cout << "There is an intervention" << std::endl;
|
||||
@ -73,8 +73,11 @@ namespace ModSecurity {
|
||||
*
|
||||
*/
|
||||
Assay::Assay(ModSecurity *ms, Rules *rules)
|
||||
: m_ipAddress(NULL),
|
||||
m_uri(NULL),
|
||||
: m_clientIpAddress(""),
|
||||
m_serverIpAddress(""),
|
||||
m_clientPort(0),
|
||||
m_serverPort(0),
|
||||
m_uri(""),
|
||||
m_rules(rules),
|
||||
save_in_auditlog(false),
|
||||
do_not_save_in_auditlog(false),
|
||||
@ -115,19 +118,27 @@ void Assay::debug(int level, std::string message) {
|
||||
*
|
||||
* @note Remember to check for a possible intervention.
|
||||
*
|
||||
* @param buf Client's IP address in text format.
|
||||
* @param assay ModSecurity assay.
|
||||
* @param client Client's IP address in text format.
|
||||
* @param cPort Client's port
|
||||
* @param server Server's IP address in text format.
|
||||
* @param sPort Server's port
|
||||
*
|
||||
* @returns If the operation was successful or not.
|
||||
* @retval true Operation was successful.
|
||||
* @retval false Operation failed.
|
||||
*
|
||||
*/
|
||||
int Assay::processConnection(const char *ipAddress) {
|
||||
this->m_ipAddress = ipAddress;
|
||||
int Assay::processConnection(const char *client, int cPort, const char *server,
|
||||
int sPort) {
|
||||
this->m_clientIpAddress = client;
|
||||
this->m_serverIpAddress = server;
|
||||
this->m_clientPort = cPort;
|
||||
this->m_serverPort = sPort;
|
||||
debug(4, "Transaction context created (blah blah)");
|
||||
debug(4, "Starting phase CONNECTION. (SecRules 0)");
|
||||
|
||||
this->store_variable("REMOTE_ADDR", ipAddress);
|
||||
this->store_variable("REMOTE_ADDR", m_clientIpAddress);
|
||||
this->m_rules->evaluate(ModSecurity::ConnectionPhase, this);
|
||||
return true;
|
||||
}
|
||||
@ -711,15 +722,19 @@ extern "C" Assay *msc_new_assay(ModSecurity *ms,
|
||||
* @note Remember to check for a possible intervention.
|
||||
*
|
||||
* @param assay ModSecurity assay.
|
||||
* @param buf Client's IP address in text format.
|
||||
* @param client Client's IP address in text format.
|
||||
* @param cPort Client's port
|
||||
* @param server Server's IP address in text format.
|
||||
* @param sPort Server's port
|
||||
*
|
||||
* @returns If the operation was successful or not.
|
||||
* @retval 1 Operation was successful.
|
||||
* @retval 0 Operation failed.
|
||||
*
|
||||
*/
|
||||
extern "C" int msc_process_connection(Assay *assay, const char *buf) {
|
||||
return assay->processConnection(buf);
|
||||
extern "C" int msc_process_connection(Assay *assay, const char *client,
|
||||
int cPort, const char *server, int sPort) {
|
||||
return assay->processConnection(client, cPort, server, sPort);
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,7 +17,8 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "modsecurity/modsecurity.h"
|
||||
#include "src/utils.h"
|
||||
#include "src/unique_id.h"
|
||||
|
||||
|
||||
namespace ModSecurity {
|
||||
|
||||
@ -39,6 +40,7 @@ namespace ModSecurity {
|
||||
* @endcode
|
||||
*/
|
||||
ModSecurity::ModSecurity() {
|
||||
UniqueId::uniqueId();
|
||||
}
|
||||
|
||||
|
||||
|
230
src/unique_id.cc
Normal file
230
src/unique_id.cc
Normal file
@ -0,0 +1,230 @@
|
||||
/*
|
||||
* ModSecurity, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address security@modsecurity.org.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "src/unique_id.h"
|
||||
#include "src/config.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
#endif
|
||||
|
||||
#if (defined(__linux__) || defined(__gnu_linux__)) || DARWIN
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
#ifdef DARWIN
|
||||
#include <ifaddrs.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <sys/types.h>
|
||||
#ifndef IFT_ETHER
|
||||
#define IFT_ETHER 0x6 /* Ethernet CSMACD */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if (defined(__linux__) || defined(__gnu_linux__))
|
||||
#include <linux/if.h>
|
||||
#include <linux/sockios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_UTSNAME_H
|
||||
#include <sys/utsname.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "src/utils/sha1.h"
|
||||
|
||||
namespace ModSecurity {
|
||||
|
||||
void UniqueId::fillUniqueId() {
|
||||
std::string macAddress;
|
||||
std::string name;
|
||||
Utils::SHA1 sha1;
|
||||
|
||||
macAddress = ethernetMacAddress();
|
||||
name = machineName();
|
||||
|
||||
sha1.update(&macAddress);
|
||||
sha1.update(&name);
|
||||
|
||||
this->uniqueId_str = sha1.final();
|
||||
}
|
||||
|
||||
// Based on:
|
||||
// http://stackoverflow.com/questions/16858782/how-to-obtain-almost-unique-system-identifier-in-a-cross-platform-way
|
||||
std::string UniqueId::machineName() {
|
||||
char machine_name[MAX_MACHINE_NAME_SIZE];
|
||||
size_t len = MAX_MACHINE_NAME_SIZE;
|
||||
#ifdef WIN32
|
||||
DWORD lenComputerName = len;
|
||||
#endif
|
||||
|
||||
memset(machine_name, '\0', sizeof(char) * len);
|
||||
|
||||
#ifdef WIN32
|
||||
if (GetComputerName(machine_name, &lenComputerName) == 0) {
|
||||
goto failed;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_UTSNAME_H
|
||||
static struct utsname u;
|
||||
|
||||
if (uname(&u) < 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
snprintf(machine_name, len-1, "%s", u.nodename);
|
||||
#endif
|
||||
|
||||
return std::string(machine_name);
|
||||
|
||||
failed:
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
std::string UniqueId::ethernetMacAddress() {
|
||||
char mac[MAC_ADDRESS_SIZE];
|
||||
memset(mac, '\0', sizeof(char)*(MAC_ADDRESS_SIZE));
|
||||
#ifdef DARWIN
|
||||
struct ifaddrs* ifaphead;
|
||||
struct ifaddrs* ifap;
|
||||
int i = 0;
|
||||
|
||||
if (getifaddrs(&ifaphead) != 0) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// iterate over the net interfaces
|
||||
for (ifap = ifaphead; ifap; ifap = ifap->ifa_next) {
|
||||
struct sockaddr_dl* sdl = (struct sockaddr_dl*)ifap->ifa_addr;
|
||||
if (sdl && (sdl->sdl_family == AF_LINK) && (sdl->sdl_type == IFT_ETHER)
|
||||
&& mac[0] && mac[1] && mac[2] && i < 6) {
|
||||
snprintf(mac, MAC_ADDRESS_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
(unsigned char)LLADDR(sdl)[0],
|
||||
(unsigned char)LLADDR(sdl)[1],
|
||||
(unsigned char)LLADDR(sdl)[2],
|
||||
(unsigned char)LLADDR(sdl)[3],
|
||||
(unsigned char)LLADDR(sdl)[4],
|
||||
(unsigned char)LLADDR(sdl)[5]);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
freeifaddrs(ifaphead);
|
||||
#endif
|
||||
|
||||
#if (defined(__linux__) || defined(__gnu_linux__))
|
||||
struct ifconf conf;
|
||||
int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
|
||||
struct ifreq* ifr;
|
||||
if ( sock < 0 ) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
char ifconfbuf[128 * sizeof(struct ifreq)];
|
||||
memset(ifconfbuf, 0, sizeof(ifconfbuf));
|
||||
conf.ifc_buf = ifconfbuf;
|
||||
conf.ifc_len = sizeof(ifconfbuf);
|
||||
if (ioctl(sock, SIOCGIFCONF, &conf)) {
|
||||
close(sock);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
for (ifr = conf.ifc_req; ifr < conf.ifc_req + conf.ifc_len; ifr++) {
|
||||
if (ioctl(sock, SIOCGIFFLAGS, ifr)) {
|
||||
continue; // failed to get flags, skip it
|
||||
}
|
||||
|
||||
if (ioctl(sock, SIOCGIFHWADDR, ifr) == 0) {
|
||||
int i = 0;
|
||||
if (!ifr->ifr_addr.sa_data[0] && !ifr->ifr_addr.sa_data[1]
|
||||
&& !ifr->ifr_addr.sa_data[2]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
snprintf(mac, MAC_ADDRESS_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
(unsigned char)ifr->ifr_addr.sa_data[0],
|
||||
(unsigned char)ifr->ifr_addr.sa_data[1],
|
||||
(unsigned char)ifr->ifr_addr.sa_data[2],
|
||||
(unsigned char)ifr->ifr_addr.sa_data[3],
|
||||
(unsigned char)ifr->ifr_addr.sa_data[4],
|
||||
(unsigned char)ifr->ifr_addr.sa_data[5]);
|
||||
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
close(sock);
|
||||
#endif
|
||||
|
||||
#if WIN32
|
||||
PIP_ADAPTER_INFO pAdapterInfo;
|
||||
PIP_ADAPTER_INFO pAdapter = NULL;
|
||||
DWORD dwRetVal = 0;
|
||||
|
||||
ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);
|
||||
pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO *>(malloc( \
|
||||
sizeof (IP_ADAPTER_INFO)));
|
||||
if (!pAdapterInfo) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) {
|
||||
free(pAdapterInfo);
|
||||
pAdapterInfo = reinterpret_cast<IP_ADAPTER_INFO *>malloc(ulOutBufLen));
|
||||
if (!pAdapterInfo) {
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
|
||||
if (dwRetVal != NO_ERROR) {
|
||||
free(pAdapterInfo);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
pAdapter = pAdapterInfo;
|
||||
while (pAdapter && !mac[0] && !mac[1] && !mac[2]) {
|
||||
if (pAdapter->AddressLength > 4) {
|
||||
apr_snprintf(mac, MAC_ADDRESS_SIZE, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
(unsigned char)pAdapter->Address[0],
|
||||
(unsigned char)pAdapter->Address[1],
|
||||
(unsigned char)pAdapter->Address[2],
|
||||
(unsigned char)pAdapter->Address[3],
|
||||
(unsigned char)pAdapter->Address[4],
|
||||
(unsigned char)pAdapter->Address[5]);
|
||||
goto end;
|
||||
}
|
||||
pAdapter = pAdapter->Next;
|
||||
}
|
||||
|
||||
free(pAdapterInfo);
|
||||
#endif
|
||||
|
||||
end:
|
||||
return std::string(reinterpret_cast<const char *>(mac));
|
||||
failed:
|
||||
return std::string("");
|
||||
}
|
||||
|
||||
|
||||
} // namespace ModSecurity
|
67
src/unique_id.h
Normal file
67
src/unique_id.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* ModSecurity, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address security@modsecurity.org.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
#ifndef SRC_UNIQUE_ID_H_
|
||||
#define SRC_UNIQUE_ID_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace ModSecurity {
|
||||
|
||||
#define MAC_ADDRESS_SIZE 19
|
||||
#define MAX_MACHINE_NAME_SIZE 256
|
||||
|
||||
/** @ingroup ModSecurity_CPP_API */
|
||||
class UniqueId {
|
||||
public:
|
||||
static UniqueId& getInstance() {
|
||||
static UniqueId instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
static std::string uniqueId() {
|
||||
if (UniqueId::getInstance().uniqueId_str.empty()) {
|
||||
UniqueId::getInstance().fillUniqueId();
|
||||
}
|
||||
|
||||
return UniqueId::getInstance().uniqueId_str;
|
||||
}
|
||||
|
||||
void fillUniqueId();
|
||||
std::string machineName();
|
||||
std::string ethernetMacAddress();
|
||||
|
||||
std::string uniqueId_str;
|
||||
|
||||
private:
|
||||
UniqueId() {}
|
||||
// C++ 03
|
||||
UniqueId(UniqueId const&);
|
||||
// void operator=(UniqueId const&);
|
||||
|
||||
// C++ 11
|
||||
// UniqueId(UniqueId const&) = delete;
|
||||
// void operator=(UniqueId const&) = delete;
|
||||
};
|
||||
|
||||
} // namespace ModSecurity
|
||||
#endif
|
||||
|
||||
#endif // SRC_UNIQUE_ID_H_
|
268
src/utils/sha1.cc
Normal file
268
src/utils/sha1.cc
Normal file
@ -0,0 +1,268 @@
|
||||
/*
|
||||
* ModSecurity, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address security@modsecurity.org.
|
||||
*
|
||||
*/
|
||||
|
||||
/** TODO: Reimplement this on the same terms and/or check if we use it. */
|
||||
/*
|
||||
sha1.cpp - source code of
|
||||
|
||||
============
|
||||
SHA-1 in C++
|
||||
============
|
||||
|
||||
100% Public Domain.
|
||||
|
||||
Original C Code
|
||||
-- Steve Reid <steve@edmweb.com>
|
||||
Small changes to fit into bglibs
|
||||
-- Bruce Guenter <bruce@untroubled.org>
|
||||
Translation to simpler C++ Code
|
||||
-- Volker Grabsch <vog@notjusthosting.com>
|
||||
*/
|
||||
|
||||
#include "src/utils/sha1.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <fstream>
|
||||
|
||||
namespace ModSecurity {
|
||||
namespace Utils {
|
||||
|
||||
SHA1::SHA1() {
|
||||
reset();
|
||||
}
|
||||
|
||||
|
||||
void SHA1::update(std::string *s) {
|
||||
std::istringstream is(*s);
|
||||
update(&is);
|
||||
}
|
||||
|
||||
|
||||
void SHA1::update(std::istream *is) {
|
||||
std::string rest_of_buffer;
|
||||
read(is, &rest_of_buffer, BLOCK_BYTES - buffer.size());
|
||||
buffer += rest_of_buffer;
|
||||
|
||||
while (*is) {
|
||||
uint32 block[BLOCK_INTS];
|
||||
buffer_to_block(buffer, block);
|
||||
transform(block);
|
||||
read(is, &buffer, BLOCK_BYTES);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
std::string SHA1::final() {
|
||||
/* Total number of hashed bits */
|
||||
uint64 total_bits = (transforms*BLOCK_BYTES + buffer.size()) * 8;
|
||||
|
||||
/* Padding */
|
||||
buffer += 0x80;
|
||||
unsigned int orig_size = buffer.size();
|
||||
while (buffer.size() < BLOCK_BYTES) {
|
||||
buffer += static_cast<char>(0x00);
|
||||
}
|
||||
|
||||
uint32 block[BLOCK_INTS];
|
||||
buffer_to_block(buffer, block);
|
||||
|
||||
if (orig_size > BLOCK_BYTES - 8) {
|
||||
transform(block);
|
||||
for (unsigned int i = 0; i < BLOCK_INTS - 2; i++) {
|
||||
block[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Append total_bits, split this uint64 into two uint32 */
|
||||
block[BLOCK_INTS - 1] = total_bits;
|
||||
block[BLOCK_INTS - 2] = (total_bits >> 32);
|
||||
transform(block);
|
||||
|
||||
/* Hex std::string */
|
||||
std::ostringstream result;
|
||||
for (unsigned int i = 0; i < DIGEST_INTS; i++) {
|
||||
result << std::hex << std::setfill('0') << std::setw(8);
|
||||
result << (digest[i] & 0xffffffff);
|
||||
}
|
||||
|
||||
/* Reset for next run */
|
||||
reset();
|
||||
|
||||
return result.str();
|
||||
}
|
||||
|
||||
|
||||
void SHA1::reset() {
|
||||
/* SHA1 initialization constants */
|
||||
digest[0] = 0x67452301;
|
||||
digest[1] = 0xefcdab89;
|
||||
digest[2] = 0x98badcfe;
|
||||
digest[3] = 0x10325476;
|
||||
digest[4] = 0xc3d2e1f0;
|
||||
|
||||
/* Reset counters */
|
||||
transforms = 0;
|
||||
buffer = "";
|
||||
}
|
||||
|
||||
|
||||
void SHA1::transform(uint32 block[BLOCK_BYTES]) {
|
||||
/* Copy digest[] to working vars */
|
||||
uint32 a = digest[0];
|
||||
uint32 b = digest[1];
|
||||
uint32 c = digest[2];
|
||||
uint32 d = digest[3];
|
||||
uint32 e = digest[4];
|
||||
|
||||
/* Help macros */
|
||||
#define rol(value, bits) (((value) << (bits)) \
|
||||
| (((value) & 0xffffffff) >> (32 - (bits))))
|
||||
|
||||
#define blk(i) (block[i&15] = rol(block[(i+13)&15] \
|
||||
^ block[(i+8)&15] ^ block[(i+2)&15] ^ block[i&15], 1))
|
||||
|
||||
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
|
||||
#define R0(v, w, x, y, z, i) z += ((w&(x^y))^y) + block[i] \
|
||||
+ 0x5a827999 + rol(v, 5); w = rol(w, 30);
|
||||
#define R1(v, w, x, y, z, i) z += ((w&(x^y))^y) + blk(i) \
|
||||
+ 0x5a827999 + rol(v, 5); w = rol(w, 30);
|
||||
#define R2(v, w, x, y, z, i) z += (w^x^y) + blk(i) \
|
||||
+ 0x6ed9eba1 + rol(v, 5); w = rol(w, 30);
|
||||
#define R3(v, w, x, y, z, i) z += (((w|x)&y)|(w&x)) + blk(i) \
|
||||
+ 0x8f1bbcdc + rol(v, 5); w = rol(w, 30);
|
||||
#define R4(v, w, x, y, z, i) z += (w^x^y) + blk(i) \
|
||||
+ 0xca62c1d6 + rol(v, 5); w = rol(w, 30);
|
||||
|
||||
/* 4 rounds of 20 operations each. Loop unrolled. */
|
||||
R0(a, b, c, d, e, 0);
|
||||
R0(e, a, b, c, d, 1);
|
||||
R0(d, e, a, b, c, 2);
|
||||
R0(c, d, e, a, b, 3);
|
||||
R0(b, c, d, e, a, 4);
|
||||
R0(a, b, c, d, e, 5);
|
||||
R0(e, a, b, c, d, 6);
|
||||
R0(d, e, a, b, c, 7);
|
||||
R0(c, d, e, a, b, 8);
|
||||
R0(b, c, d, e, a, 9);
|
||||
R0(a, b, c, d, e, 10);
|
||||
R0(e, a, b, c, d, 11);
|
||||
R0(d, e, a, b, c, 12);
|
||||
R0(c, d, e, a, b, 13);
|
||||
R0(b, c, d, e, a, 14);
|
||||
R0(a, b, c, d, e, 15);
|
||||
R1(e, a, b, c, d, 16);
|
||||
R1(d, e, a, b, c, 17);
|
||||
R1(c, d, e, a, b, 18);
|
||||
R1(b, c, d, e, a, 19);
|
||||
R2(a, b, c, d, e, 20);
|
||||
R2(e, a, b, c, d, 21);
|
||||
R2(d, e, a, b, c, 22);
|
||||
R2(c, d, e, a, b, 23);
|
||||
R2(b, c, d, e, a, 24);
|
||||
R2(a, b, c, d, e, 25);
|
||||
R2(e, a, b, c, d, 26);
|
||||
R2(d, e, a, b, c, 27);
|
||||
R2(c, d, e, a, b, 28);
|
||||
R2(b, c, d, e, a, 29);
|
||||
R2(a, b, c, d, e, 30);
|
||||
R2(e, a, b, c, d, 31);
|
||||
R2(d, e, a, b, c, 32);
|
||||
R2(c, d, e, a, b, 33);
|
||||
R2(b, c, d, e, a, 34);
|
||||
R2(a, b, c, d, e, 35);
|
||||
R2(e, a, b, c, d, 36);
|
||||
R2(d, e, a, b, c, 37);
|
||||
R2(c, d, e, a, b, 38);
|
||||
R2(b, c, d, e, a, 39);
|
||||
R3(a, b, c, d, e, 40);
|
||||
R3(e, a, b, c, d, 41);
|
||||
R3(d, e, a, b, c, 42);
|
||||
R3(c, d, e, a, b, 43);
|
||||
R3(b, c, d, e, a, 44);
|
||||
R3(a, b, c, d, e, 45);
|
||||
R3(e, a, b, c, d, 46);
|
||||
R3(d, e, a, b, c, 47);
|
||||
R3(c, d, e, a, b, 48);
|
||||
R3(b, c, d, e, a, 49);
|
||||
R3(a, b, c, d, e, 50);
|
||||
R3(e, a, b, c, d, 51);
|
||||
R3(d, e, a, b, c, 52);
|
||||
R3(c, d, e, a, b, 53);
|
||||
R3(b, c, d, e, a, 54);
|
||||
R3(a, b, c, d, e, 55);
|
||||
R3(e, a, b, c, d, 56);
|
||||
R3(d, e, a, b, c, 57);
|
||||
R3(c, d, e, a, b, 58);
|
||||
R3(b, c, d, e, a, 59);
|
||||
R4(a, b, c, d, e, 60);
|
||||
R4(e, a, b, c, d, 61);
|
||||
R4(d, e, a, b, c, 62);
|
||||
R4(c, d, e, a, b, 63);
|
||||
R4(b, c, d, e, a, 64);
|
||||
R4(a, b, c, d, e, 65);
|
||||
R4(e, a, b, c, d, 66);
|
||||
R4(d, e, a, b, c, 67);
|
||||
R4(c, d, e, a, b, 68);
|
||||
R4(b, c, d, e, a, 69);
|
||||
R4(a, b, c, d, e, 70);
|
||||
R4(e, a, b, c, d, 71);
|
||||
R4(d, e, a, b, c, 72);
|
||||
R4(c, d, e, a, b, 73);
|
||||
R4(b, c, d, e, a, 74);
|
||||
R4(a, b, c, d, e, 75);
|
||||
R4(e, a, b, c, d, 76);
|
||||
R4(d, e, a, b, c, 77);
|
||||
R4(c, d, e, a, b, 78);
|
||||
R4(b, c, d, e, a, 79);
|
||||
|
||||
/* Add the working vars back into digest[] */
|
||||
digest[0] += a;
|
||||
digest[1] += b;
|
||||
digest[2] += c;
|
||||
digest[3] += d;
|
||||
digest[4] += e;
|
||||
|
||||
/* Count the number of transformations */
|
||||
transforms++;
|
||||
}
|
||||
|
||||
|
||||
void SHA1::buffer_to_block(const std::string &buffer,
|
||||
uint32 block[BLOCK_BYTES]) {
|
||||
/* Convert the std::string (byte buffer) to a uint32 array (MSB) */
|
||||
for (unsigned int i = 0; i < BLOCK_INTS; i++) {
|
||||
block[i] = (buffer[4 * i + 3] & 0xff)
|
||||
| (buffer[4 * i + 2] & 0xff) << 8
|
||||
| (buffer[4 * i + 1] & 0xff) << 16
|
||||
| (buffer[4 * i + 0] & 0xff) << 24;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void SHA1::read(std::istream *is, std::string *s, int k_max) {
|
||||
char sbuf[BLOCK_BYTES];
|
||||
|
||||
if (k_max > BLOCK_BYTES) {
|
||||
return;
|
||||
}
|
||||
|
||||
is->read(sbuf, k_max);
|
||||
s->assign(sbuf, is->gcount());
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
} // namespace ModSecurity
|
||||
|
79
src/utils/sha1.h
Normal file
79
src/utils/sha1.h
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* ModSecurity, http://www.modsecurity.org/
|
||||
* Copyright (c) 2015 Trustwave Holdings, Inc. (http://www.trustwave.com/)
|
||||
*
|
||||
* You may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* If any of the files related to licensing are missing or if you have any
|
||||
* other questions related to licensing please contact Trustwave Holdings, Inc.
|
||||
* directly using the email address security@modsecurity.org.
|
||||
*
|
||||
*/
|
||||
|
||||
/** TODO: Reimplement this on the same terms and/or check if we use it. */
|
||||
/*
|
||||
sha1.h - header of
|
||||
|
||||
============
|
||||
SHA-1 in C++
|
||||
============
|
||||
|
||||
100% Public Domain.
|
||||
|
||||
Original C Code
|
||||
-- Steve Reid <steve@edmweb.com>
|
||||
Small changes to fit into bglibs
|
||||
-- Bruce Guenter <bruce@untroubled.org>
|
||||
Translation to simpler C++ Code
|
||||
-- Volker Grabsch <vog@notjusthosting.com>
|
||||
*/
|
||||
|
||||
#ifndef SRC_UTILS_SHA1_H_
|
||||
#define SRC_UTILS_SHA1_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
namespace ModSecurity {
|
||||
namespace Utils {
|
||||
|
||||
class SHA1 {
|
||||
public:
|
||||
SHA1();
|
||||
void update(std::string *s);
|
||||
void update(std::istream *is);
|
||||
std::string final();
|
||||
|
||||
private:
|
||||
/* just needs to be at least 32bit */
|
||||
typedef unsigned long int uint32;
|
||||
/* just needs to be at least 64bit */
|
||||
typedef unsigned long long uint64;
|
||||
|
||||
/* number of 32bit integers per SHA1 digest */
|
||||
static const unsigned int DIGEST_INTS = 5;
|
||||
/* number of 32bit integers per SHA1 block */
|
||||
static const unsigned int BLOCK_INTS = 16;
|
||||
static const unsigned int BLOCK_BYTES = BLOCK_INTS * 4;
|
||||
|
||||
uint32 digest[DIGEST_INTS];
|
||||
std::string buffer;
|
||||
uint64 transforms;
|
||||
|
||||
void reset();
|
||||
void transform(uint32 block[BLOCK_BYTES]);
|
||||
|
||||
static void buffer_to_block(const std::string &buffer,
|
||||
uint32 block[BLOCK_BYTES]);
|
||||
|
||||
void read(std::istream *is, std::string *s, int max);
|
||||
};
|
||||
|
||||
} // namespace Utils
|
||||
} // namespace ModSecurity
|
||||
|
||||
#endif // SRC_UTILS_SHA1_H_
|
@ -81,7 +81,7 @@ int main(int argc, char *argv[]) {
|
||||
std::cout << "Proceding with request " << i << std::endl;
|
||||
|
||||
Assay *modsecAssay = new Assay(modsec, rules);
|
||||
modsecAssay->processConnection(ip);
|
||||
modsecAssay->processConnection(ip, 12345, "127.0.0.1", 80);
|
||||
|
||||
if (modsecAssay->intervention()) {
|
||||
std::cout << "There is an intervention" << std::endl;
|
||||
|
@ -78,13 +78,12 @@ void perform_unit_test(std::vector<RegressionTest *> *tests,
|
||||
}
|
||||
modsec_assay = new ModSecurity::Assay(modsec, modsec_rules);
|
||||
|
||||
if (t->ip.empty() == false) {
|
||||
// FIXME: no cast please.
|
||||
modsec_assay->processConnection(t->ip.c_str());
|
||||
actions(&r, modsec_assay->intervention());
|
||||
if (r.status != 200) {
|
||||
goto end;
|
||||
}
|
||||
modsec_assay->processConnection(t->clientIp.c_str(),
|
||||
t->clientPort, t->serverIp.c_str(), t->serverPort);
|
||||
|
||||
actions(&r, modsec_assay->intervention());
|
||||
if (r.status != 200) {
|
||||
goto end;
|
||||
}
|
||||
if (t->uri.empty() == false) {
|
||||
modsec_assay->processURI(t->uri.c_str());
|
||||
|
@ -107,6 +107,32 @@ RegressionTest *RegressionTest::from_yajl_node(const yajl_val &node) {
|
||||
if (strcmp(key, "github_issue") == 0) {
|
||||
u->github_issue = YAJL_GET_INTEGER(val);
|
||||
}
|
||||
if (strcmp(key, "client") == 0) {
|
||||
for (int j = 0; j < val->u.object.len; j++) {
|
||||
const char *key2 = val->u.object.keys[j];
|
||||
yajl_val val2 = val->u.object.values[j];
|
||||
|
||||
if (strcmp(key2, "ip") == 0) {
|
||||
u->clientIp = YAJL_GET_STRING(val2);
|
||||
}
|
||||
if (strcmp(key2, "port") == 0) {
|
||||
u->clientPort = YAJL_GET_INTEGER(val2);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (strcmp(key, "server") == 0) {
|
||||
for (int j = 0; j < val->u.object.len; j++) {
|
||||
const char *key2 = val->u.object.keys[j];
|
||||
yajl_val val2 = val->u.object.values[j];
|
||||
|
||||
if (strcmp(key2, "ip") == 0) {
|
||||
u->serverIp = YAJL_GET_STRING(val2);
|
||||
}
|
||||
if (strcmp(key2, "port") == 0) {
|
||||
u->serverPort = YAJL_GET_INTEGER(val2);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (strcmp(key, "request") == 0) {
|
||||
for (int j = 0; j < val->u.object.len; j++) {
|
||||
const char *key2 = val->u.object.keys[j];
|
||||
@ -115,9 +141,6 @@ RegressionTest *RegressionTest::from_yajl_node(const yajl_val &node) {
|
||||
if (strcmp(key2, "uri") == 0) {
|
||||
u->uri = YAJL_GET_STRING(val2);
|
||||
}
|
||||
if (strcmp(key2, "ip") == 0) {
|
||||
u->ip = YAJL_GET_STRING(val2);
|
||||
}
|
||||
if (strcmp(key2, "headers") == 0) {
|
||||
u->request_headers = yajl_array_to_map(val2);
|
||||
}
|
||||
|
@ -51,7 +51,11 @@ class RegressionTest {
|
||||
std::string debug_log;
|
||||
std::string error_log;
|
||||
|
||||
std::string ip;
|
||||
std::string clientIp;
|
||||
std::string serverIp;
|
||||
int clientPort;
|
||||
int serverPort;
|
||||
|
||||
std::string uri;
|
||||
|
||||
static inline std::string yajl_array_to_str(const yajl_val &node);
|
||||
|
@ -4,8 +4,15 @@
|
||||
"version_min": 300000,
|
||||
"version_max": 0,
|
||||
"title": "actions :: trim,block",
|
||||
"request": {
|
||||
"client": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 2313
|
||||
},
|
||||
"server": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 80
|
||||
},
|
||||
"request": {
|
||||
"headers": {
|
||||
"Host": "net.tutsplus.com",
|
||||
"User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)",
|
||||
@ -56,8 +63,15 @@
|
||||
"version_min": 300000,
|
||||
"version_max": 0,
|
||||
"title": "actions :: trim,redirect:http://www.google.com",
|
||||
"request": {
|
||||
"client": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 2313
|
||||
},
|
||||
"server": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 80
|
||||
},
|
||||
"request": {
|
||||
"headers": {
|
||||
"Host": "net.tutsplus.com",
|
||||
"User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)",
|
||||
@ -109,8 +123,15 @@
|
||||
"version_min": 300000,
|
||||
"version_max": 0,
|
||||
"title": "actions :: trim,status:500,redirect:http://www.google.com",
|
||||
"request": {
|
||||
"client": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 2313
|
||||
},
|
||||
"server": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 80
|
||||
},
|
||||
"request": {
|
||||
"headers": {
|
||||
"Host": "net.tutsplus.com",
|
||||
"User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)",
|
||||
@ -162,8 +183,15 @@
|
||||
"version_min": 300000,
|
||||
"version_max": 0,
|
||||
"title": "actions :: trim,status:500",
|
||||
"request": {
|
||||
"client": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 2313
|
||||
},
|
||||
"server": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 80
|
||||
},
|
||||
"request": {
|
||||
"headers": {
|
||||
"Host": "net.tutsplus.com",
|
||||
"User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)",
|
||||
@ -214,8 +242,15 @@
|
||||
"version_min": 300000,
|
||||
"version_max": 0,
|
||||
"title": "actions :: phase:1,trim,status:500",
|
||||
"request": {
|
||||
"client": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 2313
|
||||
},
|
||||
"server": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 80
|
||||
},
|
||||
"request": {
|
||||
"headers": {
|
||||
"Host": "net.tutsplus.com",
|
||||
"User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)",
|
||||
@ -266,8 +301,15 @@
|
||||
"version_min": 300000,
|
||||
"version_max": 0,
|
||||
"title": "actions :: phase:4,trim,status:500",
|
||||
"request": {
|
||||
"client": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 2313
|
||||
},
|
||||
"server": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 80
|
||||
},
|
||||
"request": {
|
||||
"headers": {
|
||||
"Host": "net.tutsplus.com",
|
||||
"User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)",
|
||||
|
@ -4,8 +4,15 @@
|
||||
"version_min": 300000,
|
||||
"version_max": 0,
|
||||
"title": "auditlog : basic parser test",
|
||||
"request": {
|
||||
"client": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 2313
|
||||
},
|
||||
"server": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 80
|
||||
},
|
||||
"request": {
|
||||
"headers": {
|
||||
"Host": "www.modsecurity.org",
|
||||
"User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)",
|
||||
|
@ -4,8 +4,15 @@
|
||||
"version_min": 300000,
|
||||
"version_max": 0,
|
||||
"title": "Debug log",
|
||||
"request": {
|
||||
"client": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 2313
|
||||
},
|
||||
"server": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 80
|
||||
},
|
||||
"request": {
|
||||
"headers": {
|
||||
"Host": "net.tutsplus.com",
|
||||
"User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)",
|
||||
|
@ -6,6 +6,14 @@
|
||||
"title": "Segmentation fault when uploading file with SecStreamInBodyInspection enabled",
|
||||
"url": "https:\/\/github.com\/SpiderLabs\/ModSecurity\/issues\/394",
|
||||
"gihub_issue": 394,
|
||||
"client": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 2313
|
||||
},
|
||||
"server": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 80
|
||||
},
|
||||
"request": {
|
||||
"headers": "",
|
||||
"body": ""
|
||||
|
@ -4,8 +4,15 @@
|
||||
"version_min": 300000,
|
||||
"version_max": 0,
|
||||
"title": "Testing transformations :: pass,t:trim",
|
||||
"request": {
|
||||
"client": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 2313
|
||||
},
|
||||
"server": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 80
|
||||
},
|
||||
"request": {
|
||||
"headers": {
|
||||
"Host": "net.tutsplus.com",
|
||||
"User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)",
|
||||
@ -55,8 +62,15 @@
|
||||
"version_min": 300000,
|
||||
"version_max": 0,
|
||||
"title": "Testing transformations :: pass,t:trim,t:lowercase",
|
||||
"request": {
|
||||
"client": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 2313
|
||||
},
|
||||
"server": {
|
||||
"ip": "200.249.12.31",
|
||||
"port": 80
|
||||
},
|
||||
"request": {
|
||||
"headers": {
|
||||
"Host": "net.tutsplus.com",
|
||||
"User-Agent": "Mozilla\/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko\/20091102 Firefox\/3.5.5 (.NET CLR 3.5.30729)",
|
||||
|
Loading…
x
Reference in New Issue
Block a user