1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
From: =?utf-8?b?0L3QsNCx?= <nabijaczleweli@nabijaczleweli.xyz>
Date: Mon, 25 Nov 2024 21:46:48 +0100
Subject: Pass password and filename as exec() arguments,
not as popen() strings
Fixes: https://bierbaumer.net/security/rarcrack/ part 3
---
rarcrack.c | 50 +++++++++++++++++++++++++++++++++++++-------------
1 file changed, 37 insertions(+), 13 deletions(-)
diff --git a/rarcrack.c b/rarcrack.c
index 1ee7f4a..4bc3d4c 100644
--- a/rarcrack.c
+++ b/rarcrack.c
@@ -4,6 +4,8 @@
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
+#include <fcntl.h>
+#include <signal.h>
// libxml2 headers
#include <libxml/xmlmemory.h>
@@ -22,12 +24,29 @@ static const char *const TYPE[] = { "rar", "7z", "zip", "" };
// File Types
static const char *const MIME[] = { "application/x-rar;", "application/x-7z-compressed;", "application/zip;", "" };
-// Commnds for each file type
-static const char *const CMD[] = { "unrar t -y -p%s %s 2>&1", "7z t -y -p%s %s 2>&1", "unzip -P%s -t %s 2>&1", "" };
-
// Max password length
#define PWD_LEN 100
+typedef void (*CMD_exec_t)(const char password[PWD_LEN + 1], const char *filename);
+static void CMD_exec_unrar_7z(const char *prog, const char password[PWD_LEN + 1], const char *filename) {
+ char parg[2 + PWD_LEN + 1];
+ strcpy(parg, "-p");
+ strcpy(parg + 2, password);
+ execlp(prog, prog, "t", "-y", parg, filename, (char *)NULL);
+}
+static void CMD_exec_unrar(const char password[PWD_LEN + 1], const char *filename) {
+ CMD_exec_unrar_7z("unrar", password, filename);
+}
+static void CMD_exec_7z(const char password[PWD_LEN + 1], const char *filename) {
+ CMD_exec_unrar_7z("7z", password, filename);
+}
+static void CMD_exec_unzip(const char password[PWD_LEN + 1], const char *filename) {
+ execlp("unzip", "unzip", "-P", password, "-t", filename, (char *)NULL);
+}
+
+// Commnds for each file type
+static const CMD_exec_t CMD[] = { CMD_exec_unrar, CMD_exec_7z, CMD_exec_unzip, NULL };
+
char *getfirstpassword();
void crack_start(unsigned int threads);
@@ -44,7 +63,7 @@ char *statname; //status xml file name filename + ".xml"
xmlDocPtr status;
int finished = 0;
xmlMutexPtr finishedMutex;
-const char *finalcmd; //this depending on arhive file type, it's a command to test file with password
+CMD_exec_t finalcmd; //this depending on arhive file type, it's a command to test file with password
char *getfirstpassword() {
static char ret[2];
@@ -226,17 +245,19 @@ void *crack_thread() {
char *current;
char *ret = NULL;
size_t retlen = 0;
- char *cmd;
FILE *Pipe;
+ int fds[2];
while (1) {
current = nextpass();
- if (asprintf(&cmd, finalcmd, current, filename) == -1) {
- perror("ERROR");
- free(current);
- break;
+ (void) -pipe2(fds, O_CLOEXEC);
+ if (!vfork()) {
+ dup2(fds[1], 1);
+ dup2(fds[1], 2);
+ finalcmd(current, filename);
+ _exit(127);
}
- Pipe = popen(cmd, "r");
- free(cmd);
+ close(fds[1]);
+ Pipe = fdopen(fds[0], "re");
while (getline(&ret, &retlen, Pipe) != -1) {
if (strcasestr(ret, "ok") != NULL) {
strcpy(password_good, current);
@@ -249,7 +270,8 @@ void *crack_thread() {
}
}
- pclose(Pipe);
+ fclose(Pipe);
+
xmlMutexLock(finishedMutex);
counter++;
@@ -268,6 +290,8 @@ void crack_start(unsigned int threads) {
pthread_t th[13];
unsigned int i;
+ signal(SIGCHLD, SIG_IGN);
+
for (i = 0; i < threads; i++) {
(void) pthread_create(&th[i], NULL, crack_thread, NULL);
}
@@ -332,7 +356,7 @@ void init(int argc, char **argv) {
if (archive_type < 0) {
printf("WARNING: invalid parameter --type %s!\n", argv[i]);
- finalcmd = "";
+ finalcmd = NULL;
}
} else {
printf("ERROR: missing parameter for option: --type!\n");
|