uint8_t *packet_to_bytes(packet_t *packet, size_t *length, options_t options) { buffer_t *buffer = buffer_create(BO_BIG_ENDIAN); buffer_add_int16(buffer, packet->packet_id); buffer_add_int8(buffer, packet->packet_type); buffer_add_int16(buffer, packet->session_id); switch(packet->packet_type) { case PACKET_TYPE_SYN: buffer_add_int16(buffer, packet->body.syn.seq); buffer_add_int16(buffer, packet->body.syn.options); if(packet->body.syn.options & OPT_NAME) { buffer_add_ntstring(buffer, packet->body.syn.name); } if(packet->body.syn.options & OPT_DOWNLOAD) { buffer_add_ntstring(buffer, packet->body.syn.filename); } break; case PACKET_TYPE_MSG: if(options & OPT_CHUNKED_DOWNLOAD) { buffer_add_int32(buffer, packet->body.msg.options.chunked.chunk); } else { buffer_add_int16(buffer, packet->body.msg.options.normal.seq); buffer_add_int16(buffer, packet->body.msg.options.normal.ack); } buffer_add_bytes(buffer, packet->body.msg.data, packet->body.msg.data_length); break; case PACKET_TYPE_FIN: buffer_add_ntstring(buffer, packet->body.fin.reason); break; case PACKET_TYPE_PING: buffer_add_ntstring(buffer, packet->body.ping.data); break; default: LOG_FATAL("Error: Unknown message type: %u\n", packet->packet_type); exit(1); } return buffer_create_string_and_destroy(buffer, length); }
void parse_SMB_COM_NEGOTIATE(int s, SMB_t *smb) { uint16_t choice; char dialects[256]; SMB_t *response = smb_create_response(SMB_COM_NEGOTIATE, 1, smb); choice = 0; while(buffer_can_read_ntstring(smb->data[0].buffer)) { buffer_read_next_ntstring(smb->data[0].buffer, dialects, 256); printf("Offered dialect: %s\n", dialects); choice++; } /* Parameters. */ buffer_add_int16(response->parameters[0].buffer, choice); /* Dialect index. */ buffer_add_int8(response->parameters[0].buffer, 0x03); /* Security mode. */ buffer_add_int16(response->parameters[0].buffer, 0x01); /* Max Mpx. */ buffer_add_int16(response->parameters[0].buffer, 0x01); /* Max VCs. */ buffer_add_int32(response->parameters[0].buffer, 4356); /* Buffer size. */ buffer_add_int32(response->parameters[0].buffer, 65535); /* Max raw. */ buffer_add_int32(response->parameters[0].buffer, 0); /* Session key. */ buffer_add_int32(response->parameters[0].buffer, 0x8000e3fd); /* TODO: testing. CAP_STATUS32 | CAP_NT_SMBS); Capabilities. */ buffer_add_int32(response->parameters[0].buffer, 0x8789e1f4); /* System time. */ buffer_add_int32(response->parameters[0].buffer, 0x01c8fedb); /* System time. */ buffer_add_int16(response->parameters[0].buffer, 360); /* Timezone offset. */ buffer_add_int8(response->parameters[0].buffer, 8); /* Key length. */ /* Data. */ buffer_add_bytes(response->data[0].buffer, "AAAAAAAA", 8); /* Encryption key. */ buffer_add_unicode(response->data[0].buffer, "name"); /* Server name. */ buffer_add_unicode(response->data[0].buffer, "domain"); /* Server domain. */ smb_send(response, s, -1, NULL); /* TODO: Fix. */ }
/* Needs to be freed with safe_free() */ uint8_t *command_packet_to_bytes(command_packet_t *packet, size_t *length) { buffer_t *buffer = buffer_create(BO_BIG_ENDIAN); buffer_t *buffer_with_size = buffer_create(BO_BIG_ENDIAN); uint16_t packed_id; packed_id = (packet->is_request ? 0x0000 : 0x8000); packed_id |= (packet->request_id & 0x7FFF); buffer_add_int16(buffer, packed_id); buffer_add_int16(buffer, packet->command_id); switch(packet->command_id) { case COMMAND_PING: if(packet->is_request) buffer_add_ntstring(buffer, packet->r.request.body.ping.data); else buffer_add_ntstring(buffer, packet->r.response.body.ping.data); break; case COMMAND_SHELL: if(packet->is_request) buffer_add_ntstring(buffer, packet->r.request.body.shell.name); else buffer_add_int16(buffer, packet->r.response.body.shell.session_id); break; case COMMAND_EXEC: if(packet->is_request) { buffer_add_ntstring(buffer, packet->r.request.body.exec.name); buffer_add_ntstring(buffer, packet->r.request.body.exec.command); } else { buffer_add_int16(buffer, packet->r.response.body.exec.session_id); } break; case COMMAND_DOWNLOAD: if(packet->is_request) { buffer_add_ntstring(buffer, packet->r.request.body.download.filename); } else { buffer_add_bytes(buffer, packet->r.response.body.download.data, packet->r.response.body.download.length); } break; case COMMAND_UPLOAD: if(packet->is_request) { buffer_add_ntstring(buffer, packet->r.request.body.upload.filename); buffer_add_bytes(buffer, packet->r.request.body.upload.data, packet->r.request.body.upload.length); } else { } break; case COMMAND_SHUTDOWN: break; case TUNNEL_CONNECT: if(packet->is_request) { buffer_add_int32(buffer, packet->r.request.body.tunnel_connect.options); buffer_add_ntstring(buffer, packet->r.request.body.tunnel_connect.host); buffer_add_int16(buffer, packet->r.request.body.tunnel_connect.port); } else { buffer_add_int32(buffer, packet->r.response.body.tunnel_connect.tunnel_id); } break; case TUNNEL_DATA: if(packet->is_request) { buffer_add_int32(buffer, packet->r.request.body.tunnel_data.tunnel_id); buffer_add_bytes(buffer, packet->r.request.body.tunnel_data.data, packet->r.request.body.tunnel_data.length); } else { } break; case TUNNEL_CLOSE: if(packet->is_request) { buffer_add_int32(buffer, packet->r.request.body.tunnel_close.tunnel_id); buffer_add_ntstring(buffer, packet->r.request.body.tunnel_close.reason); } else { } break; case COMMAND_ERROR: if(packet->is_request) { buffer_add_int16(buffer, packet->r.request.body.error.status); buffer_add_ntstring(buffer, packet->r.request.body.error.reason); } else { buffer_add_int16(buffer, packet->r.response.body.error.status); buffer_add_ntstring(buffer, packet->r.response.body.error.reason); } break; default: LOG_FATAL("Unknown command_id: 0x%04x", packet->command_id); exit(1); } buffer_add_int32(buffer_with_size, buffer_get_length(buffer)); buffer_add_buffer(buffer_with_size, buffer); buffer_destroy(buffer); return buffer_create_string_and_destroy(buffer_with_size, length); }