Self-hosted mouse click/keydown counter thingamajig =] (OS X/Wind0ngs lol)
|
2 months ago | |
---|---|---|
ass | 2 months ago | |
bin | 11 months ago | |
release | 2 months ago | |
sauce | 2 months ago | |
.editorconfig | 1 year ago | |
.gitattributes | 3 years ago | |
.gitignore | 11 months ago | |
LICENSE | 3 years ago | |
README.md | 2 months ago |
This is something very similar to WhatPulse, except the sauce is completely open and you can connect this shit to your own SQL serbur. ;];] It's available for le macOS and 64-bit Wind0ngs.
Muy importante: this is just the client side for monitoring keystr0kes/mouse clicks. You can use (almost) any already available graphing tool to visualise that shit.
Also, the zipperin0s I've included in this repo are debug builds, so when shit hits the fan it should make troubleshooting it a bit easier. =]
A MySQL serbur obviously, just make sure the version is 5.5 or highur. One thing you'll definitely need to do if you want to use SSL/TLS connections to MySQL (and you should): make sure the SSL cert used by the server is a trusted one.
Shit was originally made for El Capitan thru Mojave, but now only supports Catalina and up. Also it supports both the x86_64
(64-butt Intel models) and arm64
(fancy-ass Apple Silicon) architectures. The reason for Catalina is that it received an update recent enough that people might still be using it. It's also the first 64-butt only OS, which makes managing libraries a bit easier.
Since it uses keychain bullshit there's no actual ca-certificates
directory by default. The .app
has a bundled certs
dir containing CAs related to LetsEncrypt only (since you're pr0lly using that anyways) as well as cURL's CA bundle (as a convenience), but you can override this location (see Config section for more deetz).
If you're not using LetsEncrypt:
openssl rehash <cert dir>
if your version supports it, if you installed it w/ Homebrew then it's not in your PATH
so use something similar to /opt/homebrew/Cellar/openssl@1.1/1.1.1q/bin/openssl
instead/opt/homebrew/Cellar/openssl@1.1/1.1.1q/bin/c_rehash <cert dir>
instead (although it might generate wrong hashes so verification will still fail, I'm unsure how to generate the proper ones manually lmao)Shit was tested on Wind0ngs 10 and 11 because righteously fuck 8.x (and who uses W7 anymore?).
It seems the MySQL client library checks against the machine's certificate store, so there's no need for a certs
dir like with macOS. =] It does seem to need cURL's CA bundle to properly establish a chain of trust though (or any valid CA bundle prolly, but cURL's is just more convenient).
Just for reference in case you ever need to add a self-signed cert:
Install Certificate
Current User
store but you actually need Local Machine
my dude, so click that shitPlace all certs in the following store
insteadTrusted Root Certification Authoritays
store or Intermediate Certification Authoritays
, depending on what kind of cert it isNext
until it says it completed lolI've included a qt lil' SQL schema, so just import that in your SQL serbur and set up a user for the DB. ez pz
Also, a list of times when the schema was updated since release as a way for you to know if you need to update em schema on your actual DB:
Issa p simple yo:
.app
file in /Applications
or some shitSystem Preferences
> Security & Privacy
> Privacy
tab > Accessibility
on the left > make sure the list on the right contains str0kem.app
(maybe use the +
button to add em) and check that b0x m8.app
bundle, the new (sandboxed) location will be shown in a dialogIf you want it to start at user login and restart when it dies:
First, copy the p00perty list file to the proper directory:
cp ass/com.jemoeder.lief.str0kem.plist.example ~/Library/LaunchAgents/com.jemoeder.lief.str0kem.plist
Then make sure the contents of that file are referring to the proper path. By default it looks for /Applications/str0kem.app/Contents/MacOS/str0kem
so if you didn't move the .app
to /Applications
, adjust that f00kin path. =] It should never address the .app
directly, it always needs the executable "hidden" inside.
And finally:
launchctl load -w ~/Library/LaunchAgents/com.jemoeder.lief.str0kem.plist
Every time the executable rips it'll be restarted by launchd
, which usually happens within a few seconds. To stop this shit just use the above command, except substitute load
for unload
0bv. ;]
Again fairly simple y0, it doesn't even need memey installer bullshit so it's pretty much a portable exe. =]
%LOCALAPPDATA%
due to permissions, it runs as a regular user and never asks for admin/UAC shit)AppData/Roaming
folder, the full location will be shown in a dialogThe config is saved to Roaming AppData so it also works with r0aming profiles. I still recommend putting the .exe
in Local AppData so it doesn't get roamed, since programs should really be kept local imo tbh famalamlmla.
Note: it requires certain .dll
and .pem
files to run properly, which I've embedded into the .exe
and they get extracted when you run that shit. It will put them in the same direct0ry as the .exe
, hence my inclusion of a dir in the .zip
file. ;]
If you want it to start at user login and restart when it dies:
Run
dial0g)taskschd.msc
Task Scheduler (Local)
followed by Import Task
CHANGEME
under General
> Security options
, so change that shit to your own userTriggers
tab and edit the At log on
triggur, edit the CHANGEME
here tooActions
tab and confirm that the path to str0kem.exe
exists (default is a direct0ry under %LOCALAPPDATA%
), also make sure there are 3 DLLs and a PEM file next to the .exe
Wind0ngs will try to start the pr0gram every minute (can't do it m0ar often w/ Task Scheduler lol) as well as at user l0g0n, but it won't run duplicate instances. You could run it as a service but there's no way to run it just for a specific user. ;]
Note: apparently sometimes the extraction of embedded files might fail when str0kem runs through the scheduled task. In that case you could just enable Run with highest privileges
in the task settings. =] But really it should work without that because your own account should have full permissions on its AppData directories, so if there's a permissions error you likely fucked shit up. [=[[=[==[[==[
Since """proper""" JSON doesn't actually allow comments, I'll mention a bit about em config here (although it should be pretty clear imo tbh fams):
{
"main": {
"host": "mysql.example.com",
"port": 3306,
"ssl": true,
"sslverify": true,
"sslcapath": "/Users/toplels/local/etc/certs",
"user": "ayylmao",
"pass": "poopfarts",
"dbname": "str0kem",
"dbtable": "keymouse",
"dbinterval": 300,
"logrotate": 2,
"debug": false
}
}
Muy importante: don't end the last lines in a hash with a comma, that shit rips on wind0ngs kek (technically that's """invalid""" JSON too).
Pretty much half of it is required, exceptions being:
port
: defaults to 3306ssl
: defaults to true, since you're prolly connecting over tEh iNtErWEbSsslverify
: verify SSL certs, defaults to true cuz inb4MITM my d00dsslcapath
: path containing a bunch of hashed Certification Authority certs, defaults to the bundled certs
dir for macOS only and simply NULL
for Wind0ngs (because it doesn't work on there, it requires one CA bundle which is embedded in the exec00table)dbinterval
: how often to connect to the DB, defaults to 300 seclogrotate
: rotate the log file when it gets this big (in megabutts lol), defaults to 2 MBdebug
: log extra shit to logfile, defaults to n0 obvIf you don't wanna use an optional configurable, just leave out the entire line. ;] In some cases it works to pass an empty value but just omit it to be sure.
If the br0gram runs into any problems along the way it'll most likely notify you about it via a dial0g. It also logs some shit to a file in the same dir as the config.
Also, if shit like writing to log fails we obviously cannot log that on disk anywhere, so there are a couple of printf
statements too. You can see these by running the executable directly.
You'll need to call the "hidden" binary directly from a terminal: /Applications/str0kem.app/Contents/MacOS/str0kem
Since cmd
won't wait for GUI/WinMain
applications to finish (i.e. returns to prompt), you gotta use a bogus pipe: "%LOCALAPPDATA%\str0kem\str0kem.exe" | rem
Otherwise any printf
output will be mixed together with the terminal's prompt and shit. =]
If the program receives a termination signal it will (try to) write the current in-memory counters to a file before it actually exits. Next time it starts up it will start from that point so you won't lose hits. For all platforms there's a timer that runs roughly every minute to write that shit as well.
The counter file should be written if the br0gram receives any of these signals: SIGTERM
, SIGINT
, SIGQUIT
, SIGHUP
, SIGUSR1
, SIGUSR2
. macOS seems to be running timers in series so there's no real need to purposely stall/offset the timer for writing the counter file.
As far as I can tell, unloading through Launch Services/launchctl
and using the Quit
option in Activity Manager (i.e. SIGTERM
) both result in the file being properly written. Using Force Quit
will obviously send SIGKILL
and prevents writing. Shutting down y0 Mac goes through Launch Services as well so it should be the same for that. [[=[=[==[[=[==[[==[=[
It doesn't actually generate signals the way Unixy systems do, but instead uses the TerminateProcess
API which might kill the process without notification (thanks Microsoft). Meaning the file might only be written on termination if you run the .exe
from a cmd
and you Ctrl+C
that shit (which does seem to gener8 SIGINT
). In my tests (on W11 at least) it did get written every time when I used taskkill /im str0kem.exe
, so maybe they finally fixed that bullshit. Also, Wind0ngs seems to be running timers in parallel so we do have to purposely stall/offset the timer for writing the counter file. Otherwise both the MySQL insert and this timer might run together, resulting in a counter file with wrong data. As such this particular timer will fire every minute but inside of it there's a wait for at least 200 milliseconds, it will also sleep for an additional 20ms as long as MySQL is inserting.
First off, I've included project files/solution bullshit so you should be able to just open those in your IDE and start editing. They should all contain relative paths regarding sauce/incl00d dirs etc, but to make sure it werks try compiling right away without any modifications. Note that you still have to install the MySQL library first, since str0kem #include
s one of its header files.
Since it was a fucking pain to figure out how to properly link (embedded) shit, I'm gonna be a br0 and explain all that shit right here. =]
You need a few external libraries for that shit, and I'll be assuming you're using Homebrew:
libmysqlclient
: used to be the mysql-connector-c
package, but that's ripped now, so instead the library is found within mysql-client
libzstd
: not really sure where the fuck this comes from but libmysqlclient
seems to need it lel, can prolly be found under /opt/homebrew/Cellar/zstd
(may need to install the zstd
package first doe)libssl
and libcrypto
lel (openssl
package obviously)Note that Homebrew by default installs dylibs for your specific CPU architecture only, so compiling a multi-arch application isn't possible by default. That shit needs some additional steps. In my case I'm on arm64
and I need to download x86_64
libs so I can target both architectures. One thing to check beforehand: you'll want to have the most recent version of the libs for your default architecture. Since we'll be downloading for the other arch straight from Homebrew, that will (most likely) be the latest version and even a slight mismatch between versions could cause issues. Always compare the version you have installed vs. the one Homebrew downloaded.
An example with openssl
:
# Or wherever the fuck the sauce dir is actually located for you ;];];];]
$ cd ~/git/str0kem
# Adjust the arch, OS name and package as needed (you can omit the @version specifier if you want to use the default version, but in openssl's case that would be 3.x while we need 1.x)
# As I mentioned bef0re, for ARM you'd use e.g. 'arm64_monterey' here
$ brew fetch --force --bottle-tag=x86_64_monterey openssl@1.1
# The relevant part from the output is this:
Downloaded to: /Users/muhbrew/Library/Caches/Homebrew/downloads/8e55d6c7baefb1ace7a73413ad6b3bf7e58686352d65ec0c6897733b63a5d146--openssl@1.1--1.1.1q.monterey.bottle.tar.gz
# Gotta untar that shit, but only need any .dylib files (some are not needed for str0kem though)
$ tar xzvf '/Users/muhbrew/Library/Caches/Homebrew/downloads/8e55d6c7baefb1ace7a73413ad6b3bf7e58686352d65ec0c6897733b63a5d146--openssl@1.1--1.1.1q.monterey.bottle.tar.gz' '*.dylib'
x openssl@1.1/1.1.1q/lib/engines-1.1/capi.dylib
x openssl@1.1/1.1.1q/lib/engines-1.1/padlock.dylib
x openssl@1.1/1.1.1q/lib/libcrypto.1.1.dylib
x openssl@1.1/1.1.1q/lib/libcrypto.dylib
x openssl@1.1/1.1.1q/lib/libssl.1.1.dylib
x openssl@1.1/1.1.1q/lib/libssl.dylib
# Prolly useful to create a temporary dir to store all the arch's libs
$ mkdir x86_64
# As mentioned before, we need the numbered files
# Also we only actually need libssl and libcrypto
$ mv openssl@1.1/1.1.1q/lib/lib{crypto,ssl}.1.1.dylib x86_64/
# Remove the extracted dir cuz we no longer need it
$ rm -rf openssl@1.1
# Now do the same for other libs
# Afterwards, the temp dir should contain something like this:
$ ls x86_64
libcrypto.1.1.dylib libmysqlclient.21.dylib libssl.1.1.dylib libzstd.1.5.2.dylib
# Compare with the libs actually used by str0kem
$ ls sauce/mac/lib/
libcrypto.1.1.dylib libmysqlclient.21.dylib libssl.1.1.dylib libzstd.1.5.2.dylib
# Check the file types
$ file x86_64/*
x86_64/libcrypto.1.1.dylib: Mach-O 64-bit dynamically linked shared library x86_64
x86_64/libmysqlclient.21.dylib: Mach-O 64-bit dynamically linked shared library x86_64
x86_64/libssl.1.1.dylib: Mach-O 64-bit dynamically linked shared library x86_64
x86_64/libzstd.1.5.2.dylib: Mach-O 64-bit dynamically linked shared library x86_64
$ file sauce/mac/lib/*
sauce/mac/lib/libcrypto.1.1.dylib: Mach-O 64-bit dynamically linked shared library arm64
sauce/mac/lib/libmysqlclient.21.dylib: Mach-O 64-bit dynamically linked shared library arm64
sauce/mac/lib/libssl.1.1.dylib: Mach-O 64-bit dynamically linked shared library arm64
sauce/mac/lib/libzstd.1.5.2.dylib: Mach-O 64-bit dynamically linked shared library arm64
# Now combine the separate architectures into the same file, then move the new file into the directory used by str0kem
$ for muhlib in libcrypto.1.1.dylib libmysqlclient.21.dylib libssl.1.1.dylib libzstd.1.5.2.dylib; do
$ lipo "sauce/mac/lib/$muhlib" "x86_64/$muhlib" -output "$muhlib" -create && mv -v "$muhlib" sauce/mac/lib/
$ done
# Check the file types again (I cleaned up the output a little to make it more readable lel)
$ file sauce/mac/lib/*
sauce/mac/lib/libcrypto.1.1.dylib: Mach-O universal binary with 2 architectures
sauce/mac/lib/libcrypto.1.1.dylib (for architecture arm64): Mach-O 64-bit dynamically linked shared library arm64
sauce/mac/lib/libcrypto.1.1.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
sauce/mac/lib/libmysqlclient.21.dylib: Mach-O universal binary with 2 architectures
sauce/mac/lib/libmysqlclient.21.dylib (for architecture arm64): Mach-O 64-bit dynamically linked shared library arm64
sauce/mac/lib/libmysqlclient.21.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
sauce/mac/lib/libssl.1.1.dylib: Mach-O universal binary with 2 architectures
sauce/mac/lib/libssl.1.1.dylib (for architecture arm64): Mach-O 64-bit dynamically linked shared library arm64
sauce/mac/lib/libssl.1.1.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
sauce/mac/lib/libzstd.1.5.2.dylib: Mach-O universal binary with 2 architectures
sauce/mac/lib/libzstd.1.5.2.dylib (for architecture arm64): Mach-O 64-bit dynamically linked shared library arm64
sauce/mac/lib/libzstd.1.5.2.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
M A G I C
One thing you'll very likely need to adjust after that is at the top of str0kemAppDelegate.m
and looks something like this:
#include </opt/homebrew/Cellar/mysql-client/8.0.31/include/mysql/mysql.h>
Make sure the path and version here match the library installed on your system.
Then also make sure it links against the .dylib
file of the matching version. If you happen to have the same version of the connector libs as used in the actual c0de, then you should be good to go. If it still n0 werkies or you have a different version, you gotta edit some shit. Most of the steps required to embed libraries are already done, so it should be a simple matter of:
/opt/homebrew/Cellar/mysql-client/8.0.31/lib
(or something similar, obviously)libmysqlclient.xx.dylib
(where xx
is a number, in this case 21
) and libmysqlclient.dylib
(a symlink to the numbered variant)sauce/mac/lib
, overwriting any existing files in the processxx
is different from before, you'll also need to tell Xcode to forget about the old one and embed the new one instead: click str0kem
under Targets
> General
tab > Frameworks, Libraries and Embedded Content
section (set it to Embed & Sign
)Build Phases
tab and scroll down to the Run Script
sectionlibmysqlclient.xx.dylib
you copied earlier, make sure the xx
in the script matches your file's version tooAnd that should d0 it. =]
Note: My custom build script used by Xcode has to re-codesign some libraries because we need to modify the "rpath" pointing to another library inside them. Xcode's own codesigning step happens before this so the resulting application will otherwise "crash" due to an incorrect signature. =] This also means that technically letting Xcode Embed & Sign
libraries is not necessary, but I seem to recall it still whined "hurrr durrrr unsigned library bruh" when building. Anyways, the build script should be able to pick up on your codesigning identity automatically, but if not then just copy the env.sh.example
to env.sh
(next to str0kem.xcodeproj
) and edit the export
line so it uses the proper identity.
Protip: Xcode builds the application within the sauce tree (bin/str0kem.app
) because writing directly to /Applications
usually isn't allowed (also I prefer to keep everything contained within the sauce tree to begin with), but macOS kinda wants you to start br0grams from /Applications
. So how to fix that? Simple, move the bin/str0kem.app
to /Applications
manually and symlink that shit: ln -s /Applications/str0kem.app ~/git/str0kem/bin/str0kem.app
(adjust the second path to match wherever the git tree is 0bv). This puts the symlink in the sauce tree, so when Xc0dd builds shit it follows em to /Applications/str0kem.app
, which (now) has the proper permissions since you moved it there and thus is properly writable. [[==[[=
>my fucking face when trying to figure out where to get the proper downl0ads, THANKS (WH)ORACLE
You need a few external libraries for that shit:
libmysqlclient
So uh, the C connector is nowhere to be found on official sources??÷¿? Their downloads page mentions it's included in the community installer, except it fucking isn't (at least not anym0ar). ;_; So we're just gonna have to pull that shit from the MySQL server:
Windows (x86, 64-bit), ZIP Archive
(i.e. without tests and debug shit)8.0
for 8.0.32
) in Program Files
: C:/Program Files/MySQL/Connector C 8.0
(the C++ connector uses almost the exact same path)include
and lib
in their entirety to the installation dir (you don't need any of the binaries for it to work)C:/Program Files/MySQL/Connector C 8.0/lib/libmysql.dll
to sauce/win/lib
in str0kem's sauce tree, overwriting the existing file in the processlibssl/libcrypto
So uhhhhh, MySQL depends on OpenSSL but it's nowhere to be found either??¿¿??÷÷?/ Apparently it is contained within the C++ connect0r though, so again we have to pull shit manually:
Add...
on the right when it finally opens -- it might also instead present you with a choice for the installation type, in that case pick Custom
MySQL Connectors
> MySQL Connector/C++
until you finally get to choose between x64
and x86
C:/Program Files/MySQL/Connector C++ 8.0
lib64
, which in turn finally contains the DLLs we need: libcrypto-1_1-x64.dll
and libssl-1_1-x64.dll
sauce/win/lib
dir, again overwriting the existing filesThe above steps should also let it link against the .dll
library files of the matching version. Obviously, if some of the versions within the file names changed you'll have to adjust the project to match.
One thing you might need to adjust after all that is at the top of str0kem.cpp
and looks something like this:
#include <C:/Program Files/MySQL/Connector C 8.0/include/mysql.h>
Make sure the path and version here match the library installed on your system.
And that should d0 it. =]
Protip: Visual st00di0 builds the application within the sauce tree (bin/str0kem.exe
) because I prefer to keep everything contained within there, but the scheduled task looks under %LOCALAPPDATA%\str0kem
. So how to fix that? Simple, remove the .exe
from %LOCALAPPDATA%\str0kem
and instead make it a symlink: mklink %LOCALAPPDATA%\str0kem\str0kem.exe %USERPROFILE%/git/str0kem/bin/str0kem.exe
(adjust the second path to match wherever the git tree is 0bv). Unlike l00nixy systems, wind0ngs isn't smart enough to follow the symlink and build an .exe
at the location it points to, it actually overwrites the symlink itself. Which is why we keep the .exe
in its original place and just provide an entry point that's compatible with the scheduled task. Note that you can (and should) still run str0kem using %LOCALAPPDATA%\str0kem\str0kem.exe
, that way it will also unpack its embedded shit in the directory where the symlink is (instead of el git dir).