stuff
This commit is contained in:
parent
103011f8f7
commit
b8db080960
11 changed files with 262 additions and 92 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,6 +1,6 @@
|
||||||
# This file is used to ignore files which are generated
|
# This file is used to ignore files which are generated
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
build/
|
||||||
*~
|
*~
|
||||||
*.autosave
|
*.autosave
|
||||||
*.a
|
*.a
|
||||||
|
|
|
@ -26,21 +26,15 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
find_package(Qt5 COMPONENTS Widgets REQUIRED)
|
find_package(Qt5 COMPONENTS Widgets REQUIRED)
|
||||||
find_package(cppzmq REQUIRED)
|
find_package(cppzmq REQUIRED)
|
||||||
|
find_package(nlohmann_json REQUIRED)
|
||||||
|
find_package(SQLite3 REQUIRED)
|
||||||
|
|
||||||
if(ANDROID)
|
|
||||||
add_library(littlesnitch SHARED
|
|
||||||
main.cpp
|
|
||||||
mainwindow.cpp
|
|
||||||
mainwindow.h
|
|
||||||
mainwindow.ui
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
add_executable(littlesnitch
|
add_executable(littlesnitch
|
||||||
main.cpp
|
main.cpp
|
||||||
mainwindow.cpp
|
mainwindow.cpp
|
||||||
mainwindow.h
|
networkthread.cpp
|
||||||
|
session.cpp
|
||||||
mainwindow.ui
|
mainwindow.ui
|
||||||
)
|
)
|
||||||
endif()
|
|
||||||
|
|
||||||
target_link_libraries(littlesnitch PRIVATE Qt5::Widgets cppzmq)
|
target_link_libraries(littlesnitch PRIVATE Qt5::Widgets cppzmq sqlite3)
|
||||||
|
|
|
@ -43,44 +43,3 @@ MainWindow::~MainWindow()
|
||||||
void MainWindow::httpMessage(HTTPData data) {
|
void MainWindow::httpMessage(HTTPData data) {
|
||||||
qDebug() << data.index;
|
qDebug() << data.index;
|
||||||
}
|
}
|
||||||
|
|
||||||
Worker::Worker() { // Constructor
|
|
||||||
}
|
|
||||||
|
|
||||||
Worker::~Worker() { // Destructor
|
|
||||||
}
|
|
||||||
|
|
||||||
void Worker::process() {
|
|
||||||
qDebug("thread started");
|
|
||||||
zmq::context_t ctx(1);
|
|
||||||
zmq::socket_t sock(ctx, zmq::socket_type::pair);
|
|
||||||
try {
|
|
||||||
sock.bind("tcp://127.0.0.1:12345");
|
|
||||||
} catch (zmq::error_t err) {
|
|
||||||
qDebug() << "failed binding socket" << err.what();
|
|
||||||
emit error(err.what());
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
qDebug("bound socket");
|
|
||||||
|
|
||||||
while(true) {
|
|
||||||
sock.send(zmq::str_buffer("littlesnitch_init"), zmq::send_flags::dontwait);
|
|
||||||
zmq::message_t msg;
|
|
||||||
const auto ret = sock.recv(msg, zmq::recv_flags::dontwait);
|
|
||||||
if(ret) {
|
|
||||||
qDebug() << "got message: " << msg.to_string().c_str();
|
|
||||||
if(msg.to_string() == "mitmaddon") {
|
|
||||||
qDebug("connected");
|
|
||||||
while(true) {
|
|
||||||
const auto ret = sock.recv(msg, zmq::recv_flags::dontwait);
|
|
||||||
if(ret) {
|
|
||||||
qDebug() << msg.to_string().c_str();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
qDebug("not connected");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
16
mainwindow.h
16
mainwindow.h
|
@ -3,6 +3,8 @@
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <zmq.hpp>
|
#include <zmq.hpp>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
namespace Ui { class MainWindow; }
|
namespace Ui { class MainWindow; }
|
||||||
|
@ -22,20 +24,6 @@ public:
|
||||||
std::string response_content;
|
std::string response_content;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Worker : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
Worker();
|
|
||||||
~Worker();
|
|
||||||
public slots:
|
|
||||||
void process();
|
|
||||||
signals:
|
|
||||||
void finished();
|
|
||||||
void error(QString err);
|
|
||||||
void httpMessage(HTTPData);
|
|
||||||
private:
|
|
||||||
// add your variables here
|
|
||||||
};
|
|
||||||
|
|
||||||
class MainWindow : public QMainWindow
|
class MainWindow : public QMainWindow
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0" colspan="2">
|
<item row="1" column="0" colspan="2">
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
<widget class="QWidget" name="tabWidgetPage1" native="true">
|
<widget class="QWidget" name="tabWidgetPage1">
|
||||||
<attribute name="title">
|
<attribute name="title">
|
||||||
<string/>
|
<string/>
|
||||||
</attribute>
|
</attribute>
|
||||||
|
@ -86,11 +86,46 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>800</width>
|
<width>800</width>
|
||||||
<height>20</height>
|
<height>22</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<widget class="QMenu" name="menuFile">
|
||||||
|
<property name="title">
|
||||||
|
<string>File</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionNew_Session"/>
|
||||||
|
<addaction name="actionOpen_Session"/>
|
||||||
|
</widget>
|
||||||
|
<widget class="QMenu" name="menuSettings">
|
||||||
|
<property name="title">
|
||||||
|
<string>Settings</string>
|
||||||
|
</property>
|
||||||
|
<addaction name="actionSettings"/>
|
||||||
|
</widget>
|
||||||
|
<addaction name="menuFile"/>
|
||||||
|
<addaction name="menuSettings"/>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QStatusBar" name="statusbar"/>
|
<widget class="QStatusBar" name="statusbar"/>
|
||||||
|
<action name="actionOpen">
|
||||||
|
<property name="text">
|
||||||
|
<string>New Session</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionNew_Session">
|
||||||
|
<property name="text">
|
||||||
|
<string>New Session</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionOpen_Session">
|
||||||
|
<property name="text">
|
||||||
|
<string>Open Session</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
|
<action name="actionSettings">
|
||||||
|
<property name="text">
|
||||||
|
<string>Settings</string>
|
||||||
|
</property>
|
||||||
|
</action>
|
||||||
</widget>
|
</widget>
|
||||||
<resources/>
|
<resources/>
|
||||||
<connections/>
|
<connections/>
|
||||||
|
|
|
@ -5,28 +5,75 @@ import threading
|
||||||
from queue import Queue
|
from queue import Queue
|
||||||
import time
|
import time
|
||||||
import zmq
|
import zmq
|
||||||
|
import json
|
||||||
|
|
||||||
|
NO_MSG {"msg": None}
|
||||||
|
INIT_MSG = {"msg": "init"}
|
||||||
|
ACK_MSG = {"msg": "ack"}
|
||||||
|
PING_MSG = {"msg": "ping"}
|
||||||
|
PONG_MSG = {"msg": "pong"}
|
||||||
|
|
||||||
|
def convert_to_strings(obj):
|
||||||
|
if isinstance(obj, dict):
|
||||||
|
return {convert_to_strings(key): convert_to_strings(value)
|
||||||
|
for key, value in obj.items()}
|
||||||
|
elif isinstance(obj, list) or isinstance(obj, tuple):
|
||||||
|
return [convert_to_strings(element) for element in obj]
|
||||||
|
elif isinstance(obj, bytes):
|
||||||
|
return str(obj)[2:-1]
|
||||||
|
return obj
|
||||||
|
|
||||||
|
def get_msg(socket):
|
||||||
|
|
||||||
|
msg = socket.recv()
|
||||||
|
try:
|
||||||
|
if msg:
|
||||||
|
return json.loads(msg)
|
||||||
|
except json.JSONDecodeError:
|
||||||
|
print("malformed message received '{msg}'")
|
||||||
|
|
||||||
|
return NO_MSG
|
||||||
|
|
||||||
|
|
||||||
|
def send_msg(msg, socket):
|
||||||
|
a = convert_to_strings(msg)
|
||||||
|
socket.send(str.encode(json.dumps(a)))
|
||||||
|
|
||||||
def networking(q):
|
def networking(q):
|
||||||
print("starting thread")
|
print("starting thread")
|
||||||
|
|
||||||
context = zmq.Context()
|
context = zmq.Context()
|
||||||
|
connected = False
|
||||||
|
while not connected:
|
||||||
socket = context.socket(zmq.PAIR)
|
socket = context.socket(zmq.PAIR)
|
||||||
socket.connect("tcp://127.0.0.1:12345")
|
socket.connect("tcp://127.0.0.1:12345")
|
||||||
|
msg = get_msg(socket)
|
||||||
|
if msg["msg"] == "init":
|
||||||
|
send_msg(ACK_MSG, socket)
|
||||||
|
connected = True
|
||||||
|
|
||||||
while True:
|
timer = time.monotonic()
|
||||||
print("try recv")
|
while connected:
|
||||||
message = socket.recv()
|
if timer - time.monotonic() >= 5:
|
||||||
if message == b"littlesnitch_init":
|
timer = time.monotonic()
|
||||||
print("connected")
|
send_msg(PING_MSG,socket)
|
||||||
socket.send(b"mitmaddon")
|
msg = get_msg(socket)
|
||||||
while True:
|
if msg["msg"] != "pong":
|
||||||
a = q.get()
|
connected = False
|
||||||
print(f"got {a}")
|
|
||||||
|
msg = get_msg(socket)
|
||||||
|
if msg['msg'] == "ping":
|
||||||
|
send_msg(PONG_MSG, socket)
|
||||||
|
timer = time.monotonic()
|
||||||
|
|
||||||
|
a = q.get(block=False)
|
||||||
if a:
|
if a:
|
||||||
socket.send(str.encode(a))
|
msg = get_msg(socket)
|
||||||
|
if msg["msg"] == "ack":
|
||||||
q.task_done()
|
q.task_done()
|
||||||
|
timer = time.monotonic()
|
||||||
else:
|
else:
|
||||||
raise ValueError("init failed")
|
connected = False
|
||||||
|
|
||||||
class Counter:
|
class Counter:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -36,13 +83,11 @@ class Counter:
|
||||||
self.q.join()
|
self.q.join()
|
||||||
|
|
||||||
def request(self, flow):
|
def request(self, flow):
|
||||||
data = flow.request.data
|
self.q.put(flow.get_state())
|
||||||
self.q.put(f"{flow.id},REQ,{data.method},{data.scheme},{data.host},{data.port},{data.path},{data.http_version},{data.headers}")
|
|
||||||
self.q.join()
|
self.q.join()
|
||||||
|
|
||||||
def response(self, flow):
|
def response(self, flow):
|
||||||
data = flow.response.data
|
self.q.put(flow.get_state())
|
||||||
self.q.put(f"{flow.id},RES,{data.status_code},{data.http_version},{data.reason},{data.headers},{data.content},{data.timestamp_start},{data.timestamp_end}")
|
|
||||||
self.q.join()
|
self.q.join()
|
||||||
|
|
||||||
|
|
||||||
|
|
39
networkthread.cpp
Normal file
39
networkthread.cpp
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#include "networkthread.h"
|
||||||
|
|
||||||
|
NetworkThread::NetworkThread(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkThread::process() {
|
||||||
|
zmq::context_t ctx(1);
|
||||||
|
zmq::socket_t sock(ctx, zmq::socket_type::pair);
|
||||||
|
|
||||||
|
try {
|
||||||
|
sock.bind("tcp://127.0.0.1:12345");
|
||||||
|
} catch (zmq::error_t err) {
|
||||||
|
qDebug() << "failed binding socket" << err.what();
|
||||||
|
emit error(err.what());
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
while(true){
|
||||||
|
bool connected = false;
|
||||||
|
while(!connected) {
|
||||||
|
sock.send(zmq::str_buffer("{'type': 'init'}"), zmq::send_flags::dontwait);
|
||||||
|
zmq::message_t msg;
|
||||||
|
const auto ret = sock.recv(msg, zmq::recv_flags::dontwait);
|
||||||
|
if(ret) {
|
||||||
|
if(msg.to_string() == "{'type': 'ack'}") {
|
||||||
|
connected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(connected) {
|
||||||
|
const auto ret = sock.recv(msg, zmq::recv_flags::dontwait);
|
||||||
|
if(ret) {
|
||||||
|
qDebug() << msg.to_string().c_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
networkthread.h
Normal file
18
networkthread.h
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class NetworkThread : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit NetworkThread(QObject *parent = nullptr);
|
||||||
|
public slots:
|
||||||
|
void process();
|
||||||
|
signals:
|
||||||
|
void finished();
|
||||||
|
void error(QString err);
|
||||||
|
void httpMessage(HTTPData);
|
||||||
|
private:
|
||||||
|
// add your variables here
|
||||||
|
};
|
31
session.cpp
Normal file
31
session.cpp
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#include "session.h"
|
||||||
|
|
||||||
|
Session::Session(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Session::~Session() {
|
||||||
|
unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Session::load(std::filesystem::path path)
|
||||||
|
{
|
||||||
|
if(db) {
|
||||||
|
unload();
|
||||||
|
}
|
||||||
|
auto rc = sqlite3_open(path.c_str(), &db);
|
||||||
|
if(rc) {
|
||||||
|
qDebug("cannot open database");
|
||||||
|
qDebug(sqlite3_errmsg(db));
|
||||||
|
unload();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Session::unload() {
|
||||||
|
if(db) {
|
||||||
|
sqlite3_close(db);
|
||||||
|
}
|
||||||
|
}
|
53
session.h
Normal file
53
session.h
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <sqlite3.h>
|
||||||
|
|
||||||
|
|
||||||
|
// static int callback(void *NotUsed, int argc, char **argv, char **azColName){
|
||||||
|
// int i;
|
||||||
|
// for(i=0; i<argc; i++){
|
||||||
|
// printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
|
||||||
|
// }
|
||||||
|
// printf("\n");
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// int main(int argc, char **argv){
|
||||||
|
// sqlite3 *db;
|
||||||
|
// char *zErrMsg = 0;
|
||||||
|
// int rc;
|
||||||
|
//
|
||||||
|
// if( argc!=3 ){
|
||||||
|
// fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
|
||||||
|
// return(1);
|
||||||
|
// }
|
||||||
|
// rc = sqlite3_open(argv[1], &db);
|
||||||
|
// if( rc ){
|
||||||
|
// fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
|
||||||
|
// sqlite3_close(db);
|
||||||
|
// return(1);
|
||||||
|
// }
|
||||||
|
// rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg);
|
||||||
|
// if( rc!=SQLITE_OK ){
|
||||||
|
// fprintf(stderr, "SQL error: %s\n", zErrMsg);
|
||||||
|
// sqlite3_free(zErrMsg);
|
||||||
|
// }
|
||||||
|
// sqlite3_close(db);
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
class Session : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
sqlite3* db;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit Session(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
|
||||||
|
};
|
||||||
|
|
8
test.sh
Executable file
8
test.sh
Executable file
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
mitmdump -p 8080 -s mitmaddon/littlesnitch.py &
|
||||||
|
./build/littlesnitch &
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
curl -x http://localhost:8080 -k https://yolo.jetzt
|
||||||
|
|
Loading…
Reference in a new issue