Determinar los recursos compartidos de SMB a los que tengo acceso de lectura y/o escritura

Determinar los recursos compartidos de SMB a los que tengo acceso de lectura y/o escritura

Para una serie de objetivos (IP), me gustaría determinar a qué recursos compartidos SMB no tiene acceso mi cuenta, a cuáles tiene acceso de lectura y a cuáles tiene acceso de lectura/escritura.

Actualmente estoy usando smbclient. El comando que ejecuto primero es

smbclient -L [targetIP] -U [user] -p 445

Esto me da una lista de acciones. Por ejemplo;

        Sharename       Type      Comment
        ---------       ----      -------
        ADMIN$          Disk      Remote Admin
        C$              Disk      Default share
        IPC$            IPC       Remote IPC
        print$          Disk      Printer Drivers
        MySecrets       Disk

Entonces puedo conectarme a un archivo compartido con este comando

smbclient //[target]/[name_of_share_from_list] -U [user] -p 445

Lo que da como resultado un mensaje SMB. Desde el mensaje escribo lsy si veo archivos, sé que tengo acceso de lectura. Supongo que tengo que enviar un archivo para ver si tengo acceso de escritura.

Esto es tedioso. ¿Cómo puedo automatizar esto de modo que para la lista dada de objetivos, obtenga una lista de todos los recursos compartidos y el nivel de acceso que tiene mi cuenta a ellos?

Respuesta1

Ya tenías gran parte del trabajo realizado. Leer la página de manual smbclientle habría proporcionado el -c <command>parámetro, que se puede utilizar para proporcionar uno o más comandos directamente en lugar de hacerlo de forma interactiva.

#!/bin/bash
username="DOMAIN\\USER"    # Double backslash
password="PASSWORD"        # For demonstration purposes only
hostname="TARGET_HOST"     # SMB hostname of target

cd "${TMPDIR:-/tmp}"
touch tmp_$$.tmp           # Required locally to copy to target

smbclient -L "$hostname" -g -A <( echo "username=$username"; echo "password=$password" ) 2>/dev/null |
    awk -F'|' '$1 == "Disk" {print $2}' |
    while IFS= read -r share
    do
        echo "Checking root of share '$share'"

        if smbclient "//$hostname/$share/" "$password" -U "$username" -c "dir" >/dev/null 2>&1
        then
            status=READ

            # Try uprating to read/write
            if smbclient "//$hostname/$share/" "$password" -U "$username" -c "put tmp_$$.tmp ; rm tmp_$$.tmp" >/dev/null 2>&1
            then
                status=WRITE
            fi
        else
            status=NONE
        fi

        case "$status" in
            READ) echo "Well, $username has read access" ;;
            WRITE) echo "Yes, $username has write access" ;;
            *) echo "No, $username has no access" ;;
        esac
    done

rm -f tmp_$$.tmp

Respuesta2

Tal vezMapa SMBte puede ayudar con esta tarea. Su autor lo desarrolló precisamente con ese propósito.

$  python smbmap.py -H [targetIP] -u [user] -P 445
[+] Finding open SMB ports....
[+] User SMB session establishd...
[+] IP: 192.168.0.4:445 Name: 192.168.0.4
        Disk                                                    Permissions
        ----                                                    -----------
        ADMIN$                                                  READ, WRITE
        C$                                                      READ, WRITE
        IPC$                                                    NO ACCESS
        TMPSHARE                                                READ, WRITE     

Puede utilizar --host-filepara pasar una lista de objetivos.

Internamente intenta crear un directorio con un nombre aleatorio para comprobar si tenemos permisos de escritura.

Respuesta3

Mismo enfoque que la respuesta aceptada pero usandoansible. Esto luego se puede usar para montar como solo lectura o lectura-escritura. (Lo que luego fabrica otras herramientas comofusionesfunciona como se esperaba cuando se crea una unión de sistemas de archivos)

- name: get available samba shares
  ansible.builtin.shell:
    cmd: "smbclient -L //{{ samba_ip }} -U % -g | grep Disk"
  register: samba_shares_raw

- name: extract samba shares
  ansible.builtin.set_fact:
    samba_shares: "{{ (samba_shares | default([])) + [ ( item | split('|') )[1] ] }}"
  loop: "{{ samba_shares_raw.stdout_lines }}"

- name: send a file to test ro / rw access
  ansible.builtin.file:
    path: "{{ ansible_env.HOME }}/samba_client"
    state: touch

- name: test writeable samba
  ansible.builtin.shell:
    cmd: "smbclient -U % //{{ samba_ip }}/{{ item }} -c 'put samba_client'"
    chdir: "{{ ansible_env.HOME }}"
  register: writeable_raw
  ignore_errors: true
  loop: "{{ samba_shares }}"

- name: extract writeable results
  ansible.builtin.set_fact:
    writeable: "{{ writeable | default({}) | combine({ item.item : not item.failed }) }}"
  loop: "{{ writeable_raw.results }}"
  loop_control:
    label: "{{ item.item }}"

- name: samba mount directories
  ansible.builtin.file:
    state: directory
    recurse: true
    path: "{{ ansible_env.HOME }}/samba/{{ item }}"
  loop: "{{ samba_shares }}"

- name: mount samba shares
  ansible.posix.mount:
    src: "//{{ samba_ip }}/{{ item }}"
    path: "{{ ansible_env.HOME }}/samba/{{ item }}"
    fstype: cifs
    opts: "{{ 'rw' if writeable[item] else 'ro' }},guest,uid=1000,gid=1000"
    state: mounted
  loop: "{{ samba_shares }}"
  become: true

información relacionada