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 ls
y 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 smbclient
le 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-file
para 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