Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 129 additions & 0 deletions SPECS/sleuthkit/CVE-2026-40024.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
From a3f96b3bc36a8bb1a00c297f77110d4a6e7dd31b Mon Sep 17 00:00:00 2001
From: Brian Carrier <carrier@sleuthkit.org>
Date: Sat, 28 Feb 2026 16:36:48 -0500
Subject: [PATCH] Clean up any path traversal symbols in export path. Reported
by Mobasi

Upstream Patch reference: https://github.com/sleuthkit/sleuthkit/commit/a3f96b3bc36a8bb1a00c297f77110d4a6e7dd31b.patch

---
tools/autotools/tsk_recover.cpp | 53 ++++++++++++++++++++++++++++-----
1 file changed, 46 insertions(+), 7 deletions(-)

diff --git a/tools/autotools/tsk_recover.cpp b/tools/autotools/tsk_recover.cpp
index 2323545..73ffaa8 100755
--- a/tools/autotools/tsk_recover.cpp
+++ b/tools/autotools/tsk_recover.cpp
@@ -46,6 +46,17 @@ usage()
exit(1);
}

+
+// special characters we do not want to have in the name when writing out.
+#ifdef TSK_WIN32
+#define TSK_IS_SPL_FILE_CHAR(x) \
+ (((x) == 0x3A) || ((x) == 0x5C))
+#else
+#define TSK_IS_SPL_FILE_CHAR(x) \
+ ((x) == 0x2F)
+#endif
+
+
#ifdef TSK_WIN32
#include <windows.h>
#include "shlobj.h"
@@ -136,8 +147,20 @@ uint8_t TskRecover::writeFile(TSK_FS_FILE * a_fs_file, const char *a_path)

// clean up any control characters
for (size_t i = 0; i < ilen; i++) {
- if (TSK_IS_CNTRL(path8[i]))
+ if (TSK_IS_CNTRL(path8[i])) {
path8[i] = '^';
+ }
+
+ if (path8[i] == '/')
+ path8[i] = '\\';
+
+ // make sure there is no \..\ path traversal
+ if (i + 4 < ilen) {
+ if ((path8[i] == '\\') && (path8[i+1] == '.') && (path8[i+2] == '.') && (path8[i+3] == '\\')) {
+ path8[i+1] = '^';
+ path8[i+2] = '^';
+ }
+ }
}

//convert path from utf8 to utf16
@@ -169,6 +192,8 @@ uint8_t TskRecover::writeFile(TSK_FS_FILE * a_fs_file, const char *a_path)
for (size_t i = 0; i < len; i++) {
if (path16full[i] == L'/')
path16full[i] = L'\\';
+
+ // break at path seperator to make that directory
if (((i > 0) && (path16full[i] == L'\\') && (path16full[i - 1] != L'\\'))
|| ((path16full[i] != L'\\') && (i == len - 1))) {
uint8_t
@@ -198,8 +223,10 @@ uint8_t TskRecover::writeFile(TSK_FS_FILE * a_fs_file, const char *a_path)
char name8[FILENAME_MAX];
strncpy(name8, a_fs_file->name->name, FILENAME_MAX);
for (int i = 0; name8[i] != '\0'; i++) {
- if (TSK_IS_CNTRL(name8[i]))
+ //make sure there is no slash, which could lead to path traversal
+ if (TSK_IS_CNTRL(name8[i]) || TSK_IS_SPL_FILE_CHAR(name8[i])) {
name8[i] = '^';
+ }
}

//convert file name from utf8 to utf16
@@ -257,13 +284,23 @@ uint8_t TskRecover::writeFile(TSK_FS_FILE * a_fs_file, const char *a_path)
for (size_t i = 0; i < strlen(fbuf); i++) {
if (TSK_IS_CNTRL(fbuf[i]))
fbuf[i] = '^';
+
+ // make sure there is no /../ path traversal
+ if (i + 4 < strlen(fbuf)) {
+ if ((fbuf[i] == '/') && (fbuf[i+1] == '.') && (fbuf[i+2] == '.') && (fbuf[i+3] == '/')) {
+ fbuf[i+1] = '^';
+ fbuf[i+2] = '^';
+ }
+ }
}

// see if the directory already exists. Create, if not.
+ // and all of the missing layers
if (0 != lstat(fbuf, &statds)) {
size_t
len = strlen(fbuf);
for (size_t i = 0; i < len; i++) {
+ // stop if we are at a path separator to make that folder
if (((i > 0) && (fbuf[i] == '/') && (fbuf[i - 1] != '/'))
|| ((fbuf[i] != '/') && (i == len - 1))) {
uint8_t
@@ -288,17 +325,19 @@ uint8_t TskRecover::writeFile(TSK_FS_FILE * a_fs_file, const char *a_path)
}

if (fbuf[strlen(fbuf) - 1] != '/')
- strncat(fbuf, "/", PATH_MAX - strlen(fbuf));
+ strncat(fbuf, "/", PATH_MAX - strlen(fbuf)-1);

- strncat(fbuf, a_fs_file->name->name, PATH_MAX - strlen(fbuf));
+ int nstart = strlen(fbuf);
+ strncat(fbuf, a_fs_file->name->name, PATH_MAX - strlen(fbuf)-1);

//do name mangling of the file name that was just added
- for (int i = strlen(fbuf)-1; fbuf[i] != '/'; i--) {
- if (TSK_IS_CNTRL(fbuf[i]))
+ for (int i = nstart; fbuf[i] != '\0'; i++) {
+ // need to make sure it doesn't have any slashes in it, which could lead
+ // to path traversal
+ if (TSK_IS_CNTRL(fbuf[i]) || TSK_IS_SPL_FILE_CHAR(fbuf[i]))
fbuf[i] = '^';
}

-
// open the file
if ((hFile = fopen(fbuf, "w+")) == NULL) {
fprintf(stderr, "Error opening file for writing (%s)\n", fbuf);
--
2.43.0

Loading
Loading