Skip to content

Commit

Permalink
Merge pull request #2 from moval0x1/1-enchantments-suggestions
Browse files Browse the repository at this point in the history
1 enchantments suggestions
  • Loading branch information
moval0x1 authored Dec 13, 2024
2 parents 0574142 + 03c40c6 commit 444cf9c
Show file tree
Hide file tree
Showing 24 changed files with 679 additions and 241 deletions.
26 changes: 16 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,21 @@ find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)
# Include headers directory
include_directories(${CMAKE_SOURCE_DIR}/src/headers)

# Include the manifest file
set(MANIFEST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/app.manifest")

# Organize files into specific folders
set(HEADERS
src/headers/mainwindow.h
src/headers/WindowsManagement.h
src/headers/windowsManagement.h
src/headers/util.h
)

set(SOURCES
src/sources/main.cpp
src/sources/mainwindow.cpp
src/sources/WindowsManagement.cpp
src/sources/windowsManagement.cpp
src/sources/util.cpp
)

set(UIS
Expand All @@ -37,31 +42,32 @@ set(CMAKE_AUTOUIC_SEARCH_PATHS
${CMAKE_SOURCE_DIR}/src/ui
)

qt_add_executable(NoDelete
MANUAL_FINALIZATION
# Add executable
add_executable(NoDelete
${HEADERS}
${SOURCES}
${UIS}
${MANIFEST_FILE}
)

if(QT_VERSION_MAJOR EQUAL 6)
qt_finalize_executable(NoDelete)
endif()

# Link Qt libraries
target_link_libraries(NoDelete PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

# Qt for iOS sets MACOSX_BUNDLE_GUI_IDENTIFIER automatically since Qt 6.1.
if(${QT_VERSION} VERSION_LESS 6.1.0)
set(BUNDLE_ID_OPTION MACOSX_BUNDLE_GUI_IDENTIFIER com.example.NoDelete)
endif()
# Set application properties
set_target_properties(NoDelete PROPERTIES
${BUNDLE_ID_OPTION}
MACOSX_BUNDLE_GUI_IDENTIFIER "com.example.NoDelete"
MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}"
MACOSX_BUNDLE TRUE
WIN32_EXECUTABLE TRUE
LINK_FLAGS "/MANIFESTUAC:NO" # Disable automatic manifest to avoid conflicts
)

# Installation rules
include(GNUInstallDirs)
install(TARGETS NoDelete
BUNDLE DESTINATION .
Expand Down
53 changes: 51 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,55 @@ NoDelete is a tool that assists in malware analysis by locking a folder where ma
If you have any suggestions, feel free to contact me.

## Let's work!
![NoDelete-Done](/imgs/NoDelete-Done.png)
### Update Notes 12/2024
- Added `config.ini`
- Added logging for monitored folders
- Added ListView with paths
- Added option to open folders from ListView
- Implemented multi-threading
- Added functionality to restore original folder permissions
- Read from environment variable
- Added ``app.manifest``

After using **NoDelete**, all the files inside a folder cannot be deleted. It allows you to Lock a specific folder used by malware to drop files, and you will be sure that the files will not be deleted after a while. This allows you to investigate each one of them.
### How it looks like now?
Now you can set the folder you would like to lock in a **``config.ini``** file.

### Configuration
* **Directories:** All the directories you want to monitor and lock.
* **LogFile:** Name of the log file (default is in the same path as the binary).

![NoDelete-Config-INI](/imgs/NoDelete-config-ini.png)

When **NoDelete** loads the file, it will convert the environment variables and display them in a user-friendly format.

![NoDelete-Main](/imgs/NoDelete-main.png)

You can also open the directory to inspect the files that the malware wrote there. Just right-click on the line and select **Open Directory**.

![NoDelete-OpenDirectory](/imgs/NoDelete-OpenDirectory.png)

### Before Execution
Before running **NoDelete**, you will have full permissions on the target folder:

![NoDelete-PublicFolder-Before](/imgs/NoDelete-PublicFolder-Before.png)

### After Execution
Once all folders are locked, you will see that only "Everyone" is allowed to perform specific actions:

![NoDelete-PublicFolder-After](/imgs/NoDelete-PublicFolder-After.png)

A log will help you validate if anything went wrong and will also provide details about the success of locking the folders.

![NoDelete-logFile](/imgs/NoDelete-logFile.png)

After using **NoDelete**, files inside the locked folder cannot be deleted. This allows you to lock a folder used by malware to drop files, ensuring the files remain intact for further investigation.

![FakeMalware](/imgs/FakeMalware.png)

You can see all activities recorded in the log file:

![NoDelete-FinalLog](/imgs/NoDelete-FinalLog.png)

## TO DO
- [ ] Save events to **EventViewer**
- [ ] **CLI** option
10 changes: 10 additions & 0 deletions app.manifest
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
12 changes: 12 additions & 0 deletions config.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[Directories]
Dir1=C:\\Users\\Public\\
Dir2=C:\\Windows\\Temp\\
Dir3=C:\\Users\\%USERNAME%\\AppData\\Local\\Temp\\
Dir4=C:\\Users\\%USERNAME%\\AppData\\Roaming\\
Dir5=C:\\Users\\%USERNAME%\\AppData\\Local\\
Dir6=C:\\ProgramData\\
Dir7=C:\\Users\\%USERNAME%\\Documents\\
[LogFile]
Path=file_monitor_log.txt
[Permissions]
Bkp=permissions_backup.txt
Binary file added imgs/FakeMalware.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file removed imgs/NoDelete-Done.png
Binary file not shown.
Binary file added imgs/NoDelete-FinalLog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/NoDelete-OpenDirectory.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/NoDelete-PublicFolder-After.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/NoDelete-PublicFolder-Before.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/NoDelete-config-ini.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/NoDelete-logFile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added imgs/NoDelete-main.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions release.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
@echo off
rem Resolve the current directory where the script is located
set SCRIPT_DIR=%~dp0
set BUILD_DIR=%SCRIPT_DIR%build\Desktop_Qt_6_8_0_MSVC2022_64bit-Release
set QT_BIN_DIR=C:\Qt\6.8.0\msvc2022_64\bin
set TARGET_DIR=C:\qtRelease
set EXECUTABLE_NAME=NoDelete.exe
set CONFIG_NAME=config.ini
set TARGET_EXECUTABLE=%TARGET_DIR%\%EXECUTABLE_NAME%

rem Ensure TARGET_DIR exists
if not exist "%TARGET_DIR%" mkdir "%TARGET_DIR%"

rem Delete all files from TARGET_DIR
echo Cleaning target directory...
del /q "%TARGET_DIR%\*"

rem Copy executable from BUILD_DIR to TARGET_DIR
echo Copying executable...
copy "%BUILD_DIR%\%EXECUTABLE_NAME%" "%TARGET_DIR%"
copy "%BUILD_DIR%\%CONFIG_NAME%" "%TARGET_DIR%"

rem Run windeployqt
echo Running windeployqt...
"%QT_BIN_DIR%\windeployqt.exe" --no-quick-import --no-translations --no-system-d3d-compiler "%TARGET_EXECUTABLE%"

echo Deployment completed.
pause
47 changes: 41 additions & 6 deletions src/headers/WindowsManagement.h
Original file line number Diff line number Diff line change
@@ -1,20 +1,55 @@
#ifndef WINDOWSMANAGEMENT_H
#define WINDOWSMANAGEMENT_H

#include <string> // For std::wstring
#include <QLabel>
#include <windows.h>
#include <aclapi.h>
#include <string>
#include <iostream>
#include <fstream>
#include <filesystem>
#include <vector>
#include <unordered_map>

#include <QLabel>
#include <QListView>
#include <QFileInfo>
#include <QStandardItemModel>
#include <QString>
#include <QSettings>
#include <QProcessEnvironment>
#include <Qpoint>
#include <QMenu>
#include <QProcess>

class WindowsManagement {

class WindowsManagement {
public:
static std::unordered_map<std::wstring, PACL> originalDACLs;

explicit WindowsManagement(std::atomic<bool>& runningFlag);

static std::vector<std::string> LoadDirectoriesFromIni(QLabel* lblMsg, const QString &filePath, const std::string &sectionName);
static void AddItemsToList(QListView* lstDirectories, std::vector<std::string> &lst);
static void ClearAllPermissions(QLabel* lblMsg, const std::wstring& folderPath);
static void ListUsersAndPermissions(QLabel* lblMsg, const std::wstring& folderPath);
static void ModifyPermissions(QLabel* lblMsg, const std::wstring& folderPath, const std::wstring& userName);
static bool ModifyFoldersPermissions(QLabel* lblMsg, const std::wstring& folderPath);

void WatchDirectoryAsync(const std::wstring& directory);
static bool SaveOriginalPermissions(QLabel* lblMsg, const std::wstring& folderPath);
static bool SetNoDeletePermissions(QLabel* lblMsg, const std::wstring& folderPath);
static void RestoreOriginalPermissions(QLabel* lblMsg);

static void ShowContextMenu(QListView* lstDirectories, const QPoint &pos);

std::wstring stringToWString(const std::string& str);

private:
std::atomic<bool>& running;
static QString ExpandEnvironmentVariables(const QString &path);

static DWORD GetSecurityDescriptor(const std::wstring& folderPath, PSECURITY_DESCRIPTOR& pSD, PACL& pOldDACL);
static DWORD SetCustomDACL(const std::wstring& folderPath, PACL pNewDACL = nullptr);

void WatchDirectory(const std::wstring& directory);

};

#endif // WINDOWSMANAGEMENT_H
16 changes: 13 additions & 3 deletions src/headers/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@
#define MAINWINDOW_H

#include <QMainWindow>
#include <QFileDialog>
#include <QtGui>
#include <QStandardItemModel>
#include <QMessageBox>
#include <thread>
#include <atomic>

#include "windowsManagement.h"


QT_BEGIN_NAMESPACE
namespace Ui {
Expand All @@ -16,13 +25,14 @@ class MainWindow : public QMainWindow
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
bool LockFolderCLI();

private slots:
void on_btnOpenFolder_clicked();

void on_btnLockFolder_clicked();
void on_btnRun_clicked();
void on_btnStop_clicked();

private:
Ui::MainWindow *ui;
WindowsManagement* wm;
};
#endif // MAINWINDOW_H
23 changes: 23 additions & 0 deletions src/headers/util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#ifndef UTIL_H
#define UTIL_H

#include <QString>
#include <QLabel>
#include <QCoreApplication>
#include <mutex>

class Util
{
// Global mutex for logging
static std::mutex logMutex;

public:
static void setMessage(QLabel* label, const QString& message, const QString& color);
static std::wstring stringToWString(const std::string &str);
static void LogEvent(const std::wstring& message);
static std::wstring escapeBackslashes(const std::wstring& path);

static inline const QString CONFIG_PATH = "/config.ini";
};

#endif // UTIL_H
Loading

0 comments on commit 444cf9c

Please sign in to comment.