Skip to content

smbclient: add list_snapshots command#15

Merged
psycep merged 1 commit intomainfrom
smbclient-list-snapshots
Apr 22, 2026
Merged

smbclient: add list_snapshots command#15
psycep merged 1 commit intomainfrom
smbclient-list-snapshots

Conversation

@psycep
Copy link
Copy Markdown
Collaborator

@psycep psycep commented Apr 22, 2026

Summary

Fixes #8. Adds list_snapshots to smbclient's interactive shell, which enumerates VSS shadow copies on the currently selected share via FSCTL_SRV_ENUMERATE_SNAPSHOTS. Output format matches Impacket's smbclient.py:

SMB (corp\c$:\)> list_snapshots
@GMT-2026.03.15-22.24.19

Unblocks the VSS-based NTDS extraction workflow (enumerate snapshot, get @GMT-...\Windows\NTDS\ntds.dit, parse offline with secretsdump -ntds).

Protocol

MS-SMB2 2.2.32 requires a two-call size probe: the first ioctl uses a 16-byte output buffer to read the SRV_SNAPSHOT_ARRAY header (SnapShotArraySize tells us how large the second buffer needs to be), then a second ioctl asks for the full payload. The body is a sequence of UTF-16LE NUL-terminated @GMT-YYYY.MM.DD-HH.MM.SS strings followed by a final UTF-16LE NUL.

Changes

  • pkg/third_party/smb2/client.go: export an Ioctl(ctlCode, input, maxOutput) method on *File as a thin wrapper over the internal ioctl helper, so FSCTL operations beyond FSCTL_PIPE_TRANSCEIVE don't need their own dedicated method in the vendored library.
  • pkg/smb/client.go: new EnumerateSnapshots() ([]string, error) method. Handles the size-probe dance, parses UTF-16LE tokens via pkg/utf16le, returns an empty slice when no snapshots exist.
  • tools/smbclient/main.go: wire list_snapshots into the shell's command switch and help text.

Test plan

  • go build ./... clean
  • go vet ./... clean
  • GOOS=windows CGO_ENABLED=0 go build ./... clean
  • go test ./pkg/transport/ passes
  • End-to-end tested against a Windows Server 2022 DC with a shadow copy created via vssadmin create shadow /for=C:. Confirmed output:
    SMB (corp\C$:\)> list_snapshots
    @GMT-2026.04.22-18.48.31
    

Fixes #8. smbclient's interactive shell now supports list_snapshots,
which enumerates VSS shadow copies on the currently selected share
via FSCTL_SRV_ENUMERATE_SNAPSHOTS. Matches Impacket smbclient.py's
list_snapshots output format.

The response follows MS-SMB2 2.2.32 and requires a two-call size
probe: the first ioctl uses a 16-byte output buffer to read the
SRV_SNAPSHOT_ARRAY header (SnapShotArraySize tells us how large the
second buffer needs to be), then a second ioctl asks for the full
payload and parses the UTF-16LE NUL-separated @GMT-... tokens.

Changes:
- pkg/third_party/smb2/client.go: add an exported Ioctl method on
  *File as a thin wrapper over the internal ioctl helper, so FSCTL
  operations beyond FSCTL_PIPE_TRANSCEIVE don't need their own
  dedicated method in the vendored library.
- pkg/smb/client.go: EnumerateSnapshots() method on *Client. Handles
  the size-probe dance, parses the UTF-16LE token list via
  pkg/utf16le, returns []string. Empty slice when no snapshots exist.
- tools/smbclient/main.go: wire list_snapshots into the shell's
  command switch and help text.

Unblocks the VSS-based NTDS extraction path:
  use c$
  list_snapshots      # get @GMT-YYYY.MM.DD-HH.MM.SS
  get @GMT-...\Windows\NTDS\ntds.dit
  secretsdump -ntds ntds.dit -system SYSTEM
@psycep psycep merged commit 5c03c57 into main Apr 22, 2026
2 checks passed
@psycep psycep deleted the smbclient-list-snapshots branch April 22, 2026 18:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Add list_snapshots command to smbclient interactive shell

1 participant