Skip to content

Commit

Permalink
file overwrite
Browse files Browse the repository at this point in the history
  • Loading branch information
asdfugil committed Jan 3, 2024
1 parent 5540f1e commit dd9f82c
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 3 deletions.
3 changes: 2 additions & 1 deletion include/libjailbreak/libjailbreak.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ enum {
JBD_CMD_GET_PINFO_ROOTDEV,
JBD_CMD_DEPLOY_BOOTSTRAP,
JBD_CMD_OBLITERATE_JAILBREAK,
JBD_CMD_REBOOT_USERSPACE
JBD_CMD_REBOOT_USERSPACE,
JBD_CMD_OVERWRITE_FILE_WITH_CONTENT,
};

int jailbreak_get_bmhash(char* hash);
Expand Down
1 change: 1 addition & 0 deletions include/payload/payload.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ void obliterate(xpc_object_t xrequest, xpc_object_t xreply, struct paleinfo* pin
int print_jailbreakd_reply(xpc_object_t xreply);
int obliterate_main(int argc, char* argv[]);
int remove_bogus_var_jb(void);
void overwrite_file(xpc_object_t xrequest, xpc_object_t xreply, struct paleinfo* pinfo);

enum {
/* only for sysstatuscheck and prelaunchd stage! */
Expand Down
4 changes: 4 additions & 0 deletions src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ RAMDISK_SIZE = 8m
CFLAGS += -DASAN=1
endif

ifeq ($(DEV_BUILD),1)
CFLAGS += -DDEV_BUILD=1
endif

.PHONY: all clean $(patsubst %, %-all, $(SUBDIRS)) $(patsubst %, %-clean, $(SUBDIRS)) libjailbreak

export CC STRIP DSYMUTIL CFLAGS LDID
Expand Down
7 changes: 5 additions & 2 deletions src/payload/jailbreakd/bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ void* write_log(void* arg) {
void bootstrap(xpc_object_t xrequest, xpc_object_t xreply, struct paleinfo* pinfo) {
const char* password = xpc_dictionary_get_string(xrequest, "password");
const char* path = xpc_dictionary_get_string(xrequest, "path");
const char* bootstrapper_name = xpc_dictionary_get_string(xrequest, "bootstrapper-name");
const char* bootstrapper_version = xpc_dictionary_get_string(xrequest, "bootstrapper-version");

bool no_password = xpc_dictionary_get_bool(xrequest, "no-password");

if (pinfo->flags & palerain_option_force_revert) {
Expand Down Expand Up @@ -789,8 +792,8 @@ void bootstrap(xpc_object_t xrequest, xpc_object_t xreply, struct paleinfo* pinf
}
lseek(installed_fd, 0, SEEK_END);

dprintf(installed_fd, "Bootstrapper-Name=p1ctl\n");
dprintf(installed_fd, "Bootstrapper-Version=3.0\n");
dprintf(installed_fd, "Bootstrapper-Name=%s\n", bootstrapper_name ? bootstrapper_name : "Unknown");
dprintf(installed_fd, "Bootstrapper-Version=%s\n", bootstrapper_version ? bootstrapper_version : "Unknown");
close(installed_fd);

xpc_object_t msg;
Expand Down
13 changes: 13 additions & 0 deletions src/payload/jailbreakd/handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,19 @@ void palera1nd_handler(xpc_object_t peer, xpc_object_t request, struct paleinfo*
}
break;
}
case JBD_CMD_OVERWRITE_FILE_WITH_CONTENT: {
bool entitled = false;
xpc_object_t val = xpc_connection_copy_entitlement_value(peer, BOOTSTRAPPER_ENTITLEMENT);
if (xpc_get_type(val) == XPC_TYPE_BOOL) {
entitled = xpc_bool_get_value(val);
}
if (!entitled) {
xpc_dictionary_set_int64(xreply, "error", EPERM);
xpc_dictionary_set_string(xreply, "errorDescription", "This call requires the " BOOTSTRAPPER_ENTITLEMENT ".");
break;
}
overwrite_file(request, xreply, pinfo_p);
}
default:
xpc_dictionary_set_int64(xreply, "error", EINVAL);
break;
Expand Down
100 changes: 100 additions & 0 deletions src/payload/jailbreakd/overwrite_file.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
#include <stdio.h>
#include <stdlib.h>
#include <dispatch/dispatch.h>
#include <xpc/xpc.h>
#include <xpc/private.h>
#include <xpc/connection.h>
#include <libjailbreak/libjailbreak.h>
#include <CoreFoundation/CoreFoundation.h>
#include <payload/payload.h>
#include <paleinfo.h>
#include <errno.h>
#include <spawn.h>
#include <pthread.h>
#define TARGET_OS_IPHONE 1
#include <spawn_private.h>
#include <sys/utsname.h>
#include <sys/spawn_internal.h>
#include <sys/kern_memorystatus.h>
#include <CoreFoundation/CoreFoundation.h>
#include <removefile.h>
#include <copyfile.h>

#include <sys/stat.h>

void overwrite_file(xpc_object_t xrequest, xpc_object_t xreply, struct paleinfo* pinfo) {
size_t data_size;
const char* path = xpc_dictionary_get_string(xrequest, "path");
uint64_t mode = xpc_dictionary_get_uint64(xrequest, "mode");
const uint8_t* data = xpc_dictionary_get_data(xrequest, "data", &data_size);
if (!path) {
xpc_dictionary_set_string(xreply, "errorDescription", "Missing file path");
xpc_dictionary_set_int64(xreply, "error", EINVAL);
return;
}

const char* allowlist[] = {
"/var/jb/etc/apt/sources.list.d",
"/etc/apt/sources.list.d",
"/.installed_",
"/var/jb/.installed_",
NULL
};

bool is_allowlisted;
for (uint16_t i = 0; allowlist[i] != NULL; i++) {
if (!strncmp(allowlist[i], path, strlen(allowlist[i]))) {
is_allowlisted = true;
}
}

if (!is_allowlisted) {
xpc_dictionary_set_string(xreply, "errorDescription", "requested file not in allowlist");
xpc_dictionary_set_int64(xreply, "error", EPERM);
return;
}

if (!data) {
xpc_dictionary_set_string(xreply, "errorDescription", "Missing file data");
xpc_dictionary_set_int64(xreply, "error", EINVAL);
return;
}

int ret;
struct stat st;
if ((ret = lstat(path, &st))) {
if (errno != ENOENT) {
xpc_dictionary_set_string(xreply, "errorDescription", "failed to stat destination file");
xpc_dictionary_set_int64(xreply, "error", errno);
return;
}
}

if (!S_ISREG(st.st_mode)) {
xpc_dictionary_set_string(xreply, "errorDescription", "destination file exists and is not a regular file");
xpc_dictionary_set_int64(xreply, "error", errno);
return;
}

int fd = open(path, O_WRONLY | O_TRUNC | O_CREAT, (mode_t)mode);
if (fd == -1) {
xpc_dictionary_set_string(xreply, "errorDescription", "failed to open destination file");
xpc_dictionary_set_int64(xreply, "error", errno);
return;
}

errno = 0;
ssize_t didWrite = write(fd, data, data_size);
if (didWrite == -1) {
xpc_dictionary_set_string(xreply, "errorDescription", "Failed to write destination file");
xpc_dictionary_set_int64(xreply, "error", errno);
return;
}

xpc_dictionary_set_string(xreply, "message", "Success");
xpc_dictionary_set_int64(xreply, "bytes-written", didWrite);

close(fd);

return;
}
4 changes: 4 additions & 0 deletions src/payload/p1ctl/bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,13 @@ int bootstrap_main(int argc, char* argv[]) {
}

xpc_object_t xdict = xpc_dictionary_create(NULL, NULL, 0);

xpc_dictionary_set_string(xdict, "path", bootstrap);
xpc_dictionary_set_uint64(xdict, "cmd", JBD_CMD_DEPLOY_BOOTSTRAP);
xpc_dictionary_set_string(xdict, "bootstrapper-name", "p1ctl");
xpc_dictionary_set_string(xdict, "bootstrapper-version", "3.0");
xpc_dictionary_set_bool(xdict, "no-password", no_password);

if (password) xpc_dictionary_set_string(xdict, "password", password);
xpc_object_t xreply = jailbreak_send_jailbreakd_message_with_reply_sync(xdict);
xpc_release(xdict);
Expand Down

0 comments on commit dd9f82c

Please sign in to comment.