This code can find all the SK records in an NTUSER.DAT
Richard Sharpe
rsharpe at ns.aus.com
Thu Oct 31 09:15:26 GMT 2002
Hi,
This program can find all the SK records in an NTUSER.DAT, which means it
can find all the Security Descriptors in one.
It will be a short step from here to modify the SID of certain of them,
including those in the DACLs.
Build it by:
gcc -g -I../include -I../ubiqx -I../nsswitch -I../smbwrapper -I.. -o
profiles profiles.c
from the samba/source/utils dir. Run by:
./profiles /path/to/NTUSER.DAT
Regards
-----
Richard Sharpe, rsharpe at ns.aus.com, rsharpe at samba.org,
sharpe at ethereal.com, http://www.richardsharpe.com
-------------- next part --------------
#include "includes.h"
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/mman.h>
typedef unsigned int DWORD;
typedef unsigned short WORD;
#define REG_REGF_ID 0x66676572
typedef struct regf_block {
DWORD REGF_ID; /* regf */
DWORD uk1;
DWORD uk2;
DWORD tim1, tim2;
DWORD uk3; /* 1 */
DWORD uk4; /* 3 */
DWORD uk5; /* 0 */
DWORD uk6; /* 1 */
DWORD first_key; /* offset */
unsigned int dblk_size;
DWORD uk7[116]; /* 1 */
DWORD chksum;
} REGF_HDR;
typedef struct hbin_sub_struct {
DWORD dblocksize;
char data[1];
} HBIN_SUB_HDR;
#define REG_HBIN_ID 0x6E696268
typedef struct hbin_struct {
DWORD HBIN_ID; /* hbin */
DWORD next_off;
DWORD prev_off;
DWORD uk1;
DWORD uk2;
DWORD uk3;
DWORD uk4;
DWORD blk_size;
HBIN_SUB_HDR hbin_sub_hdr;
} HBIN_HDR;
#define REG_NK_ID 0x6B6E
typedef struct nk_struct {
WORD NK_ID;
WORD type;
DWORD t1, t2;
DWORD uk1;
DWORD own_off;
DWORD subk_num;
DWORD uk2;
DWORD lf_off;
DWORD uk3;
DWORD val_cnt;
DWORD val_off;
DWORD sk_off;
DWORD clsnam_off;
} NK_HDR;
#define REG_SK_ID 0x6B73
typedef struct sk_struct {
WORD SK_ID;
WORD uk1;
DWORD prev_off;
DWORD next_off;
DWORD ref_cnt;
DWORD rec_size;
char sec_desc[1];
} SK_HDR;
typedef struct sec_desc_rec {
WORD rev;
WORD type;
DWORD owner_off;
DWORD group_off;
DWORD sacl_off;
DWORD dacl_off;
} MY_SEC_DESC;
#define OFF(f) (0x1000 + (f) + 4)
print_sid(DOM_SID *sid)
{
int i, comps = sid->num_auths;
fprintf(stdout, "S-%u-%u", sid->sid_rev_num, sid->id_auth[5]);
for (i = 0; i < comps; i++) {
fprintf(stdout, "-%u", sid->sub_auths[i]);
}
fprintf(stdout, "\n");
}
int main(int argc, char *argv[])
{
int i, fd, aces, start = 0;
typedef struct acl_struct {
unsigned char type;
unsigned char flags;
unsigned short length;
unsigned int perms;
DOM_SID trustee;
} ACL;
void *base;
struct stat sbuf;
fstring sid_str;
REGF_HDR *regf_hdr;
HBIN_HDR *hbin_hdr;
NK_HDR *nk_hdr;
SK_HDR *sk_hdr;
WORD first_sk_off, sk_off;
MY_SEC_DESC *sec_desc;
int *ptr;
if (argc < 2) {
fprintf(stderr, "Usage: profiles profile-file\n");
exit(1);
}
fd = open(argv[1], O_RDWR, 0000);
if (fd < 0) {
fprintf(stderr, "Could not open %s: %s\n", argv[1],
strerror(errno));
exit(2);
}
if (fstat(fd, &sbuf) < 0) {
fprintf(stderr, "Could not stat file %s, %s\n", argv[1],
strerror(errno));
exit(3);
}
/*
* Now, mmap the file into memory, check the header and start
* dealing with the records. We are interested in the sk record
*/
start = 0;
base = mmap(&start, sbuf.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if ((int)base == -1) {
fprintf(stderr, "Could not mmap file: %s, %s\n", argv[1],
strerror(errno));
exit(4);
}
regf_hdr = (REGF_HDR *)base;
fprintf(stdout, "Registry file size: %u\n", sbuf.st_size);
if (regf_hdr->REGF_ID != REG_REGF_ID) {
fprintf(stderr, "Incorrect Registry file (doesn't have header ID): %s\n", argv[1]);
exit(5);
}
fprintf(stdout, "First Key Off: %u, Data Block Size: %u\n",
regf_hdr->first_key, regf_hdr->dblk_size);
hbin_hdr = (HBIN_HDR *)(base + 0x1000);
/*
* This should be the hbin_hdr
*/
if (hbin_hdr->HBIN_ID != REG_HBIN_ID) {
fprintf(stderr, "Incorrect hbin hdr: %s\n", argv[1]);
exit(6);
}
fprintf(stdout, "Next Off: %u, Prev Off: %u\n",
hbin_hdr->next_off, hbin_hdr->prev_off);
nk_hdr = (NK_HDR *)(base + 0x1000 + regf_hdr->first_key + 4);
if (nk_hdr->NK_ID != REG_NK_ID) {
fprintf(stderr, "Incorrect NK Header: %s\n", argv[1]);
exit(7);
}
fprintf(stdout, "Type: %0x\n", nk_hdr->type);
fprintf(stdout, "SK Off : %o\n", (0x1000 + nk_hdr->sk_off + 4));
sk_hdr = (SK_HDR *)(base + 0x1000 + nk_hdr->sk_off + 4);
sk_off = first_sk_off = nk_hdr->sk_off;
do {
DOM_SID *owner_sid, *group_sid;
ACL *sacl, *dacl;
if (sk_hdr->SK_ID != REG_SK_ID) {
fprintf(stderr, "Incorrect SK Header format: %08X\n",
(0x1000 + nk_hdr->sk_off + 4));
exit(8);
}
ptr = (int *)sk_hdr;
fprintf(stdout, "Off: %08X, Refs: %u, Size: %u\n",
sk_off, sk_hdr->ref_cnt, sk_hdr->rec_size);
sec_desc = &(sk_hdr->sec_desc[0]);
owner_sid = (DOM_SID *)(&sk_hdr->sec_desc[0] + sec_desc->owner_off);
group_sid = (DOM_SID *)(&sk_hdr->sec_desc[0] + sec_desc->group_off);
sacl = (ACL *)(&sk_hdr->sec_desc[0] + sec_desc->sacl_off);
dacl = (ACL *)(&sk_hdr->sec_desc[0] + sec_desc->dacl_off);
fprintf(stdout, " Owner SID: "); print_sid(owner_sid);
fprintf(stdout, " Group SID: "); print_sid(group_sid);
fprintf(stdout, " SACL: ");
if (!sec_desc->sacl_off)
fprintf(stdout, "NONE\n");
else
fprintf(stdout, "\n SACL Here\n");
fprintf(stdout, " DACL: ");
if (!sec_desc->dacl_off)
fprintf(stdout, "NONE\n");
else
fprintf(stdout, "\n DACL Here\n");
sk_off = sk_hdr->prev_off;
sk_hdr = (SK_HDR *)(base + OFF(sk_hdr->prev_off));
} while (sk_off != first_sk_off);
}
More information about the samba-technical
mailing list