Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help Needed: Automating tests #87

Open
Hackndo opened this issue Oct 9, 2023 · 3 comments
Open

Help Needed: Automating tests #87

Hackndo opened this issue Oct 9, 2023 · 3 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@Hackndo
Copy link
Collaborator

Hackndo commented Oct 9, 2023

lsassy

Description

lsassy is a Python tool designed to remotely extract credentials from a set of hosts, particularly targeting the lsass process on these hosts. This is done in two steps First, code must be executed on the remote target to dump lsass. Then, the dump must be parsed remotely to extract the passwords.

Workflow

Here is how a dump and parsing works in a nutshell:

https://github.com/Hackndo/lsassy/blob/4b1ddf1b3491b014aa27a68f3aa26cb0c962b0a5/lsassy/console.py#L99

From console.py, the ThreadPool is used to execute different lsassy instances in different threads

https://github.com/Hackndo/lsassy/blob/4b1ddf1b3491b014aa27a68f3aa26cb0c962b0a5/lsassy/core.py#L149

Get an SMB session with the target and provided credentials (checks for admin rights)

https://github.com/Hackndo/lsassy/blob/4b1ddf1b3491b014aa27a68f3aa26cb0c962b0a5/lsassy/core.py#L170

Get the dumping method (defined globally in https://github.com/Hackndo/lsassy/blob/master/lsassy/dumpmethod/__init__.py and every dump method will override get_commands)

https://github.com/Hackndo/lsassy/blob/4b1ddf1b3491b014aa27a68f3aa26cb0c962b0a5/lsassy/core.py#L175 to actually dump lsass remotely.

https://github.com/Hackndo/lsassy/blob/4b1ddf1b3491b014aa27a68f3aa26cb0c962b0a5/lsassy/dumpmethod/__init__.py#L291

For dumping lsass, a command line is remotely executed on the target using one of the executors (SMB using services by default, code stolen from impacket)

https://github.com/Hackndo/lsassy/blob/4b1ddf1b3491b014aa27a68f3aa26cb0c962b0a5/lsassy/dumpmethod/__init__.py#L300

Checks if dump was successful

https://github.com/Hackndo/lsassy/blob/4b1ddf1b3491b014aa27a68f3aa26cb0c962b0a5/lsassy/core.py#L193

Then back to core.py, instantiating Parser that will use Pypykatz project to parse the lsass dump remotely.

https://github.com/Hackndo/lsassy/blob/4b1ddf1b3491b014aa27a68f3aa26cb0c962b0a5/lsassy/core.py#L208

To write credentials in console (and file if asked)

Goal

I want to create tests for lsassy to ensure that all features and options work correctly with each new version release.
I know how to create tests for everything that happens locally on my machine (and on Github actions), like testing threads number, instantiating classes dynamically, stuff like that.

My issue

The problem I encounter is testing network functionalities. I know about mock from unittest but I don't think it's enough for what I need.

For instance:

These are behaviors I can test if I execute lsassy in a controlled environment, with a Windows machine whose IP address I know. However, I would like to be able to launch tests from anywhere.

Ideas

One solution I can think of would be to use Docker, with a Linux machine executing the tool, and a Windows machine that would be the target.

But I'm not sure it's a good solution, and I would really appreciate some input

Thanks a lot

@Hackndo Hackndo added enhancement New feature or request help wanted Extra attention is needed labels Oct 9, 2023
@Driikolu
Copy link

It is possible to create a GitHub Workflow (actions), that will execute jobs on 2 separates runners (See https://docs.github.com/en/actions/using-jobs/choosing-the-runner-for-a-job ).

I think here, that you can create a workflow that will trigger on commit on the main branch.
I'm not an expert in writing workflow but it could be something like this :

name: Lsassy tests

on:
  push:
    branches:
      - main

jobs:
  windows:
    runs-on: windows-latest

    steps:
    - name: Checkout repository
      uses: actions/checkout@v2

    - name: Running lsassy on windows
      run: |
        <YOUR CODE HERE>

  linux:
    runs-on: ubuntu-latest
    needs: windows  #So you make sure the windows tests have been done

    steps:
    - name: Checkout repository
      uses: actions/checkout@v2

    - name: Checking the results and trying remote executions
      run: |
        <YOUR CODE HERE>

It is also possible to use self-hosted runners. ( https://docs.github.com/en/actions/hosting-your-own-runners/managing-self-hosted-runners/about-self-hosted-runners )
It will allow you to control your environment so you'll be able to do every network tests.

Hope it will help you.

@Hackndo
Copy link
Collaborator Author

Hackndo commented Oct 12, 2023

I think I found a workaround. I use a windows runner (provided by Github), I run lsassy on this runner, and I dump lsass on localhost. For this to work, I need to add a local admin and set a registry key, but it seems to work quite well
92e4ae4

@NokiDev
Copy link

NokiDev commented Oct 16, 2023

@Hackndo, great workaround.

It sounds that

  • all data related commands can be tested through unit tests ( like parsing the dump )
  • all "client" (remote handler) can be tested by mocking cases (wrong responses, good ones and special cases)
  • all remote operations (that run on windows hosts) can be either tested directly on the host based on configuration and in that case would require to setup several hosts to test your cases
  • and of course have complete (or integration) tests cases you'll need to pop off the whole stack.

Of course everything I described can be combined.
I'm so sorry I didn't had time to look at the code you provided.

But if you can have a quick win by checking the whole is working correctly do so ! Your idea and "workaround" is the way to go.
But when you'll need to identify which part is faulty then try to unit test it as the fault arise. So it doesn't happen again.
Not sure I would have time but I'll look at the code and try to see how all the above is possible

Cya

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants