hierynomus / smbj

Server Message Block (SMB2, SMB3) implementation in Java
Other
707 stars 180 forks source link

STATUS_ACCESS_DENIED | SMB3 | Obtaining Decryption Keys for WireShark #746

Open cottiar opened 1 year ago

cottiar commented 1 year ago

I've been trying to get to the root cause of the below issue:

com.hierynomus.mssmb2.SMBApiException: STATUS_ACCESS_DENIED (0xc0000022): Create failed for \hostname\utilisateurs\IT\test\AP_VENDOR_MAPICS.csv

Because the SmbConfig has the following, the traffic monitoring on WireShark is quite useless as the data exchange is encrypted.

.withEncryptData(true);

In course, I stumbled upon THIS. Thus, my question: Does SMBJ dump the encryption session details such as ID and Key on logs? My logging is currently set to trace and I can't seem to find anything relevant. Please advise. TIA.

cottiar commented 1 year ago

If anyone lands on this page, revising SMBSessionBuilder class to add the following, I was able to get the details printed on logs:

logger.info("Successfully authenticated {} on {}, session id is {}, session key is {}", new Object[] { authContext.getUsername(), this.connection.getRemoteHostname(), encodeHexString(BigInteger.valueOf(session.getSessionId()).toByteArray()), String.valueOf(Hex.encodeHex(ctx.sessionKey)) });
logger.info("signing key is {}", new Object[] { getKeyInHex(context.getSigningKey()) });      
if(context.getDecryptionKey() != null) {logger.info("decryption key is {}", new Object[] { getKeyInHex(context.getDecryptionKey()) });  }
if(context.getEncryptionKey() != null) {logger.info("encryption key is {}", new Object[] { getKeyInHex(context.getEncryptionKey()) });  }  

Although I ended up not requiring this because the blog I was following relied only the session id and session key reported on WireShark's pcap only, which I paid attention to, a little late. None of this effort resolved the issue.

What resolved however was this: the file to be renamed did not award Full Control permissions to the user account being used for this operation. This is despite other permissions such as Read/Write/Execute/Modify enabled. After the Full Control permissions was granted, the operation succeeded.

cottiar commented 1 year ago

Hello, I am re-opening this seeking your assistance to understand whether this could be fixed on smbj. Please advise.

hierynomus commented 1 year ago
  1. The reason why SMBJ will never print the encryption keys should be self-explanatory I hope....
  2. Without having at least some insight into what your code is doing I can only guess what's going wrong. My guess is that it's not SMBJ's fault, but you're requesting too wide permissions for the action that you're doing. Are you using AccessMask.MAXIMUM_ALLOWED?
cottiar commented 1 year ago
  1. Yes, just was wondering if there was an option. In any case, this was to be used during a debugging session alone. Clear.
  2. I apologize, here are the details:

Decompiled code from a package authored by someone else:

  public String renameFile(String paramString1, String paramString2, boolean paramBoolean) throws SmbFileSystemException {
    File file = getFile(paramString1, EnumSet.of(AccessMask.GENERIC_ALL), SMB2CreateDisposition.FILE_OPEN);
    try {
      String str;
      int i = paramString1.lastIndexOf('\\');
      if (i == -1) {
        str = "\\";
      } else {
        str = paramString1.substring(0, i + 1);
      } 
      if (exists(str + str) && !paramBoolean)
        throw new SmbFileSystemException("Rename failed. A file named '" + paramString2 + "' already exists"); 
      file.rename(str + str, paramBoolean);
      if (file != null)
        file.close(); 
    } catch (Throwable throwable) {
      if (file != null)
        try {
          file.close();
        } catch (Throwable throwable1) {
          throwable.addSuppressed(throwable1);
        }  
      throw throwable;
    } 
    return paramString2;
  }

With this, I see the following on WireShark:

image

With Access Mask specs returned by server:

image

I remember attempting with FILE_READ_DATA, FILE_WRITE_DATA, FILE_READ_EA, FILE_WRITE_EA that ended up in failure too. Would you like me test anything in specific? Please advise. TIA.

PS: The rename action succeeds via Windows SMB client.