{"id":17383464,"url":"https://github.com/johnlatwc/pypowershellxray","last_synced_at":"2025-08-21T07:33:22.148Z","repository":{"id":96673248,"uuid":"74513766","full_name":"JohnLaTwC/PyPowerShellXray","owner":"JohnLaTwC","description":"Python script to decode common encoded PowerShell scripts","archived":false,"fork":false,"pushed_at":"2018-06-13T17:36:03.000Z","size":132,"stargazers_count":215,"open_issues_count":2,"forks_count":35,"subscribers_count":27,"default_branch":"master","last_synced_at":"2024-12-19T21:09:33.478Z","etag":null,"topics":["dfir","forensic-analysis","forensics","incident-response","powershell","security","security-tools","shellcode"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JohnLaTwC.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2016-11-22T21:13:17.000Z","updated_at":"2024-11-03T19:57:03.000Z","dependencies_parsed_at":"2023-05-18T12:19:29.556Z","dependency_job_id":null,"html_url":"https://github.com/JohnLaTwC/PyPowerShellXray","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohnLaTwC%2FPyPowerShellXray","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohnLaTwC%2FPyPowerShellXray/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohnLaTwC%2FPyPowerShellXray/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JohnLaTwC%2FPyPowerShellXray/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JohnLaTwC","download_url":"https://codeload.github.com/JohnLaTwC/PyPowerShellXray/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":230501172,"owners_count":18236061,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dfir","forensic-analysis","forensics","incident-response","powershell","security","security-tools","shellcode"],"created_at":"2024-10-16T07:42:52.383Z","updated_at":"2024-12-19T21:09:38.435Z","avatar_url":"https://github.com/JohnLaTwC.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PyPowerShellXray\nPython script to decode common encoded PowerShell scripts.\n\nHope you find it helpful!\n\nEven more hacked together by @JohnLaTwC, Nov 2016\nv 0.6\nWith apologies to @Lee_Holmes for using Python instead of PowerShell. In decoding so much PowerShell, I didn't want to risk a self-infection :)\n\nThis script attempts to decode encoded powershell commands.  \n  REQUIREMENTS: This script uses vivisect for PE parsing and dissasembly: https://github.com/vivisect/vivisect. Set the PYTHONPATH as appropriate.\ne.g. set pythonpath=C:\\vivisect-master\\vivisect-master\n\nThings this script tries to do.  Emphasis on tries.\n* It attempts to decode recusively if instructed (via the -r switch)\n* It attempts to find Base64 data, compressed content (Gzip, Deflate), or char[]](77,105,95) style encoding\n* It attempts to 'find/replace' the encoded text in the powershell command. This is handy\n     if the script has numerous chunks of encoded content\n* If it finds shellcode, it attempts to display it. LIMITATION: x86 shellcode only\n     If you ever come across this sequence in PowerShell, you know you have shellcode\n\n```\n         [Byte[]]$z = 0xb8,0x46,0x0f,0x64...REST OF SHELLCODE;\n         ...\n         $Nb7=$w::VirtualAlloc(0,0x1000,$g,0x40);\n         ...\n         $w::CreateThread(0,0,$Nb7,0,0,0);\n```\nWith the shellcode it tries:\n     - Resolve APIs. The APIs used by shellcode gives defenders a clue as to what to look for on host.\n         e.g. if you calls to winsock/wininet/winhttp APIs, you know they connected to a URL or IP\n         e.g. if you see a call to WinExec / CreateProcess, you know something was downloaded and spawned\n\n```\n         push 0x0726774c         \u003c\u003c 0x0726774c is the hash of the API text \"kernel32.dll!LoadLibraryA\"\n         call ebp --\u003e kernel32.dll!LoadLibraryA\n```\n\nPretty sure @stephenfewer came up with blockhash in https://github.com/rapid7/metasploit-framework/blob/master/external/source/shellcode/windows/x86/src/block/block_api.asm\n         Rather than have a hardcoded list of API hashes, it build a dictionary based on your local binaries. \n         This means the script requires Windows as the underlying OS to do this.\n- Display ascii text for DWORD constants to assist decoding. \n         e.g. the below shows the encoding of ws2_32 [.dll] before a call to LoadLibrary\n\n```\n         push 0x00003233--\u003e '23'\n         push 0x5f327377--\u003e '_2sw'\n         push esp\n         push 0x0726774c--\u003e '\u0026wL' \u003c\u003c garbage. this is just the API hash for 'kernel32.dll!LoadLibraryA'\n         call ebp --\u003e kernel32.dll!LoadLibraryA\n```\n- Display IP:port for calls to socket/Internet APIs\n\n```\n         push 0x68bff1c0\n         push 0xbb010002--\u003e IP 192.241.191.104:443\n```\n- Display a hex dump to look for strings\n- Decode some encoded shellcode. Shellcode is often encoded.  A common one is shikata_ga_nai.\n         You can disable this behavior by the -nx switch\n         Here is an example of the shikata encoder in action:\n\n```\n         0x00000000 b8460f64cf       mov eax,0xcf640f46          \u003c\u003c 4byte XOR key\n         0x00000005 dbcf             fcmovne st0,st7             \u003c\u003c execute any floating point operation to set up GetPC\n         0x00000007 d97424f4         fnstenv  [esp - 12]         \u003c\u003c stores floating point state\n         0x0000000b 5d               pop ebp                     \u003c\u003c GetPC: pop addr of last FP instr into ebp\n         0x0000000c 29c9             sub ecx,ecx\n         0x0000000e b147             mov cl,71                   \u003c\u003c 71 DWORD to decode\n         0x00000010 314513           xor dword [ebp + 19],eax    \u003c\u003c start of XOR decode loop\n         0x00000013 83edfc           sub ebp,0xfffffffc          \u003c\u003c increment counter by 4 \n         0x00000016 034549           add eax,dword [ebp + 73]    \u003c\u003c partial garbage instruction\n         0x00000019 ed               in eax,dx                   \u003c\u003c garbage b/c it's encoded\n         0x0000001a 91               ... garbarge bytes continue\n```\n\n  Post decode you get something like:\n\n```\n         0x00000010 314513           xor dword [ebp + 19],eax\n         0x00000013 83edfc           sub ebp,0xfffffffc\n         0x00000016 03450f           add eax,dword [ebp + 15] \u003c\u003c pre decode this was: add eax,dword [ebp + 73] \n         0x00000019 e2f5             loop 0x00000010             \u003c\u003c the expected loop operation. 71 times\n         0x0000001b fc               cld                         ... decoded content. it's now valid shellcode\n         0x0000001c e882000000       call 0x000000a3\n         0x00000021 60               pushad \n         0x00000022 89e5             mov ebp,esp\n         0x00000024 31c0             xor eax,eax\n         0x00000026 648b5030         fs: mov edx,dword [eax + 48]\n         0x0000002a 8b520c           mov edx,dword [edx + 12]\n         0x0000002d 8b5214           mov edx,dword [edx + 20]\n         0x00000030 8b7228           mov esi,dword [edx + 40]\n         0x00000033 0fb74a26         movzx ecx,word [edx + 38]\n         ...\n```\nA real programmer would use an emulator (libemu).  Not this script\n\n\"I'm running this on Linux or Mac and don't have the Windows DLLs around to get the hashes for API resolution. Help!\" I added a database (sqlite) of common APIs \u0026 hashes.  Give it a whirl like so:\n\n```\npython.exe psx.py  -f test1.txt -db apihashes.db\nHex dump: 60 9c 54 5e fc e8 82 00 00 00 60 89 e5 31 c0 64 8b 50 30 8b 52 0c 8b 52 14 8b 72 28 0f b7 4a 26 31 ff ac 3c 61 7c 02 2c 20 c1 cf 0d 01 c7 e2 f2 52 57 8b 52 10 8b 4a 3c 8b 4c 11 78 e3 48 01 d1 51 8b 59 20 01 d3 8b 49 18 e3 3a 49 8b 34 8b 01 d6 31 ff ac c1 cf 0d 01 c7 38 e0 75 f6 03 7d f8 3b 7d 24 75 e4 58 8b 58 24 01 d3 66 8b 0c 4b 8b 58 1c 01 d3 8b 04 8b 01 d0 89 44 24 24 5b 5b 61 59 5a 51 ff e0 5f 5f 5a 8b 12 eb 8d 5d 68 49 47 c6 62 ff d5 50 6a 00 68 ff 0f 1f 00 68 ee 95 b6 50 ff d5 89 c3 6a 00 68 70 69 33 32 68 61 64 76 61 54 68 4c 77 26 07 ff d5 68 44 3a 50 00 83 ec 04 6a 00 8d 44 24 04 50 6a 01 8d 44 24 10 50 68 9a 63 6f da ff d5 6a 04 53 68 db f8 3a d6 ff d5 89 f4 61 9d c3\n0x00000000 60               pushad\n0x00000001 9c               pushfd\n0x00000002 54               push esp\n0x00000003 5e               pop esi\n0x00000004 fc               cld\n0x00000005 e882000000       call 0x0000008c\n0x0000000a 60               pushad\n0x0000000b 89e5             mov ebp,esp\n0x0000000d 31c0             xor eax,eax\n0x0000000f 648b5030         fs: mov edx,dword [eax + 48]\n0x00000013 8b520c           mov edx,dword [edx + 12]\n0x00000016 8b5214           mov edx,dword [edx + 20]\n0x00000019 8b7228           mov esi,dword [edx + 40]\n0x0000001c 0fb74a26         movzx ecx,word [edx + 38]\n0x00000020 31ff             xor edi,edi\n0x00000022 ac               lodsb\n0x00000023 3c61             cmp al,97\n0x00000025 7c02             jl 0x00000029\n0x00000027 2c20             sub al,32\n0x00000029 c1cf0d           ror edi,13\n0x0000002c 01c7             add edi,eax\n0x0000002e e2f2             loop 0x00000022\n0x00000030 52               push edx\n0x00000031 57               push edi\n0x00000032 8b5210           mov edx,dword [edx + 16]\n0x00000035 8b4a3c           mov ecx,dword [edx + 60]\n0x00000038 8b4c1178         mov ecx,dword [ecx + edx + 120]\n0x0000003c e348             jecxz 0x00000086\n0x0000003e 01d1             add ecx,edx\n0x00000040 51               push ecx\n0x00000041 8b5920           mov ebx,dword [ecx + 32]\n0x00000044 01d3             add ebx,edx\n0x00000046 8b4918           mov ecx,dword [ecx + 24]\n0x00000049 e33a             jecxz 0x00000085\n0x0000004b 49               dec ecx\n0x0000004c 8b348b           mov esi,dword [ebx + ecx * 4]\n0x0000004f 01d6             add esi,edx\n0x00000051 31ff             xor edi,edi\n0x00000053 ac               lodsb\n0x00000054 c1cf0d           ror edi,13\n0x00000057 01c7             add edi,eax\n0x00000059 38e0             cmp al,ah\n0x0000005b 75f6             jnz 0x00000053\n0x0000005d 037df8           add edi,dword [ebp - 8]\n0x00000060 3b7d24           cmp edi,dword [ebp + 36]\n0x00000063 75e4             jnz 0x00000049\n0x00000065 58               pop eax\n0x00000066 8b5824           mov ebx,dword [eax + 36]\n0x00000069 01d3             add ebx,edx\n0x0000006b 668b0c4b         mov cx,word [ebx + ecx * 2]\n0x0000006f 8b581c           mov ebx,dword [eax + 28]\n0x00000072 01d3             add ebx,edx\n0x00000074 8b048b           mov eax,dword [ebx + ecx * 4]\n0x00000077 01d0             add eax,edx\n0x00000079 89442424         mov dword [esp + 36],eax\n0x0000007d 5b               pop ebx\n0x0000007e 5b               pop ebx\n0x0000007f 61               popad\n0x00000080 59               pop ecx\n0x00000081 5a               pop edx\n0x00000082 51               push ecx\n0x00000083 ffe0             jmp eax\n0x00000085 5f               pop edi\n0x00000086 5f               pop edi\n0x00000087 5a               pop edx\n0x00000088 8b12             mov edx,dword [edx]\n0x0000008a eb8d             jmp 0x00000019\n0x0000008c 5d               pop ebp\n0x0000008d 684947c662       push 0x62c64749--\u003e 'bGI'\n0x00000092 ffd5             call ebp --\u003e kernel32.dll!GetCurrentProcessId\n0x00000094 50               push eax\n0x00000095 6a00             push 0\n0x00000097 68ff0f1f00       push 0x001f0fff\n0x0000009c 68ee95b650       push 0x50b695ee\n0x000000a1 ffd5             call ebp --\u003e kernel32.dll!OpenProcess\n0x000000a3 89c3             mov ebx,eax\n0x000000a5 6a00             push 0\n0x000000a7 6870693332       push 0x32336970--\u003e '23ip'\n0x000000ac 6861647661       push 0x61766461--\u003e 'avda'\n0x000000b1 54               push esp\n0x000000b2 684c772607       push 0x0726774c--\u003e '\u0026wL'\n0x000000b7 ffd5             call ebp --\u003e kernel32.dll!LoadLibraryA\n0x000000b9 68443a5000       push 0x00503a44--\u003e 'P:D'\n0x000000be 83ec04           sub esp,4\n0x000000c1 6a00             push 0\n0x000000c3 8d442404         lea eax,dword [esp + 4]\n0x000000c7 50               push eax\n0x000000c8 6a01             push 1\n0x000000ca 8d442410         lea eax,dword [esp + 16]\n0x000000ce 50               push eax\n0x000000cf 689a636fda       push 0xda6f639a--\u003e 'oc'\n0x000000d4 ffd5             call ebp --\u003e advapi32.dll!ConvertStringSecurityDescriptorToSecurityDescriptorA\n0x000000d6 6a04             push 4\n0x000000d8 53               push ebx\n0x000000d9 68dbf83ad6       push 0xd63af8db\n0x000000de ffd5             call ebp --\u003e advapi32.dll!SetKernelObjectSecurity\n0x000000e0 89f4             mov esp,esi\n0x000000e2 61               popad\n0x000000e3 9d               popfd\n0x000000e4 c3               ret\n\nByte Dump:\n`.T^......`..1.d.P0.R.R..r(..J\u00261..\u003ca|.,......RW.R..J\u003c.L.x.H..Q.Y...I..:I.4...1......8.u..}.;}$u.X.X$..f.K.X.........D$$[[aYZQ..__Z....]hIG.b..Pj.h....h...P....j.hpi32hadvaThLw\u0026...hD:P....j..D$.Pj..D$.Ph.co...j.Sh..:.....a..\n```\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnlatwc%2Fpypowershellxray","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjohnlatwc%2Fpypowershellxray","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjohnlatwc%2Fpypowershellxray/lists"}