Commit 589ae180 authored by Olivier Dion's avatar Olivier Dion Committed by Adrien Béraud
Browse files

fuzzing/examples: Add examples that were used as LD_PRELOAD

Change-Id: Ieeda03d459eeefb86a19e57277bde7c194e5b8c5
parent d26984cc
/*
* Copyright (C) 2021 Savoir-faire Linux Inc.
*
* Author: Olivier Dion <olivier.dion>@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <cstdlib>
#include <set>
#include <msgpack.hpp>
#include "jamidht/multiplexed_socket.h"
#include "lib/gnutls.h"
enum class ChannelRequestState {
REQUEST,
ACCEPT,
DECLINE,
};
/**
* That msgpack structure is used to request a new channel (id, name)
* Transmitted over the TLS socket
*/
struct ChannelRequest
{
std::string name {};
uint16_t channel {0};
ChannelRequestState state {ChannelRequestState::REQUEST};
MSGPACK_DEFINE(name, channel, state)
};
/*
* Mangle channel
*/
bool
mutate_gnutls_record_send(ChanneledMessage& msg)
{
try {
msgpack::unpacked result;
msgpack::unpack(result, (const char*) msg.data.data(), msg.data.size(), 0);
auto object = result.get();
auto req = object.as<ChannelRequest>();
int state = rand() % 8;
static_assert(sizeof(state) == sizeof(req.state));
memcpy(&req.state, &state, sizeof(state));
msgpack::sbuffer buffer(512);
msgpack::pack(buffer, req);
msg.data.clear();
for (size_t i=0; i<buffer.size(); ++i) {
msg.data.emplace_back(buffer.data()[i]);
}
} catch (...) {
return false;
}
return true;
}
MSGPACK_ADD_ENUM(ChannelRequestState);
/*
* Copyright (C) 2021 Savoir-faire Linux Inc.
*
* Author: Olivier Dion <olivier.dion>@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <cstdlib>
#include <set>
#include "jamidht/multiplexed_socket.h"
#include "lib/gnutls.h"
#if 0
static std::set<uint16_t> known_channel {};
static std::vector<channel
__attribute__((constructor))
static void channel_spammer(void)
{
std::thread([&]{
std::unique_lock<std::mutex> ulock(spammer_lock);
while (true) {
}
}).detach();
}
/*
* Mangle channel
*/
bool
mutate_gnutls_record_recv(ChanneledMessage& msg)
{
known_channel.emplace(msg.channel);
auto it = known_channel.begin();
std::advance(it, rand() % known_channel.size());
msg.channel = *it;
return true;
}
#endif
/*
* Copyright (C) 2021 Savoir-faire Linux Inc.
*
* Author: Olivier Dion <olivier.dion>@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* Do Nothing */
/*
* Copyright (C) 2021 Savoir-faire Linux Inc.
*
* Author: Olivier Dion <olivier.dion>@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <memory>
#include <thread>
#include "lib/gnutls.h"
/* Jami */
#include "jamidht/multiplexed_socket.h"
static gnutls_session_t captured_session = nullptr;
static std::mutex worker_lock {};
static std::condition_variable cv;
struct VersionMsg
{
int v;
MSGPACK_DEFINE_MAP(v)
};
__attribute__((constructor))
static void
init(void)
{
std::thread([&] {
msgpack::sbuffer buffer(8);
{
msgpack::packer<msgpack::sbuffer> pk(&buffer);
pk.pack(VersionMsg {rand()});
}
msgpack::sbuffer buffer2(16 + buffer.size());
{
msgpack::packer<msgpack::sbuffer> pk(&buffer2);
pk.pack_array(2);
pk.pack(jami::PROTOCOL_CHANNEL);
pk.pack_bin(buffer2.size());
pk.pack_bin_body(buffer2.data(), buffer2.size());
}
std::unique_lock<std::mutex> lock(worker_lock);
cv.wait(lock);
while (true) {
gnutls_record_send(captured_session, buffer2.data(), buffer2.size());
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
}).detach();
}
void
post_gnutls_init_hook(const gnutls_session_t session)
{
if (nullptr == captured_session) {
captured_session = session;
cv.notify_one();
}
}
/*
* Copyright (C) 2021 Savoir-faire Linux Inc.
*
* Author: Olivier Dion <olivier.dion>@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "lib/gnutls.h"
static gnutls_session_t captured_tls_session = nullptr;
void post_gnutls_init_hook(const gnutls_session_t session)
{
captured_tls_session = session;
}
/*
* Copyright (C) 2021 Savoir-faire Linux Inc.
*
* Author: Olivier Dion <olivier.dion>@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "lib/gnutls.h"
#include "lib/syslog.h"
/*
* Reverse channel and data in packed message
*/
void
pack_gnutls_record_recv(msgpack::sbuffer& buf, const ChanneledMessage& msg)
{
msgpack::packer<msgpack::sbuffer> pk(&buf);
#if 0
pk.pack_array(2);
pk.pack_bin(msg.data.size());
pk.pack_bin_body((const char*) msg.data.data(), msg.data.size());
pk.pack(msg.channel);
#else
pk.pack_array(1);
pk.pack(msg.channel);
#endif
}
bool
mutate_gnutls_record_recv(ChanneledMessage& msg)
{
(void)msg;
return true;
}
/*
* Copyright (C) 2021 Savoir-faire Linux Inc.
*
* Author: Olivier Dion <olivier.dion>@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <mutex>
#include <memory>
#include <thread>
#include "lib/gnutls.h"
static gnutls_session_t captured_session = nullptr;
static std::mutex worker_lock {};
static std::condition_variable cv {};
__attribute__((constructor))
static void
init(void)
{
std::thread([&] {
std::unique_lock<std::mutex> lock(worker_lock);
cv.wait(lock);
size_t max_size = gnutls_record_get_max_size(captured_session);
void *payload = NULL;
while (true) {
size_t size = (size_t)rand() % max_size;
payload = realloc(payload, size);
printf("Spamming random payload of %zu bytes...\n",
size);
gnutls_record_send(captured_session, payload, size);
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
}).detach();
}
void
post_gnutls_init_hook(const gnutls_session_t session)
{
if (nullptr == captured_session) {
captured_session = session;
cv.notify_one();
}
}
/*
* Copyright (C) 2021 Savoir-faire Linux Inc.
*
* Author: Olivier Dion <olivier.dion>@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <cstdlib>
#include "lib/gnutls.h"
#include "lib/sip-fmt.h"
/*
* Example that will try to overflow the SDP parser.
*/
bool
mutate_gnutls_record_send(ChanneledMessage& msg)
{
SIPFmt sip(msg.data);
/* Only SIP request */
if (not sip.isRequest()) {
return false;
}
/* Skip none SDP Content-Type */
if (not sip.isApplication("sdp")) {
return false;
}
char payload[] = "@";
sip.pushBody(payload, 1);
/* Commit changes! */
sip.swap(msg.data);
return true;
}
/*
* Copyright (C) 2021 Savoir-faire Linux Inc.
*
* Author: Olivier Dion <olivier.dion>@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <cstdlib>
#include "lib/gnutls.h"
#include "lib/sip-fmt.h"
/*
* Example that will try to overflow the SDP parser.
*/
bool
mutate_gnutls_record_send(ChanneledMessage& msg)
{
static size_t body_repeat = 1;
SIPFmt sip(msg.data);
/* Only SIP request */
if (not sip.isRequest()) {
return false;
}
/* Skip none SDP Content-Type */
if (not sip.isApplication("media_control+xml")) {
return false;
}
auto body = sip.getBody();
std::vector<uint8_t> newBody;
newBody.reserve(body_repeat * body.size());
for (size_t i=0; i<body_repeat; ++i) {
for (auto it=body.cbegin(); it!=body.cend(); ++it) {
newBody.emplace_back(*it);
}
}
sip.swapBody(newBody);
body_repeat *= 2;
/* Commit changes! */
sip.swap(msg.data);
return true;
}
/*
* Copyright (C) 2021 Savoir-faire Linux Inc.
*
* Author: Olivier Dion <olivier.dion>@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <cstdlib>
#include "lib/gnutls.h"
#include "lib/sip-fmt.h"
/*
* Insert a HTML payload in a SIP request if no content-type
*/
bool
mutate_gnutls_record_send(ChanneledMessage& msg)
{
SIPFmt sip(msg.data);
if (not sip.isRequest()) {
return false;
}
if (not sip.getField("content-type").empty()) {
return false;
}
char htmlBody[] = "<html><h1>FUZZ</h1></html>\n";
std::vector<uint8_t> body;
body.reserve(array_size(htmlBody));
for (size_t i=0; i<array_size(htmlBody); ++i) {
body.emplace_back(htmlBody[i]);
}
sip.swapBody(body);
sip.setFieldValue("content-type", "text/html");
/* Commit changes! */
sip.swap(msg.data);
return true;
}
/*
* Copyright (C) 2021 Savoir-faire Linux Inc.
*
* Author: Olivier Dion <olivier.dion>@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <cstdlib>
#include "lib/gnutls.h"
#include "lib/sip-fmt.h"
/*
* Example that will try to overflow the SDP parser.
*/