Linux Appimage (#85)
* updates to try to make appimage work * Add notes on compatibility * add wayland note * minor change to better encode the screenshot commands * add publish for linux artifactmain
|
@ -27,7 +27,8 @@ jobs:
|
||||||
needs: [store-sha8]
|
needs: [store-sha8]
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-latest]
|
os: [macos-latest, ubuntu-16.04]
|
||||||
|
qt-version: ['5.15.2']
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
@ -39,6 +40,43 @@ jobs:
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
|
|
||||||
|
- name: Cache Qt
|
||||||
|
if: matrix.os == 'ubuntu-16.04' # We might want to do this for both mac and linux
|
||||||
|
id: cache-qt
|
||||||
|
uses: actions/cache@v1
|
||||||
|
with:
|
||||||
|
path: ../Qt
|
||||||
|
key: ${{ runner.os }}-QtCache-${{ matrix.qt-version }}
|
||||||
|
|
||||||
|
- name: Install Qt on Linux # we can also use this for macs
|
||||||
|
if: matrix.os == 'ubuntu-16.04'
|
||||||
|
uses: jurplel/install-qt-action@v2
|
||||||
|
with:
|
||||||
|
version: ${{ matrix.qt-version }}
|
||||||
|
cached: ${{ steps.cache-qt.outputs.cache-hit }}
|
||||||
|
|
||||||
|
- name: Build Pr (Linux)
|
||||||
|
if: matrix.os == 'ubuntu-16.04' && !contains(github.ref, 'tags/v') && !contains(github.ref, 'refs/heads/master') && !contains(github.ref, 'refs/heads/release-')
|
||||||
|
run: |
|
||||||
|
echo "Building!"
|
||||||
|
sudo apt install libxcb-keysyms1-dev desktop-file-utils libxcb-icccm4 libxcb-image0 libxcb-util1 \
|
||||||
|
libxcb-render-util0 libxcb-xinerama0 libxcb-composite0 libxcb-cursor0 libxcb-damage0 \
|
||||||
|
libxcb-dpms0 libxcb-dri2-0 libxcb-dri3-0 libxcb-ewmh2 libxcb-glx0 libxcb-present0 \
|
||||||
|
libxcb-randr0 libxcb-record0 libxcb-render0 libxcb-res0 libxcb-screensaver0 \
|
||||||
|
libxcb-shape0 libxcb-shm0 libxcb-sync1
|
||||||
|
qmake PREFIX=/usr -config release
|
||||||
|
make -j2
|
||||||
|
|
||||||
|
# create app image
|
||||||
|
make INSTALL_ROOT=appdir -j2 install ; find appdir/
|
||||||
|
wget -c -nv "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage"
|
||||||
|
chmod a+x linuxdeployqt-continuous-x86_64.AppImage
|
||||||
|
export VERSION=${{ needs.store-sha8.outputs.sha8 }}
|
||||||
|
./linuxdeployqt-continuous-x86_64.AppImage appdir/usr/share/applications/*.desktop -appimage -verbose=2
|
||||||
|
mkdir -p dist
|
||||||
|
# file should be named ashirt-${{ needs.store-sha8.outputs.sha8 }}-x86_64.AppImage
|
||||||
|
mv ashirt*.AppImage dist/
|
||||||
|
|
||||||
- name: Build PR (mac)
|
- name: Build PR (mac)
|
||||||
if: |
|
if: |
|
||||||
matrix.os == 'macos-latest' &&
|
matrix.os == 'macos-latest' &&
|
||||||
|
@ -52,7 +90,7 @@ jobs:
|
||||||
qmake -config release
|
qmake -config release
|
||||||
make
|
make
|
||||||
macdeployqt ashirt.app -dmg
|
macdeployqt ashirt.app -dmg
|
||||||
mkdir dist
|
mkdir -p dist
|
||||||
cp ashirt.dmg dist/ashirt.dmg
|
cp ashirt.dmg dist/ashirt.dmg
|
||||||
cp LICENSE dist/LICENSE
|
cp LICENSE dist/LICENSE
|
||||||
cp README.md dist/README.md
|
cp README.md dist/README.md
|
||||||
|
@ -77,7 +115,7 @@ jobs:
|
||||||
qmake -config release
|
qmake -config release
|
||||||
make
|
make
|
||||||
macdeployqt ashirt.app -dmg -always-overwrite -sign-for-notarization="John Kennedy"
|
macdeployqt ashirt.app -dmg -always-overwrite -sign-for-notarization="John Kennedy"
|
||||||
mkdir dist
|
mkdir -p dist
|
||||||
cp ashirt.dmg dist/ashirt.dmg
|
cp ashirt.dmg dist/ashirt.dmg
|
||||||
cp LICENSE dist/LICENSE
|
cp LICENSE dist/LICENSE
|
||||||
cp README.md dist/README.md
|
cp README.md dist/README.md
|
||||||
|
@ -126,7 +164,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
platform: [darwin]
|
platform: [darwin, linux]
|
||||||
steps:
|
steps:
|
||||||
- name: Set Version
|
- name: Set Version
|
||||||
run: echo "version=$(echo ${{ github.ref }} | cut -d'/' -f3 | cut -c2-)" >> $GITHUB_ENV
|
run: echo "version=$(echo ${{ github.ref }} | cut -d'/' -f3 | cut -c2-)" >> $GITHUB_ENV
|
||||||
|
|
42
README.md
|
@ -18,6 +18,39 @@ This application allows users to connect to a remote ASHIRT backend and create a
|
||||||
|
|
||||||
Official releases for Mac and Linux will be provided via the releases tab in GitHub along with source code for users to build themselves if desired.
|
Official releases for Mac and Linux will be provided via the releases tab in GitHub along with source code for users to build themselves if desired.
|
||||||
|
|
||||||
|
### Installing for Linux
|
||||||
|
|
||||||
|
The official Linux release is delivered as an AppImage. Certain systems may require specialized information. For most distributions, "installation" is easy: simply set the execute flag on the AppImage, then run the application either in a terminal, or via the UI.
|
||||||
|
|
||||||
|
#### Support Matrix
|
||||||
|
|
||||||
|
| Distribution | Support Status | Notes |
|
||||||
|
| -------------------------- | ----------------- | ----------------------------------------------------------------- |
|
||||||
|
| Kali (xfce) | Supported¹ | Status is as of March, 2021 |
|
||||||
|
| Ubuntu 20.04 (Gnome) | Supported¹ | The operations menu does not update properly |
|
||||||
|
| Fedora 33 (Gnome) | Partial Support¹² | Key capture may not work properly |
|
||||||
|
| KDE Neon | Supported¹ | Status as of January 2021 |
|
||||||
|
| Linux Mint 20.1 (Cinnamon) | Supported¹ | |
|
||||||
|
| Linux Mint 20.1 (Mate) | Partial Support¹ | An alternate screenshotting tool is needed. e.g. gnome-screenshot |
|
||||||
|
|
||||||
|
¹ The application icon does not display properly
|
||||||
|
|
||||||
|
² Pure Gnome installations require a taskbar implementation, which is absent on newer versions of gnome. This can be solved by installing gnome extensions. See the list below of compatible Gnome Extensions
|
||||||
|
|
||||||
|
Note that, due to Wayland simply operating differently, global hotkeys are not supported on those platforms.
|
||||||
|
|
||||||
|
##### Valid Gnome Extensions
|
||||||
|
|
||||||
|
Various gnome extensions work. The below list is a subset. Before using one of these, check that the
|
||||||
|
gnome version they target is the same as the version you are using. Version mismatch could be buggy,
|
||||||
|
or just not work at all
|
||||||
|
|
||||||
|
| Extension Name | Notes |
|
||||||
|
| ---------------------------------------------------------------------------------------- | ----- |
|
||||||
|
| [Tray Icons](https://extensions.gnome.org/extension/1503/tray-icons/) | |
|
||||||
|
| [Tray Icons: Reloaded](https://extensions.gnome.org/extension/2890/tray-icons-reloaded/) | |
|
||||||
|
| [TopIcons Plus](https://extensions.gnome.org/extension/1031/topicons/) | |
|
||||||
|
|
||||||
## Non-tray OSes
|
## Non-tray OSes
|
||||||
|
|
||||||
Current Status: Non-functional
|
Current Status: Non-functional
|
||||||
|
@ -53,11 +86,14 @@ Theoretically, any application that satisfies this requirement will work. For Ma
|
||||||
This tool will replace the above filename with `%file` as noted below:
|
This tool will replace the above filename with `%file` as noted below:
|
||||||
|
|
||||||
| OS/DE/App | Capture Window | Capture Area | Notes |
|
| OS/DE/App | Capture Window | Capture Area | Notes |
|
||||||
| ----------- | ---------------------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ---------------- | --------------------------------- | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| Linux/Gnome | gnome-screenshot -w -f %file | gnome-screenshot -a -f %file | Capture window captures the focused window, rather than allowing a selection; adding the `--delay` flag can help mitigate choosing the wrong window |
|
| Linux/Gnome | `gnome-screenshot -w -f %file` | `gnome-screenshot -a -f %file` | Capture window captures the focused window, rather than allowing a selection; adding the `--delay` flag can help mitigate choosing the wrong window |
|
||||||
| MacOS X | screencapture -w %file | screencapture -s %file | |
|
| Linux/Xfce4 | `xfce4-screenshooter -w -s %file` | `xfce4-screenshooter -r -s %file` | Capture window captures the focused window, rather than allowing a selection; adding the `--delay` flag can help mitigate choosing the wrong window |
|
||||||
|
| Linux/KDE Plasma | `spectacle -a -bno %file` | `spectacle -r -bno %file` | Capture window captures the focused window, rather than allowing a selection; adding the `--delay` flag can help mitigate choosing the wrong window |
|
||||||
|
| MacOS X | `screencapture -w %file` | `screencapture -s %file` | |
|
||||||
|
|
||||||
Note: this application expects a _single, basic command_. While piping output to another command _may_ work, it is not guaranteed. Likewise, providing multiple commands on the same "line" _may_ work, but is also not guaranteed. Officially, both of these techniques are unsupported.
|
Note: this application expects a _single, basic command_. While piping output to another command _may_ work, it is not guaranteed. Likewise, providing multiple commands on the same "line" _may_ work, but is also not guaranteed. Officially, both of these techniques are unsupported.
|
||||||
|
Note 2: Mate-screenshot is unsupported, as it does not appear possible to specify where to write the file without opening up a GUI window
|
||||||
|
|
||||||
### Shortcuts
|
### Shortcuts
|
||||||
|
|
||||||
|
|
34
ashirt.pro
|
@ -1,8 +1,7 @@
|
||||||
QT += core gui network sql
|
QT += core gui network sql widgets
|
||||||
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
|
||||||
|
|
||||||
CONFIG += c++11
|
CONFIG += c++11
|
||||||
|
TEMPLATE = app
|
||||||
|
|
||||||
# The following define makes your compiler emit warnings if you use
|
# The following define makes your compiler emit warnings if you use
|
||||||
# any Qt feature that has been marked deprecated (the exact warnings
|
# any Qt feature that has been marked deprecated (the exact warnings
|
||||||
|
@ -144,15 +143,36 @@ macx {
|
||||||
ICON = icons/ashirt.icns
|
ICON = icons/ashirt.icns
|
||||||
QMAKE_TARGET_BUNDLE_PREFIX = com.theparanoids
|
QMAKE_TARGET_BUNDLE_PREFIX = com.theparanoids
|
||||||
}
|
}
|
||||||
|
unix {
|
||||||
|
isEmpty(PREFIX) {
|
||||||
|
PREFIX = /usr
|
||||||
|
}
|
||||||
|
|
||||||
|
isEmpty(BINDIR) {
|
||||||
|
BINDIR = $$PREFIX/bin
|
||||||
|
}
|
||||||
|
|
||||||
|
isEmpty(DATADIR) {
|
||||||
|
DATADIR = $$PREFIX/share
|
||||||
|
}
|
||||||
|
message("INSTROOT: |$$INSTROOT|")
|
||||||
|
message("PREFIX: |$$PREFIX|")
|
||||||
|
|
||||||
|
INSTALLS += target desktop icons
|
||||||
|
target.path = $$BINDIR
|
||||||
|
|
||||||
|
# Create appimage structure
|
||||||
|
desktop.path = $$DATADIR/applications
|
||||||
|
desktop.files += linux/ashirt.desktop
|
||||||
|
icons.path = $$DATADIR/icons/hicolor
|
||||||
|
icons.files += linux/icons/*
|
||||||
|
}
|
||||||
|
|
||||||
# Default rules for deployment.
|
# Default rules for deployment.
|
||||||
qnx: target.path = /tmp/$${TARGET}/bin
|
qnx: target.path = /tmp/$${TARGET}/bin
|
||||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
# else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||||
!isEmpty(target.path): INSTALLS += target
|
!isEmpty(target.path): INSTALLS += target
|
||||||
|
|
||||||
DISTFILES += \
|
|
||||||
bin/update_migration_resource.py
|
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
res_migrations.qrc \
|
res_migrations.qrc \
|
||||||
res_icons.qrc
|
res_icons.qrc
|
||||||
|
|
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1,8 @@
|
||||||
|
[Desktop Entry]
|
||||||
|
Name=ashirt
|
||||||
|
Comment=Collect and add evidence to remote AShirt Instances
|
||||||
|
Terminal=false
|
||||||
|
Categories=Qt;Development;
|
||||||
|
Type=Application
|
||||||
|
Icon=ashirt
|
||||||
|
Exec=ashirt
|
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 322 B |
After Width: | Height: | Size: 419 B |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 529 B |
After Width: | Height: | Size: 797 B |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 1015 B |
After Width: | Height: | Size: 1.6 KiB |
|
@ -3,5 +3,6 @@
|
||||||
<file>icons/shirt-dark.svg</file>
|
<file>icons/shirt-dark.svg</file>
|
||||||
<file>icons/shirt-light.svg</file>
|
<file>icons/shirt-light.svg</file>
|
||||||
<file>icons/shirt-red.svg</file>
|
<file>icons/shirt-red.svg</file>
|
||||||
|
<file>icons/windowIcon.png</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|
|
@ -20,6 +20,8 @@ void handleCLI(std::vector<std::string> args);
|
||||||
#include "exceptions/fileerror.h"
|
#include "exceptions/fileerror.h"
|
||||||
#include "traymanager.h"
|
#include "traymanager.h"
|
||||||
|
|
||||||
|
QIcon getWindowIcon();
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
Q_INIT_RESOURCE(res_icons);
|
Q_INIT_RESOURCE(res_icons);
|
||||||
Q_INIT_RESOURCE(res_migrations);
|
Q_INIT_RESOURCE(res_migrations);
|
||||||
|
@ -67,6 +69,7 @@ int main(int argc, char* argv[]) {
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
qRegisterMetaType<model::Tag>();
|
qRegisterMetaType<model::Tag>();
|
||||||
|
|
||||||
|
app.setWindowIcon(getWindowIcon());
|
||||||
if (!QSystemTrayIcon::isSystemTrayAvailable()) {
|
if (!QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||||
handleCLI(std::vector<std::string>(argv, argv + argc));
|
handleCLI(std::vector<std::string>(argv, argv + argc));
|
||||||
}
|
}
|
||||||
|
@ -89,6 +92,10 @@ int main(int argc, char* argv[]) {
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QIcon getWindowIcon() {
|
||||||
|
return QIcon(":icons/windowIcon.png");
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|