#!/usr/bin/python
# check_pipes.py - enumerate accessible named pipes on an SMB target
# Usage:
#   python check_pipes.py <ip>
#   python check_pipes.py <ip> <username> <password>
#   python check_pipes.py <ip> <username> <password> <domain>

import sys
import socket
from mysmb import MYSMB


PIPES = [
    'browser', 'spoolss', 'netlogon', 'lsarpc', 'samr',
    'srvsvc', 'wkssvc', 'atsvc', 'epmapper', 'eventlog',
    'InitShutdown', 'keysvc', 'ntsvcs', 'scerpc',
    'plugplay', 'protected_storage', 'trkwks',
    'W32TIME', 'DAV RPC SERVICE',
    'MsFteWds', 'Search', 'PIPE_EVENTROOT\\CIMV2SCM EVENT PROVIDER',
]


def main():
    if len(sys.argv) < 2:
        print("Usage: {} <ip> [username] [password] [domain]".format(sys.argv[0]))
        sys.exit(1)

    target = sys.argv[1]
    username = sys.argv[2] if len(sys.argv) > 2 else ''
    password = sys.argv[3] if len(sys.argv) > 3 else ''
    domain = sys.argv[4] if len(sys.argv) > 4 else ''

    print("[*] Target  : {}".format(target))
    print("[*] User    : {!r}".format(username))
    print("[*] Domain  : {!r}".format(domain))
    print("[*] Password: {!r}".format('*' * len(password)))
    print()

    conn = MYSMB(target)
    conn.get_socket().setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

    try:
        conn.login(username, password, domain, maxBufferSize=4356)
    except Exception as e:
        print("[-] Login failed: {}".format(e))
        sys.exit(1)

    try:
        server_os = conn.get_server_os()
        print("[+] Server OS: {}".format(server_os))
    except Exception:
        print("[!] Could not read server OS")

    print()

    try:
        tid = conn.tree_connect_andx('\\\\' + target + '\\IPC$')
    except Exception as e:
        print("[-] Could not connect to IPC$: {}".format(e))
        sys.exit(1)

    print("[*] Probing named pipes on \\\\{}\\IPC$".format(target))
    print("-" * 60)

    opened = []
    denied = []

    for pipe in PIPES:
        try:
            fid = conn.nt_create_andx(tid, pipe)
            print("[+] OPEN  {:<40} fid=0x{:x}".format(pipe, fid))
            opened.append(pipe)
            try:
                conn.close(tid, fid)
            except Exception:
                pass
        except Exception as e:
            msg = str(e).split('\n')[0]
            print("[-] DENY  {:<40} ({})".format(pipe, msg))
            denied.append(pipe)

    print("-" * 60)
    print("[*] Summary: {} open, {} denied".format(len(opened), len(denied)))
    if opened:
        print("[*] Use one of these with smbold.py:")
        for p in opened:
            print("        python smbold.py {} {}".format(target, p))
    else:
        print("[!] No accessible pipes with the supplied credentials.")
        print("[!] Try eternalblue_exploit7.py instead, which only needs IPC$.")

    try:
        conn.disconnect_tree(tid)
        conn.logoff()
    except Exception:
        pass


if __name__ == '__main__':
    main()