├── LICENSE ├── README.md ├── sensor.sh ├── tango ├── appserver │ └── static │ │ ├── appLogo_allblack.png │ │ ├── appLogo_allwhite.png │ │ ├── appLogo_black.gif │ │ ├── appLogo_black.png │ │ ├── appLogo_white.gif │ │ ├── appLogo_white.png │ │ ├── application.css │ │ ├── bg_hash_grey.gif │ │ ├── loader.gif │ │ ├── overlay_bottomgradient_10.png │ │ ├── overlay_bottomgradient_18.png │ │ ├── overlay_bottomgradient_large.png │ │ ├── overlay_bottomgradient_soft.png │ │ ├── overlay_glass_28.png │ │ ├── overlay_gloss_28.png │ │ ├── overlay_gradient.png │ │ ├── overlay_gradient_25.png │ │ ├── overlay_gradient_28.png │ │ ├── overlay_gradient_4.png │ │ ├── overlay_gradient_50.png │ │ ├── overlay_innerleftshadow.png │ │ ├── overlay_innershadow_4.png │ │ ├── overlay_reversegradient_28.png │ │ ├── overlay_reversegradient_4.png │ │ ├── overlay_reversegradient_light_28.png │ │ ├── overlay_reversegradientridge_28.png │ │ ├── overlay_softgradient_28.png │ │ ├── overlay_togradient_large.png │ │ ├── overlay_topInnerShadow_35.png │ │ ├── overlay_topgradient.png │ │ ├── overlay_topgradient_beige_soft.png │ │ ├── overlay_topgradient_soft.png │ │ ├── overlay_white_28.png │ │ ├── overlay_whiteridge_28.png │ │ ├── single.css │ │ ├── single_trend.css │ │ ├── single_trend.js │ │ └── splIcons.gif ├── bin │ └── vt.py ├── default │ ├── app.conf │ ├── commands.conf │ ├── data │ │ └── ui │ │ │ ├── nav │ │ │ └── default.xml │ │ │ └── views │ │ │ ├── attacker_overview.xml │ │ │ ├── attacker_profile.xml │ │ │ ├── attacker_session_analysis.xml │ │ │ ├── edit_sensor.xml │ │ │ ├── file_analysis.xml │ │ │ ├── ioc_feed.xml │ │ │ ├── location_overview.xml │ │ │ ├── malware_analysis.xml │ │ │ ├── malware_campaigns.xml │ │ │ ├── network_analysis.xml │ │ │ ├── password_analysis.xml │ │ │ ├── sensor_status.xml │ │ │ └── session_overview.xml │ ├── eventtypes.conf │ ├── indexes.conf │ ├── props.conf │ ├── savedsearches.conf │ └── transforms.conf ├── lookups │ ├── sensors.csv │ └── virustotal.csv ├── metadata │ ├── default.meta │ └── local.meta └── static │ ├── appIcon.png │ ├── appIconAlt.png │ ├── appIconAlt_2x.png │ └── appIcon_2x.png ├── tango_input ├── bin │ ├── input.py │ └── input.sh └── default │ ├── app.conf │ ├── inputs.conf │ └── outputs.conf └── uf_only.sh /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 |

3 | 4 | ## About 5 | Tango is a set of scripts and Splunk apps which help organizations and users quickly and easily deploy honeypots and then view the data and analysis of the attacker sessions. There are two scripts provided which facilitate the installation of the honeypots and/or Splunk Universal Forwarder. One of the scripts `uf_only.sh` will install the Splunk Universal Forwarder and install the necessary input and output configuration files. The other script `sensor.sh` will install the Splunk Universal Forwarder along with the Cowrie honeypot required for the Tango Honeypot Intelligence app to work. 6 | 7 | ###Version 2.0 8 | Version 2.0 now supports the Cowrie honeypot as well as updates the Sensor forwarders to 6.3.0 9 | 10 | ## Before You Begin 11 | 12 | There are a few things that should be noted before you install: 13 | 14 | - When you deploy the input app on a sensor, the app will communicate with the website, [ipv4.icanhazip.com](www.ipv4.icanhazip.com) to get the external IP address of the sensor. This is useful information for the sensor management portion of the app. Please feel free to remove if you'd rather not communicate with that site. Please note that if you do not use this, a lot of the "Sensor Management" fields will be blank. 15 | - The Tango Honeypot Intelligence Splunk App is built to use JSON formatted data from Cowrie by Michel Oosterhof, which can be found on his [github](https://github.com/micheloosterhof/cowrie). 16 | - You will need to add your own VirusTotal API key to the Splunk app, which can be configured at /opt/splunk/etc/apps/tango/bin/vt.py The API is free to obtain, you will just need to follow the procedures found on their website to receive one. Please note that you are limited to 4 requests per minute, so if you attempt to do more than that, you will not receive any information. This pertains to the File Analysis section of the Splunk Honeypot Intelligence app. 17 | 18 | ## Installation 19 | 20 | 21 | ### Sensor Installation (Cowrie and Splunk Universal Fowarder) 22 | This script has been tested on a brand-new install of Ubuntu 14.04 and Cent OS 7 with no reported issues. 23 | 24 | To get started, run the commands below and follow the prompts to enter the necessary input. 25 | 26 | ``` 27 | git clone https://github.com/aplura/Tango.git /tmp/tango; chmod +x /tmp/tango/sensor.sh 28 | cd /tmp/tango/ 29 | ./sensor.sh 30 | ``` 31 | 32 | There are some options you can change in /opt/cowrie/cowrie.cfg if you choose, however, some of these will break the forwarding of logs (such as changing the listening port set to 2222), however, there are some extra modules, such as mysql or xmpp logging you can enable if you choose, as well as changing the hostname of the honeypot. 33 | 34 | cowrie is highly configurable, so if you wish to add extra commands or output to cowrie, there are tons of resources on github or google, which can help you do that if you choose. 35 | 36 | The script will install the required packages based on the OS, then install cowrie, and lastly, install the Splunk Universal Forwarder. 37 | 38 | ### Sensor Installation (Splunk UF Only) 39 | 40 | If you already have cowrie honeypots deployed and wish to start analyzing their logs in the Tango Honeypot Intelligence Splunk App, you can run the uf_only.sh script, which will install the Splunk UF on your host, and configure the inputs and outputs necessary to start viewing your logs. 41 | 42 | To get started, run the commands below and follow the prompts to enter the necessary input. 43 | 44 | ``` 45 | git clone https://github.com/aplura/Tango.git /tmp/tango; chmod +x /tmp/tango/uf_only.sh 46 | cd /tmp/tango/ 47 | ./uf_only.sh 48 | ``` 49 | 50 | ### Server Installation 51 | 52 | In order to view the logs you are sending from cowrie, you will need to install Splunk Enterprise on a server, and install the Tango Honeypot Intelligence for Splunk App from this repo. There are plenty of guides on Splunk's website to get Splunk Enterprise running, however, the basic gist of setting up a server is this: 53 | 54 | - Download Splunk Enterprise from Splunk 55 | - Copy the Tango Honeypot Intelligence for Splunk App into $SPLUNK_HOME/etc/apps/ 56 | - Create a Splunk listener on port 9997 (It's not required to be on 9997, however, the scripts are configured to use that port, so, if you change the port, change it everywhere) 57 | - Add your VirusTotal API key to /opt/splunk/etc/apps/tango/bin/vt.py 58 | - You'll need to add the requests source into the tango app's bin directory `/opt/splunk/etc/apps/tango/bin/`. Requests can be found here: [Kenneth Reitz Github](https://github.com/kennethreitz/requests/). This is needed for the VirusTotal lookup. 59 | - Restart Splunk 60 | - You'll need to allow users to search the 'honeypot' index by default. To do this, go into “Settings”, then “Access Controls”, then “Roles”, “Admin”, then scroll all the way down to “Indexes Searched by Default”, then add honeypot to the right-hand column. 61 | 62 | Once in Splunk, you can start using the Tango app to analyze your Honeypot logs. 63 | 64 | ## Tango Honeypot Intelligence for Splunk App 65 | 66 | Now that you have your sensors and server running, you'll want to use the Tango Splunk App to analyze your logs and start identifying what the attackers are doing on your systems. Start by logging into Splunk and clicking on the "Tango Honeypot Intelligence App" on the left-hand side. 67 | 68 | Once you enter the app, you'll be first taken to the "Attack Overview" portion of the app, which shows a broad overview of the attacks against your sensors. This includes Attempts vs. Successes, Latest Logins, Attackers logging into multiple locations, etc. 69 | 70 | You'll notice at the top of the app, in the navigation pane, there are multiple categories of reports available to you, which include: 71 | 72 | - Attack Analysis 73 | - File Analysis 74 | - Network Analysis 75 | - Sensor Management 76 | - Threat Feed 77 | 78 | Below we will go through each section and describe some of the data available in each section. 79 | 80 | ### Attack Analysis 81 | 82 | ##### Attack Overview 83 | 84 | This dashboard shows a broad overview of the attacks against your sensors. This includes Attempts vs. Successes, Latest Logins, Attackers logging into multiple locations, etc. 85 | 86 | ##### Session Playlog 87 | 88 | This is one of the most beneficial dashboards available in the app, since it actually shows you what the attacker is doing on your honeypot. At the top of the dashboard, you can see the most recent sessions along with a filter to select a particular sensor. Clicking on a session will populate the panels below, which includes the passwords attempted/accepted, the commands entered, any files downloaded during the session and the raw logs for the session. 89 | 90 | ##### Attacker Profile 91 | 92 | Using this dashboard, you can inquire about a certain IP and if seen in the app, you can get valuable information pertaining to that IP to include: 93 | 94 | - Geolocational data 95 | - Times seen 96 | - SSH Client versions 97 | - Sessions seen 98 | - Files Downloaded 99 | 100 | ##### Session Analysis 101 | 102 | This series of dashboards contains some analytical information, to include the % of sessions with interaction, the various SSH versions seen, some environment details extracted by the session, and a Human vs. Bot Identification dashboard. 103 | 104 | ##### Location Overview 105 | 106 | In this section, you are able to see various geographical data related to each session and attacker. There are currently three dashboards available: 107 | 108 | - Top countries from which attackers have logged in from 109 | - Top countries where attackers have scanned from 110 | - Top sensors that have been attacked 111 | 112 | We also include a map which includes the location of attackers seen. 113 | 114 | ##### Username/Password Analysis 115 | 116 | Currently, this dashboard contains the top usernames and passwords seen being attempted by the attackers, as well as the top username/password combinations. 117 | 118 | ### Malware Analysis 119 | 120 | ##### File Analysis 121 | 122 | Starting at the top of this page, you can see the latest files downloaded by attackers, which includes the following: 123 | 124 | - URL of file 125 | - SHA256 Hash of file 126 | - Sensor which the file was seen being download 127 | - The session identifier of the session, which the file was downloaded 128 | - The time that the file was downloaded 129 | 130 | Below that is the latest "Attempted" file downloads. This contains URL's that were seen in a session that do not have a corresponding SHA256 hash (which indicates a successful download). This can be due to a server error on the hosting website, an incorrect spelling of the file, or if this URL was seen elsewhere in the command, perhaps as an argument or target site of the malware. 131 | 132 | Lastly, is a panel which you are able to look up a particular SHA256 hash seen previously downloaded in VirusTotal to retrieve the following information: 133 | 134 | - Date Scanned 135 | - SHA256 Hash 136 | - How many AV vendors identified this file 137 | - The various signatures of the file 138 | 139 | Please note that the VirusTotal API is limited to 4 requests per minute. With that being said, you can use this panel to quickly lookup the file hashes seen by in your sessions. 140 | 141 | This "lookup" will produce a local "cache" to use in other dashboards, so it's useful to run lookups on any malware you see. This was created do to limitations in the Virustotal API, and will be used as a workaround for the time being. 142 | 143 | ##### Malware Analysis 144 | 145 | This dashboard will show the Top 10 Malware Signatures we've seen over time, as well as the most recent legitimate malware. This dashboard is populated from the VirusTotal local "cache" found on the File Analysis page. This dashboard will also show you files that have been downloaded, but, produced no signatures in Virustotal. 146 | 147 | ##### Malware Campaigns 148 | 149 | This set of reports give you information on possible campaigns associated with your sessions. Currently this includes: 150 | 151 | - Potential Malware Campaigns (By URL) 152 | - Potential Malware Campaigns (By Domain) 153 | - Potential Malware Campaigns (By Filename) 154 | - Potential Malware Campaigns (By SHA Hash) 155 | 156 | This section will continue to be developed to include other possible campaign attribution by looking at other TTP's associated with each session. This could include commands entered during each session, terminal variables (size, language, SSH keys, etc.). For now, we can see the URL's, Domain's and Filenames that have been seen being used by multiple attackers. 157 | 158 | ### Network Analysis 159 | 160 | This dashboard currently includes reports on the following: 161 | 162 | - Top Domains Seen 163 | - Same URI on Multiple Domains 164 | - Latest IP Addresses Seen 165 | 166 | ### Sensor Management 167 | 168 | ##### Sensor Status 169 | 170 | This dashboard provides geographical information pertaining to each sensor currently deployed. You will find the following information available to you in this dashboard: 171 | 172 | - Sensor Name 173 | - Last Active 174 | - Sensor IP Address (External IP) 175 | - ASN 176 | - ASN Country 177 | - Network Name 178 | - Network Range 179 | 180 | This dashboard also provides you with a map populated with the locations of all your sensors deployed. 181 | 182 | ##### Edit Sensor 183 | 184 | In this dashboard, you are able to edit a few fields for your sensors, these fields are: 185 | 186 | - Owner 187 | - Owner Email 188 | - Comment 189 | 190 | 191 | ### Threat Feed 192 | 193 | Lastly, this dashboard contains feeds which you can download and integrate with other network monitoring solutions, which will hopefully be automated in the future. 194 | 195 | The feeds currently available are: 196 | 197 | - IP Addresses 198 | - Potentially Malicious URLs 199 | - SHA File Hashes 200 | - Potentially Malicious Domains 201 | - File Names 202 | 203 | ### Screenshots 204 | 205 | Below are some screenshots which illustrate the features of Tango: 206 | 207 | #### Attack Overview 208 |

209 |

210 | 211 | #### Session Analysis 212 |

213 |

214 | 215 | #### Malware Campaigns 216 |

217 |

218 | 219 | #### Session Playlog 220 |

221 |

222 | 223 | #### IOC Feed 224 |

225 |

226 | 227 | #### Network Analysis 228 |

229 |

230 | 231 | #### Malware Analysis 232 |

233 |

234 | 235 | ### To-Do 236 | - Utilize Data Models to speed up searches 237 | - Auto-extract indicators inside of malware 238 | - TOR Exit Node Identifier 239 | 240 | ### Credits 241 | - https://github.com/kennethreitz for Requests 242 | - http://virustotal.com/ for their awesome app and API we use 243 | - Michel Oosterhof for the Cowrie Honeypot 244 | -------------------------------------------------------------------------------- /sensor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Tango Sensor Install 3 | #Should be compatible with Ubuntu and Debian 4 | 5 | 6 | #Disclaimer. Continues for yes, quits for no. 7 | while true; do 8 | read -p "[!] You are about to install Cowrie and the Splunk Universal Forwarder. By running this installer, you accept Splunk's EULA. Do you wish to proceed? (Yes/No)" yn 9 | case $yn in 10 | [Yy]* ) break;; 11 | [Nn]* ) exit;; 12 | * ) echo "Please answer Yes or No.";; 13 | esac 14 | done 15 | 16 | ######################################## 17 | 18 | #User input variables 19 | #Splunk Indexer hostname/IP address from user 20 | read -e -p "[?] Enter the Splunk Indexer to forward logs to: (example: splunk.test.com:9997) " SPLUNK_INDEXER 21 | 22 | #Sensor hostname from user 23 | read -e -p "[?] Enter Sensor name. (example: hp-US-Las_Vegas-01) " HOST_NAME 24 | 25 | #SSH Port number from user 26 | read -e -p "[?] Enter new SSH port number, since Kippo will listen on default SSH port. (example: 1337) " SSH_PORT 27 | 28 | ######################################## 29 | 30 | # Logging setup. This is done to log all the output from commands executed in the script to a file. 31 | #This provides us troubleshooting data if the script fails. 32 | logfile=/var/log/tango_install.log 33 | mkfifo ${logfile}.pipe 34 | tee < ${logfile}.pipe $logfile & 35 | exec &> ${logfile}.pipe 36 | rm ${logfile}.pipe 37 | 38 | ######################################## 39 | 40 | #metasploit-like print statements. Status messages, error messages, good status returns. 41 | # I added in a notification print for areas users should definitely pay attention to. 42 | 43 | function print_status () 44 | { 45 | echo -e "\x1B[01;34m[*]\x1B[0m $1" 46 | } 47 | 48 | function print_good () 49 | { 50 | echo -e "\x1B[01;32m[*]\x1B[0m $1" 51 | } 52 | 53 | function print_error () 54 | { 55 | echo -e "\x1B[01;31m[*]\x1B[0m $1" 56 | } 57 | 58 | function print_notification () 59 | { 60 | echo -e "\x1B[01;33m[*]\x1B[0m $1" 61 | } 62 | ######################################## 63 | 64 | #Script does a lot of error checking. Decided to insert an error check function. 65 | # If a task performed returns a non zero status code, something very likely went wrong. 66 | 67 | function error_check 68 | { 69 | 70 | if [ $? -eq 0 ]; then 71 | print_good "$1 successfully completed." 72 | else 73 | print_error "$1 failed. Please check $logfile for more details." 74 | exit 1 75 | fi 76 | 77 | } 78 | 79 | ######################################## 80 | 81 | #BEGIN MAIN# 82 | 83 | ######################################## 84 | 85 | 86 | 87 | # These Variables Need to be set! # 88 | 89 | #SPLUNK_INDEXER: This is the box that is going to process your splunk logs. 90 | #Can be a hostname or an IP address. The default port is 9997/tcp. # 91 | #SPLUNK_INDEXER="splunkserver.yourdomain.com:9997" 92 | 93 | #HOST_NAME: This controls what name your kippo server will have when reviewing its 94 | # data in the Tango Splunk App. Use unique names. 95 | # Suggestion: "hp-{country code}-{city}-{number}" such as: hp-US-Las_Vegas-01 # 96 | #HOST_NAME="hp-countrycode-city-01" 97 | 98 | 99 | #SSH_PORT: This port will replace the default SSH port (22), so that Kippo may run on it, and you'll stil be able 100 | # to access the host using SSH. 101 | #SSH_PORT= "1337" 102 | 103 | 104 | ######################################## 105 | 106 | # Set the directory we are initially executing the script in. 107 | execdir=`pwd` 108 | 109 | ######################################## 110 | 111 | #We need root privs to run most of this, this is a quick check to ensure that we are root. If not, bail. 112 | 113 | print_status "Checking for root privs.." 114 | if [ $(whoami) != "root" ]; then 115 | print_error "This script must be ran with sudo or root privileges." 116 | exit 1 117 | else 118 | print_good "We are root." 119 | fi 120 | 121 | ######################################## 122 | 123 | #We check what architecture the system is and download the correct splunk Universal Forwarder for that CPU arch. 124 | 125 | arch=`uname -m` 126 | 127 | if [[ $arch == "x86_64" ]]; then 128 | INSTALL_FILE="splunkforwarder-6.3.0-aa7d4b1ccb80-Linux-x86_64.tgz" 129 | print_notification "System is $arch. Downloading: $INSTALL_FILE to /opt.." 130 | wget -O /opt/splunkforwarder-6.3.0-aa7d4b1ccb80-Linux-x86_64.tgz 'http://www.splunk.com/bin/splunk/DownloadActivityServlet?architecture=x86_64&platform=linux&version=6.3.0&product=universalforwarder&filename=splunkforwarder-6.3.0-aa7d4b1ccb80-Linux-x86_64.tgz&wget=true' &>> $logfile 131 | error_check 'Splunk Forwarder Download' 132 | elif [[ $arch == "i686" ]]; then 133 | INSTALL_FILE="splunkforwarder-6.3.0-aa7d4b1ccb80-Linux-i686.tgz" 134 | print_notification "System is $arch. Downloading: $INSTALL_FILE to /opt.." 135 | wget -O /opt/splunkforwarder-6.3.0-aa7d4b1ccb80-Linux-i686.tgz 'http://www.splunk.com/bin/splunk/DownloadActivityServlet?architecture=x86&platform=linux&version=6.3.0&product=universalforwarder&filename=splunkforwarder-6.3.0-aa7d4b1ccb80-Linux-i686.tgz&wget=true' &>> $logfile 136 | error_check 'Splunk Forwarder Download' 137 | else 138 | print_error "System arch is not x86_64 or i686. Tango Honeypot is not yet supported on other CPU architectures." 139 | exit 1 140 | fi 141 | 142 | ######################################## 143 | 144 | # Based on the OS (Debian or Redhat based), use the OS package mangaer to download required packages 145 | 146 | if [ -f /etc/debian_version ]; then 147 | apt-get -y update &>> $logfile 148 | print_notification "Installing required packages via apt-get.." 149 | apt-get -y install python-dev python-openssl python-pyasn1 authbind git libcurl4-gnutls-dev libssl-dev libffi-dev openssh-server&>> $logfile 150 | error_check 'Apt Package Installation' 151 | 152 | curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py" &>> $logfile 153 | python get-pip.py &>> $logfile 154 | print_notification "Installed pip" 155 | print_notification "Installing required python packages via pip.." 156 | pip install pycrypto cryptography service_identity requests ipwhois twisted &>> $logfile 157 | error_check 'Python pip' 158 | iptables -t nat -A PREROUTING -p tcp --dport 22 -j REDIRECT --to-port 2222 159 | elif [ -f /etc/redhat-release ]; then 160 | yum -y update &>> $logfile 161 | print_notification "Installing required packages via yum.." 162 | yum -y install wget python-devel python-zope-interface unzip git gnutls-devel gcc gcc-c++ &>> $logfile 163 | error_check 'Yum Package Installation' 164 | 165 | print_notification "Installing required python packages via easy_install.." 166 | easy_install pycrypto pyasn1 twisted requests &>> $logfile 167 | error_check 'Python easy_install' 168 | else 169 | print_error "Unable to determine correct package manager to use. This script currently supports apt-based Operating Systems (Debian, Ubuntu, Kali) and yum-based Operating Systems (Redhat, CentOS, etc.) and relies on either /etc/redhat-release or /etc/debian_version being present to determine the correct package manager to use." 170 | exit 1 171 | fi 172 | 173 | 174 | ######################################## 175 | 176 | # Adding splunk user for service to run as. Shell is set to /bin/false. 177 | 178 | print_status "Checking for splunk user and group.." 179 | 180 | getent passwd splunk &>> $logfile 181 | if [ $? -eq 0 ]; then 182 | print_status "splunk user exists. Verifying group exists.." 183 | id -g splunk &>> $logfile 184 | if [ $? -eq 0 ]; then 185 | print_notification "splunk group exists." 186 | else 187 | print_notification "splunk group does not exist. Creating.." 188 | groupadd splunk &>> $logfile 189 | usermod -G splunk splunk &>> $logfile 190 | error_check 'Creation of Splunk group and Addition of Splunk user to group' 191 | fi 192 | else 193 | print_status "Creating splunk user and group.." 194 | groupadd splunk &>> $logfile 195 | useradd -g splunk splunk -d /home/splunk -s /bin/false &>> $logfile 196 | mkdir /home/splunk 197 | chown -R splunk:splunk /home/splunk 198 | error_check 'Splunk user and group creation' 199 | 200 | fi 201 | 202 | chown -R splunk:splunk /home/splunk &>> $logfile 203 | 204 | ######################################## 205 | 206 | # Adding splunk user for service to run as. Shell is set to /bin/false. 207 | 208 | print_status "Checking for cowrie user and group.." 209 | 210 | getent passwd cowrie &>> $logfile 211 | if [ $? -eq 0 ]; then 212 | print_status "cowrie user exists. Verifying group exists.." 213 | id -g cowrie &>> $logfile 214 | if [ $? -eq 0 ]; then 215 | print_notification "cowrie group exists." 216 | else 217 | print_notification "cowrie group does not exist. Creating.." 218 | groupadd cowrie &>> $logfile 219 | usermod -G cowrie cowrie &>> $logfile 220 | error_check 'Creation of cowrie group and Addition of cowrie user to group' 221 | fi 222 | else 223 | print_status "Creating cowrie user and group.." 224 | groupadd cowrie &>> $logfile 225 | useradd -g cowrie cowrie -d /home/splunk -s /bin/false &>> $logfile 226 | error_check 'Cowrie user and group creation' 227 | 228 | fi 229 | 230 | chown -R splunk:splunk /home/splunk &>> $logfile 231 | 232 | ######################################## 233 | 234 | # Installing Cowrie Honeypot 235 | 236 | print_notification "Installing Cowrie Honeypot.." 237 | cd /opt 238 | git clone https://github.com/micheloosterhof/cowrie.git &>> $logfile 239 | error_check "Cloned Cowrie Repository from GitHub" 240 | cd cowrie 241 | cp cowrie.cfg.dist cowrie.cfg &>> $logfile 242 | # Changing the Honeypot name as well as changing the port that Kippo listens on 243 | #sed -i "s/#listen_port = 2222/listen_port = 22/" cowrie.cfg &>> $logfile 244 | #sed -i "s/#\[database_jsonlog\]/\[database_jsonlog\]/" cowrie.cfg &>> $logfile 245 | #sed -i "s/#logfile = log\/kippolog.json/logfile = log\/kippolog.json/" cowrie.cfg &>> $logfile 246 | #sed -i "s/\[output_jsonlog\]/#\[output_jsonlog\]/" cowrie.cfg &>> $logfile 247 | #sed -i "s/logfile = log\/kippo.json/#logfile = log\/kippo.json/" cowrie.cfg &>> $logfile 248 | print_notification "Configured Cowrie Honeypot" 249 | 250 | ######################################## 251 | 252 | # Changing Default SSH Port 253 | 254 | # Changing the port that SSH listens on to the variable set above 255 | if [[ $arch == "x86_64" ]]; then 256 | cd /etc/ssh/ 257 | sed -i "s/Port 22/Port $SSH_PORT/" sshd_config &>> $logfile 258 | service ssh restart &>> $logfile 259 | error_check 'SSH Service Restarted' 260 | elif [[ $arch == "i686" ]]; then 261 | cd /etc/ssh/ 262 | sed -i "s/#Port 22/Port $SSH_PORT/" sshd_config &>> $logfile 263 | service sshd restart &>> $logfile 264 | error_check "SSH Service Restarted" 265 | cd /tmp 266 | git clone https://github.com/tootedom/authbind-centos-rpm.git &>> $logfile 267 | error_check 'Cloned authbind repo from GitHub' 268 | cd authbind-centos-rpm/authbind/RPMS/x86_64/ 269 | rpm -i authbind-2.1.1-0.x86_64.rpm &>> $logfile 270 | error_check 'Installed authbind' 271 | else 272 | print_error "System arch is not x86_64 or i686. Tango Honeypot is not yet supported on other CPU architectures." 273 | exit 1 274 | fi 275 | 276 | ######################################## 277 | 278 | # Setting up authbind to allow kippo user to bind to privileged port 279 | #print_notification "Configuring Authbind" 280 | #touch /etc/authbind/byport/22 &>> $logfile 281 | #chown cowrie:cowrie /etc/authbind/byport/22 &>> $logfile 282 | chown -R cowrie:cowrie /opt/cowrie &>> $logfile 283 | cd /opt/cowrie 284 | #sed -i "s,twistd -y kippo.tac -l log/kippo.log --pidfile kippo.pid,authbind --deep twistd -y kippo.tac -l log/kippo.log --pidfile kippo.pid," start.sh &>> $logfile 285 | sudo -u cowrie ./start.sh &>> $logfile 286 | error_check "Cowrie started successfully" 287 | #print_notification "Authbind Configured to use Port 22" 288 | 289 | ######################################## 290 | 291 | # Installing Splunk Universal Forwarder and setting it to persist on reboot 292 | 293 | print_notification "Installing Splunk Universal Forwarder.." 294 | cd /opt 295 | tar -xzf $INSTALL_FILE &>> $logfile 296 | chown -R splunk:splunk splunkforwarder &>> $logfile 297 | sudo -u splunk /opt/splunkforwarder/bin/splunk start --accept-license --answer-yes --auto-ports --no-prompt &>> $logfile 298 | error_check 'Universal Forwarder Configuration' 299 | /opt/splunkforwarder/bin/splunk enable boot-start -user splunk &>> $logfile 300 | error_check 'Universal Forwarder Install' 301 | 302 | ######################################## 303 | 304 | #Check to see if the user tried to execute uf_only outside of the Tango directory. Yell at them if they did. 305 | # Grab tango_input from the Tango directory (if it's there), configure inputs.conf, start up the forwarder. We done here. 306 | 307 | print_notification "Installing tango_input.." 308 | 309 | if [ ! -d "$execdir/tango_input" ]; then 310 | print_error "Unable to find tango_input directory in $execdir. tango_input should be in the same directory as uf_only.sh. Please correct this and run the script again." 311 | exit 1 312 | else 313 | cp -r "$execdir/tango_input" /opt/splunkforwarder/etc/apps &>> $logfile 314 | fi 315 | 316 | print_notification "Configuring /opt/splunkforwarder/etc/apps/tango_input/default/inputs.conf and outputs.conf.." 317 | 318 | cd /opt/splunkforwarder/etc/apps/tango_input/default 319 | sed -i "s/test/$HOST_NAME/" inputs.conf &>> $logfile 320 | sed -i "s/test/$SPLUNK_INDEXER/" outputs.conf &>> $logfile 321 | 322 | chown -R splunk:splunk /opt/splunkforwarder &>> $logfile 323 | /opt/splunkforwarder/bin/splunk restart &>> $logfile 324 | error_check 'Tango_input installation' 325 | sudo -u cowrie chmod 777 /opt/cowrie/log/cowrie.json 326 | 327 | print_notification "If the location of your kippo log files changes or the hostname/ip of the indexer changes, you will need to modify /opt/splunkfowarder/etc/apps/tango_input/default/inputs.conf and outputs.conf respectively." 328 | 329 | print_good "Install Completed. The splunk forwarder should be reporting and sending data to your indexer. Log file is located at /var/log/tango_install.log" 330 | 331 | exit 0 332 | -------------------------------------------------------------------------------- /tango/appserver/static/appLogo_allblack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/appLogo_allblack.png -------------------------------------------------------------------------------- /tango/appserver/static/appLogo_allwhite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/appLogo_allwhite.png -------------------------------------------------------------------------------- /tango/appserver/static/appLogo_black.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/appLogo_black.gif -------------------------------------------------------------------------------- /tango/appserver/static/appLogo_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/appLogo_black.png -------------------------------------------------------------------------------- /tango/appserver/static/appLogo_white.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/appLogo_white.gif -------------------------------------------------------------------------------- /tango/appserver/static/appLogo_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/appLogo_white.png -------------------------------------------------------------------------------- /tango/appserver/static/application.css: -------------------------------------------------------------------------------- 1 | /* How to use this file 2 | 3 | Any values in application.css will override those from the default.css file. This file allows you to customize the look of your Splunk App. It does not let you change the overall layout. For the most part, use this to change background colors, buttons, navigation, menus, etc. You can change the color of the histogram bars, but the palette for other chart colors is not exposed to CSS yet. 4 | 5 | A note on images: 6 | Alpha channel PNG files are used for a variety of transparency effects (gradient, glass, shadows, etc.) These images will not work on IE6, so you should either provide an alternate image or override the image by using the "underscore" hack, i.e. _background-image:none. To ensure that IE6 does not render alpha channel PNG files, make sure that the override comes after the declaration that contains your PNG. Any image that starts with "overlay" is an alpha channel graphic. As well, the logo images that are PNG format are also alpha channel so you can use on whatever background you like. GIF formats are available and are set as transparent against black and white only. 7 | 8 | A note on background positioning: 9 | We use and image sprite (splIcons.gif) for most of the icons and arrows that appear in the UI. Background-position is used to set different colors. By default, this sprite has black, white, grey, green, and blue versions of arrows. If you want to change these colors, edit the local version of this file (inside this directory). Otherwise, you can choose a different color by adjusting the background position on the selected element. 10 | 11 | */ 12 | 13 | 14 | /* Basic Typography 15 | ---------------------------------*/ 16 | body, td { 17 | font-family:Arial,Helvetica,sans-serif; 18 | font-size:11px; 19 | color: #111; 20 | } 21 | 22 | input, textarea, select { 23 | font-family:Arial,Helvetica,sans-serif; 24 | font-size:12px; 25 | color: #333; 26 | } 27 | 28 | /* monospaced font */ 29 | .splFont-mono { 30 | font-family: Consolas,Monaco,Courier New,monospace; 31 | } 32 | 33 | 34 | /* App header elements 35 | ---------------------------------*/ 36 | 37 | /* Application logo 38 | 39 | height and width should be the same as your image. make sure to include some top and buttom margin in the padding. 40 | 41 | Black logo, green > 42 | background-image: url(appLogo_black.png); 43 | Black logo, black > 44 | background-image: url(appLogo_allblack.png); 45 | White logo, green > 46 | background-image: url(appLogo_white.png); 47 | White logo, white > 48 | background-image: url(appLogo_allwhite.png); 49 | 50 | For IE6, use the following images. Note that if you make a background color other than black or white (or close to it) you will need to redo the transparent GIF matte. 51 | White logo, green > for IE6, transparent against black 52 | background-image: url(appLogo_white.gif); 53 | Black logo, green > for IE6, transparent against white 54 | background-image: url(appLogo_black.gif); 55 | */ 56 | 57 | .appLogo { 58 | height: 43px; 59 | width: 81px; 60 | background-image: url(appLogo_white.png); 61 | _background-image: url(appLogo_white.gif); /* for IE6 */ 62 | background-repeat: no-repeat; 63 | } 64 | 65 | /* the name of your app. line height can be adjusted to fix alignment issues w/ the logo. color is the color of the text. if your logo has the name in it, then you can set this to "display:none; */ 66 | 67 | .appHeaderWrapper h1 { 68 | color:; 69 | line-height: 43px; 70 | } 71 | 72 | 73 | /* background-color and/or image of your app */ 74 | .appHeaderWrapper { 75 | background-color: #000; 76 | background-image: url(overlay_togradient_large.png); 77 | background-repeat: repeat-x; 78 | background-position: top; 79 | border-bottom-style: ; 80 | border-bottom-width: ; 81 | border-bottom-color: ; 82 | } 83 | 84 | /* color of top-right text */ 85 | .appHeaderWrapper { 86 | color: ; 87 | } 88 | /* color of top-right links */ 89 | .appHeaderWrapper a { 90 | color:; 91 | } 92 | 93 | /* app menu arrows */ 94 | .appHeaderWrapper .splIcon-triangle-3-s { 95 | background-position: ; 96 | } 97 | 98 | 99 | /* loader background */ 100 | #loading { 101 | background-color: ; 102 | } 103 | 104 | 105 | /* link colors 106 | ---------------------------------*/ 107 | a { 108 | color: ; 109 | } 110 | a.disabled { 111 | color: ; 112 | } 113 | 114 | 115 | /* nav bar and aux links 116 | ---------------------------------*/ 117 | 118 | /* 119 | set an overlay effect for your navbar or leave blank for default 120 | background-image: url(overlay_glass_28.png); 121 | background-image: url(overlay_gloss_28.png); 122 | background-image: url(overlay_gradient_28.png); 123 | background-image: url(overlay_reversegradient_28.png); 124 | background-image: url(overlay_reversegradient_light_28.png); 125 | background-image: url(overlay_reversegradientridge_28.png); 126 | background-image: url(overlay_softgradient_28.png); 127 | background-image: url(overlay_white_28.png); 128 | background-image: url(overlay_whiteridge_28.png); 129 | */ 130 | 131 | .splHeader-navigation { 132 | background-image: ; 133 | background-repeat: repeat-x; 134 | _background-image: none; 135 | } 136 | 137 | /*--- the default state ---*/ 138 | ul.appBarNav li a, ul.appBarNav li a:active, ul.appBarNav li a:visited { 139 | color: ; 140 | } 141 | 142 | /*--- the hover state ---*/ 143 | ul.appBarNav li.hasMenu a:hover, ul.appBarNav li a:hover { 144 | color: ; 145 | background-color: ; 146 | background-image: url(overlay_white_28.png); 147 | background-repeat: repeat-x; 148 | _background-image: none; /* for IE6 */ 149 | } 150 | 151 | /*--- the open state ---*/ 152 | ul.appBarNav li a.menuOpen { 153 | color: ; 154 | background-color: ; 155 | background-image: url(overlay_white_28.png); 156 | background-repeat: repeat-x; 157 | _background-image: none; /* for IE6 */ 158 | } 159 | 160 | /*--- link color ---*/ 161 | ul.appBarNav li.hasMenu a:hover, ul.appBarNav li a.menuOpen { 162 | color: ; 163 | } 164 | 165 | /* to change arrows, see Menu section, below */ 166 | 167 | 168 | /* auxiliary text and links */ 169 | .AppBar .auxLinks a { 170 | color: ; 171 | } 172 | .AppBar .auxLinks span { 173 | color: ; 174 | } 175 | 176 | /* Menus 177 | ---------------------------------*/ 178 | 179 | /* primary menu */ 180 | .splMenu-primary ul { 181 | background-color: ; 182 | } 183 | .splMenu-primary, .splMenu-primary a, .splMenu-primary a:visited, .splMenu-primary a:hover { 184 | color: ; 185 | } 186 | .splMenu-primary .actionsMenuDivider { 187 | } 188 | .splMenu-primary li:hover { 189 | background-color: ; 190 | } 191 | 192 | /* secondary menu, used for apps pulldown */ 193 | .splMenu-secondary ul { 194 | background-color: ; 195 | } 196 | .splMenu-secondary, .splMenu-secondary a { 197 | color: ; 198 | } 199 | .splMenu-secondary li.disabled a { 200 | color: ; 201 | } 202 | .splMenu-secondary li:hover { 203 | background-color: ; 204 | } 205 | .splMenu-secondary a:hover { 206 | color: ; 207 | } 208 | 209 | /* actions menu open state */ 210 | .TitleBar div.menuOpen { 211 | background-color: ; 212 | color: ; 213 | } 214 | 215 | 216 | /* 217 | Arrow color is changed by adjusting background position. use the following values for these colors: 218 | grey: background-position: -7px -367px; 219 | white: background-position: -27px -367px; 220 | green: background-position: -47px -367px; 221 | black: background-position: -67px -367px; 222 | */ 223 | 224 | /* nav arrow, default state */ 225 | ul.appBarNav li.hasMenu a span.splIcon-triangle-2-s { 226 | } 227 | 228 | /* hover state */ 229 | ul.appBarNav li.hasMenu a:hover span.splIcon-triangle-2-s { 230 | } 231 | 232 | /* open state */ 233 | ul.appBarNav li.hasMenu a.menuOpen span.splIcon-triangle-2-s { 234 | } 235 | 236 | /* actions menu open state */ 237 | .TitleBar div.menuOpen .splIcon-triangle-4-s { 238 | } 239 | 240 | 241 | /* background colors 242 | ---------------------------------*/ 243 | 244 | /* default page color */ 245 | body, .splBackground-default, 246 | .graphArea, .resultsArea, 247 | .reportSecondPanel, .reportThirdPanel, 248 | .sidebarCollapsed, 249 | .SearchBar .saTypeaheadWrapper, 250 | .ui-datepicker-links, 251 | .popupContent { 252 | background-color: ; 253 | } 254 | 255 | /* primary background - applies to search controls and primary action panels */ 256 | .viewHeader, .mainSearchControls, .splSearchControls-inline, 257 | .SearchBar .saHelpWrapper, 258 | .popupContent { 259 | background-color: ; 260 | } 261 | 262 | /* secondary background - sidebar, other panels */ 263 | .splBackground-secondary, .sidebarExpanded, 264 | .fieldValuePopup p.reportLinks { 265 | background-color: ; 266 | } 267 | 268 | /* Specific overrides */ 269 | .layoutCellInner .ResultsHeader .splHeader, .layoutCellInner .ResultsHeader .splHeader-secondary { 270 | background: transparent none; 271 | } 272 | 273 | /* Specific overrides */ 274 | .popupFooter { 275 | background-color: ; 276 | } 277 | 278 | /* dashboard background color */ 279 | body.splTemplate-dashboard { 280 | background-color:; 281 | } 282 | 283 | /* dashboard containers */ 284 | .dashboardCell { 285 | background-color: ; 286 | background-image:url(overlay_topgradient.png); 287 | background-repeat:repeat-x; 288 | _background-image: none; /* for IE6 */ 289 | } 290 | 291 | /* headers 292 | ---------------------------------*/ 293 | 294 | /* default header font color */ 295 | .splHeader-dashboard h2, .dashboardContent .ServerSideInclude h2, .dashboardContent .GenericHeader h3, .SearchBar .saRow h4 { 296 | color: ; 297 | } 298 | 299 | /* primary header background color + overlay */ 300 | .splHeader-primary, 301 | .TitleBar .splHeader, 302 | .FieldPickerPopup .splHeader-primary { 303 | background-color: ; 304 | background-image:url(overlay_topgradient.png); 305 | background-repeat:repeat-x; 306 | _background-image: none; 307 | } 308 | 309 | /* secondary (i.e. sidebar) header background color + overlay */ 310 | .splHeader-secondary { 311 | background-color:; 312 | background-image:url(overlay_topgradient.png); 313 | background-repeat:repeat-x; 314 | _background-image: none; 315 | } 316 | 317 | /* headers w/o any overlay */ 318 | .FlashTimeline .splHeader-primary { 319 | background-color:; 320 | background-image: none; 321 | } 322 | 323 | /* borders 324 | ---------------------------------*/ 325 | 326 | /* ALL elements with a generic border attribute */ 327 | * { 328 | border-color: #ccc; 329 | } 330 | 331 | /* refactor to remove these in default.css since they have specific color declarations; should be same value as * elements, above */ 332 | .splMenu-primary ul, 333 | .splMenu-secondary ul, 334 | .Paginator a:hover { 335 | border-color: ; 336 | } 337 | 338 | /* specific overrides */ 339 | 340 | .fieldValuePopup table tr.fieldNameHeaderRow th { 341 | border-bottom:1px solid #ccc; 342 | } 343 | 344 | /* horixontal rules in the sidebar */ 345 | .splDivider, .SuggestedFieldViewer .splBorder-n { 346 | border-color: #ccc; 347 | } 348 | 349 | 350 | 351 | 352 | /* search controls 353 | ---------------------------------*/ 354 | 355 | /* search button color; background-position of 0 0 is black, -40px 0 is white */ 356 | input.searchButton { 357 | background-color: ; 358 | background-position:-40px 0; 359 | } 360 | 361 | .SearchBar .assistantActivator { 362 | background-color: ; 363 | } 364 | 365 | 366 | 367 | /* Flash timeline and charts 368 | ---------------------------------*/ 369 | 370 | /* All flash charts */ 371 | /* 372 | background-color -> controls bgcolor 373 | border-left-color -> controls foregroundColor 374 | color -> controls fontColor 375 | controls and and font color get screened via an alpha layer, so should probably be set to all black or white, depending on main background 376 | */ 377 | div.FlashChart { 378 | background-color: ; 379 | color: ; 380 | border-left-color: ; 381 | } 382 | 383 | /* flash timeline specific */ 384 | /* 385 | background-color -> controls bgcolor 386 | border-left-color -> controls foregroundColor 387 | color -> controls fontColor 388 | border-right-color -> controls seriesColor 389 | controls and and font color get screened via an alpha layer, so should probably be set to all black or white, depending on main background 390 | */ 391 | div.FlashTimeline { 392 | background-color: ; 393 | border-left-color: ; 394 | color: ; 395 | /* the color of the histogram bar. border-right-color = fill */ 396 | border-right-color: ; 397 | } 398 | 399 | /* popup bar chart; should be same color as flash timeline */ 400 | .splBarGraphBar { 401 | background-color:; 402 | } 403 | 404 | 405 | 406 | 407 | /* buttons 408 | ---------------------------------*/ 409 | 410 | .splButton-primary { 411 | background-color: ; 412 | color: ; 413 | } 414 | .splButton-primary:hover { 415 | background-color: ; 416 | } 417 | .splButton-secondary { 418 | background-color:; 419 | color: ; 420 | } 421 | .splButton-secondary:hover { 422 | background-color: ; 423 | } 424 | 425 | /* form elements 426 | _________________________________*/ 427 | 428 | fieldset legend { 429 | color: ; 430 | } 431 | fieldset legend span { 432 | color: ; 433 | } 434 | p.exampleText { 435 | color: ; 436 | } 437 | p.fieldsetHelpText { 438 | color: ; 439 | } 440 | 441 | /*-- disabled and read-only form elements --*/ 442 | 443 | label.disabledLabel { 444 | color: ; 445 | } 446 | select option[disabled] { 447 | color: ; 448 | } 449 | input.readonly { 450 | background-color: ; 451 | } 452 | 453 | 454 | input[disabled]{ 455 | background-color: transparent; 456 | border-color: transparent; 457 | color: ; 458 | } 459 | 460 | /* Icons 461 | ---------------------------------*/ 462 | .splIcon-events-list, .splIcon-events-table, .splIcon-results-table { 463 | /*-- 464 | master icon file. edit the local file and include this stanza if you want to override the defaults 465 | background-image: url(splIcons.gif); 466 | 467 | --*/ 468 | } 469 | 470 | /*-- background color for icons --*/ 471 | .splIcon { 472 | background-color: #999; 473 | } 474 | 475 | /*-- switchers that use icons --*/ 476 | 477 | .ButtonSwitcher ul li.selected, .ButtonSwitcher ul li.selected:hover, 478 | .EventsViewer .default .actions, 479 | div.FlashTimeline a.logScaleSelected span, div.FlashTimeline a.linScaleSelected span { 480 | border: 1px solid #999; 481 | background-color: #999; 482 | } 483 | 484 | /*-- paginator uses similar styles --*/ 485 | 486 | .Paginator .active a, .Paginator .active a:hover { 487 | background-color: #999; 488 | border-color: #999; 489 | color: #fff; 490 | } 491 | 492 | /*-- arrow icons --*/ 493 | .splIcon-arrow-n, .splIcon-arrow-e, .splIcon-arrow-s, .splIcon-arrow-w { 494 | background-color: #999; 495 | } 496 | 497 | /* triangles. keep this last to avoid getting background colors in the arrows! */ 498 | /* Note: to separate color from implementation, we're using a numbering system to differentiate colors. 499 | 1=grey,2=white,3=green,4=black,5=blue. If the icon sprite changes, the number mapping to colors would be different */ 500 | .splIcon-triangle, 501 | .splIcon-triangle-1-n, .splIcon-triangle-1-s, .splIcon-triangle-1-e, .splIcon-triangle-1-w, 502 | .splIcon-triangle-2-n, .splIcon-triangle-2-s, .splIcon-triangle-2-e, .splIcon-triangle-2-w, 503 | .splIcon-triangle-3-n, .splIcon-triangle-3-s, .splIcon-triangle-3-e, .splIcon-triangle-3-w, 504 | .splIcon-triangle-4-n, .splIcon-triangle-4-s, .splIcon-triangle-4-e, .splIcon-triangle-4-w, 505 | .splIcon-triangle-5-n, .splIcon-triangle-5-s, .splIcon-triangle-5-e, .splIcon-triangle-5-w { 506 | background-color:transparent; 507 | } 508 | .splIcon-triangle-large { 509 | background-color:transparent; 510 | } 511 | 512 | 513 | /* tables 514 | ------------------------------*/ 515 | table.splTable { 516 | border-color: ; 517 | } 518 | table.splTable th { 519 | border-color: ; 520 | } 521 | table.splTable th a { 522 | color: ; 523 | } 524 | table.splTable td { 525 | border-color: ; 526 | } 527 | 528 | 529 | 530 | /* highlight colors 531 | ---------------------------------*/ 532 | /*-- event items --*/ 533 | .EventsViewer .default .a, .EventsViewer .default .h, .EventsViewer .default .fields .v:hover, .EventsViewer .default .fields .tg:hover { 534 | background-color: ; 535 | } 536 | 537 | /*-- row highlighting for tables --*/ 538 | table.splTable tr:hover td { 539 | background-color:; 540 | } 541 | .mouseoverHighlight, .mouseoverHightlight td { 542 | background-color:; 543 | } 544 | 545 | /*-- matching search terms --*/ 546 | .SimpleEventsViewer span.searchTermHighlight { 547 | background-color:; 548 | } 549 | 550 | /* MultiFieldViewer + SuggestedFieldViewer, i.e. highlight in the fields sidebar */ 551 | .MultiFieldViewer .fieldTabs .mouseoverHighlight, 552 | .MultiFieldViewer .fieldTabs .selected, 553 | .SuggestedFieldViewer .fieldTabs .mouseoverHighlight, 554 | .SuggestedFieldViewer .fieldTabs .selected { 555 | background-color:; 556 | } 557 | 558 | /* field picker popup hover row */ 559 | .FieldPickerPopup .fpFieldList tbody tr:hover, .FieldPickerPopup .fpFieldList tbody tr.mouseoverHighlight { 560 | background-color: ; 561 | } 562 | 563 | 564 | 565 | /* date picker 566 | ---------------------------------*/ 567 | .ui-datepicker-current-day { 568 | background-color: ; 569 | } 570 | 571 | .ui-datepicker-links { 572 | background-image: url(overlay_gradient.png) repeat-x 0 0; 573 | _background-image: none; 574 | } 575 | 576 | /* popups 577 | ---------------------------------*/ 578 | .splHeader-popup { 579 | background-color: #000; 580 | background-image: url(overlay_gradient.png); 581 | background-repeat: repeat-x; 582 | _background-image: none; 583 | } 584 | 585 | .splHeader-popup h2 { 586 | color:#FFF; 587 | } 588 | 589 | .popupContainer { 590 | border-color: ; 591 | } 592 | 593 | /* modal overlay */ 594 | .splOverlay, .splOverlay-white { 595 | background-color: #000; 596 | opacity:0.8; 597 | filter:alpha(opacity=80); 598 | } 599 | .splOverlay-white { 600 | background-color:#FFF; 601 | } 602 | 603 | /* Misc 604 | ---------------------------------*/ 605 | 606 | /* resize handle */ 607 | .ui-resizable-s { 608 | background-color:#ccc !important; 609 | } 610 | 611 | /* loading image for jobs */ 612 | .JobStatus .output .running h2, 613 | .JobStatus .output .runningReport h2, 614 | .JobStatus .output .finalizing h2 { 615 | /* 616 | loader background must match the same color as the background of your output div. leave blank to use the default loader, or download a custom image from www.ajaxload.info, name it loader.gif and include this line: 617 | 618 | background-image: url(loader.gif); 619 | */ 620 | } 621 | 622 | 623 | /* remove the gradient at top of event and results area */ 624 | .EventsViewer, .SimpleResultsTableResults { 625 | background-image: none; 626 | } 627 | -------------------------------------------------------------------------------- /tango/appserver/static/bg_hash_grey.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/bg_hash_grey.gif -------------------------------------------------------------------------------- /tango/appserver/static/loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/loader.gif -------------------------------------------------------------------------------- /tango/appserver/static/overlay_bottomgradient_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_bottomgradient_10.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_bottomgradient_18.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_bottomgradient_18.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_bottomgradient_large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_bottomgradient_large.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_bottomgradient_soft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_bottomgradient_soft.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_glass_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_glass_28.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_gloss_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_gloss_28.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_gradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_gradient.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_gradient_25.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_gradient_25.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_gradient_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_gradient_28.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_gradient_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_gradient_4.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_gradient_50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_gradient_50.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_innerleftshadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_innerleftshadow.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_innershadow_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_innershadow_4.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_reversegradient_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_reversegradient_28.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_reversegradient_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_reversegradient_4.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_reversegradient_light_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_reversegradient_light_28.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_reversegradientridge_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_reversegradientridge_28.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_softgradient_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_softgradient_28.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_togradient_large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_togradient_large.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_topInnerShadow_35.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_topInnerShadow_35.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_topgradient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_topgradient.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_topgradient_beige_soft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_topgradient_beige_soft.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_topgradient_soft.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_topgradient_soft.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_white_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_white_28.png -------------------------------------------------------------------------------- /tango/appserver/static/overlay_whiteridge_28.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/overlay_whiteridge_28.png -------------------------------------------------------------------------------- /tango/appserver/static/single.css: -------------------------------------------------------------------------------- 1 | .single-trend { 2 | position: relative; 3 | top: -15px; 4 | text-align: center; 5 | font-size: 18px; 6 | color: #888; 7 | } 8 | .single-trend i { 9 | font-size: 28px; 10 | vertical-align: text-bottom; 11 | } 12 | .single-trend.nochange, .single-trend.nochange i { 13 | font-size: 14px; 14 | } 15 | .single-trend.increase { 16 | color: #F03B4E; 17 | } 18 | .single-trend.decrease { 19 | color: #40EBBB; 20 | } 21 | .table .table, .table-striped>tbody>tr>td { 22 | color: #131B23; 23 | } 24 | -------------------------------------------------------------------------------- /tango/appserver/static/single_trend.css: -------------------------------------------------------------------------------- 1 | .single-trend { 2 | position: relative; 3 | top: -15px; 4 | text-align: center; 5 | font-size: 18px; 6 | color: #888; 7 | } 8 | .single-trend i { 9 | font-size: 28px; 10 | vertical-align: text-bottom; 11 | } 12 | .single-trend.nochange, .single-trend.nochange i { 13 | font-size: 14px; 14 | } 15 | .single-trend.increase { 16 | color: #F03B4E; 17 | } 18 | .single-trend.decrease { 19 | color: #40EBBB; 20 | } 21 | .table .table, .table-striped>tbody>tr>td { 22 | color: #131B23; 23 | } 24 | .single-value .single-result { 25 | color: #40EBBB; 26 | } 27 | -------------------------------------------------------------------------------- /tango/appserver/static/single_trend.js: -------------------------------------------------------------------------------- 1 | require([ 2 | 'jquery', 3 | 'underscore', 4 | 'splunkjs/mvc', 5 | 'splunkjs/mvc/simplesplunkview', 6 | 'splunkjs/mvc/simplexml/element/single', 7 | 'splunkjs/mvc/simplexml/ready!' 8 | ], function($, _, mvc, SimpleSplunkView, SingleElement) { 9 | // Custom view to annotate a single value element with a trend indicator 10 | var SingleValueTrendIndicator = SimpleSplunkView.extend({ 11 | // Override fetch settings 12 | outputMode: 'json', 13 | returnCount: 2, 14 | // Default options 15 | options: { 16 | changeFieldType: 'text' 17 | }, 18 | // Icon CSS classes 19 | icons: { 20 | increase: 'icon-triangle-up-small', 21 | decrease: 'icon-triangle-down-small' 22 | }, 23 | // Template for trend indicator 24 | template: _.template( 25 | '
' + 26 | ' ' + 27 | '<%- diff %>' + 28 | '
' 29 | ), 30 | displayMessage: function() { 31 | // Don't display messages 32 | }, 33 | createView: function() { 34 | return true; 35 | }, 36 | /** 37 | * Automatically extract the numerical value of the first and second result row and 38 | * create the trend value according to their difference 39 | * 40 | * @param data the search results 41 | * @returns {*} the model object to for the template 42 | */ 43 | autoExtractTrend: function(data) { 44 | var icon = 'icon-minus', trendClass = 'nochange', diff = 'no change', field = this.settings.get('field'); 45 | // Only show the change if we get 2 results from the search 46 | if (data.length < 2) { 47 | return null; 48 | } 49 | var cur = parseFloat(data[0][field]), prev = parseFloat(data[1][field]); 50 | // Calculate the change percentage between the first and second result 51 | var changePct = parseInt(((cur - prev) / prev) * 100); 52 | if (cur > prev) { 53 | trendClass = 'increase'; 54 | icon = this.icons.increase; 55 | if (prev === 0) { 56 | trendClass += ' infinity'; 57 | diff = "+ ∞"; 58 | } else { 59 | diff = ['+', String(changePct), '%'].join(''); 60 | } 61 | } else if (cur < prev) { 62 | trendClass = 'decrease'; 63 | icon = this.icons.decrease; 64 | diff = [String(changePct), '%'].join(''); 65 | } 66 | return { 67 | icon: icon, 68 | trendClass: trendClass, 69 | diff: diff, 70 | prev: data[1][field] 71 | }; 72 | }, 73 | updateView: function(viz, data) { 74 | this.$el.empty(); 75 | var model = null; 76 | if (this.settings.has('changeField')) { 77 | var icon = 'icon-minus', trendClass = 'nochange', diff = 'no change', 78 | field = this.settings.get('field'), prev = "n/a"; 79 | switch (this.settings.get('changeFieldType')) { 80 | case 'percent': 81 | var v = parseInt(data[0][this.settings.get('changeField')], 10); 82 | if (v > 0) { 83 | trendClass = 'increase'; 84 | icon = this.icons.increase; 85 | diff = ['+', String(v), '%'].join(''); 86 | } else if (v < 0) { 87 | trendClass = 'decrease'; 88 | icon = this.icons.decrease; 89 | diff = [String(v), '%'].join(''); 90 | } 91 | break; 92 | default: 93 | diff = data[0][this.settings.get('changeField')]; 94 | trendClass = data[0][this.settings.get('trendClassField')]; 95 | icon = this.icons[trendClass]; 96 | } 97 | if (this.settings.has('prevField')) { 98 | prev = data[0][this.settings.get('prevField')]; 99 | } 100 | model = { 101 | icon: icon, 102 | trendClass: trendClass, 103 | diff: diff, 104 | prev: prev 105 | }; 106 | } else { 107 | model = this.autoExtractTrend(data); 108 | } 109 | if (!model) { 110 | return; 111 | } 112 | // Render the HTML 113 | this.$el.html(this.template(model)); 114 | } 115 | }); 116 | // Find all single value elements created on the dashboard 117 | _(mvc.Components.toJSON()).chain().filter(function(el) { 118 | return el instanceof SingleElement; 119 | }).each(function(singleElement) { 120 | singleElement.getVisualization(function(single) { 121 | // Inject a new element after the single value visualization 122 | var $el = $('
').insertAfter(single.$el); 123 | // Create a new change view to attach to the single value visualization 124 | new SingleValueTrendIndicator(_.extend(single.settings.toJSON(), { 125 | el: $el, 126 | id: _.uniqueId('single') 127 | })); 128 | }); 129 | }); 130 | }); 131 | -------------------------------------------------------------------------------- /tango/appserver/static/splIcons.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/appserver/static/splIcons.gif -------------------------------------------------------------------------------- /tango/bin/vt.py: -------------------------------------------------------------------------------- 1 | import requests 2 | import json 3 | import sys 4 | 5 | try: 6 | sha = sys.argv[1] 7 | requests.packages.urllib3.disable_warnings() 8 | url = "https://www.virustotal.com/vtapi/v2/file/report" 9 | params = { 10 | "resource": sha, 11 | "apikey": "" 12 | } 13 | r = requests.get(url, params=params, verify=False) 14 | j = json.loads(r.text) 15 | print "scan_date, shasum, vendors, signatures" 16 | print j['scan_date']+",",j['sha256']+",",j['positives'],",", 17 | for i in j['scans']: 18 | if j['scans'][i]['result'] == None: 19 | pass 20 | else: 21 | print j['scans'][i]['result'] + "|", 22 | 23 | except: 24 | print "Unknown," + sha + ",Unknown,Unknown" 25 | 26 | -------------------------------------------------------------------------------- /tango/default/app.conf: -------------------------------------------------------------------------------- 1 | ## Splunk app configuration file 2 | 3 | [install] 4 | is_configured = true 5 | state = enabled 6 | 7 | [launcher] 8 | author = Aplura, LLC 9 | version = 1.0 10 | description = This app provides insight and analysis of your honeypot log data. 11 | 12 | [ui] 13 | is_visible = true 14 | label = Tango Honeypot Intelligence 15 | 16 | -------------------------------------------------------------------------------- /tango/default/commands.conf: -------------------------------------------------------------------------------- 1 | [vt] 2 | type=python 3 | filename = vt.py 4 | generating = True 5 | streaming = False 6 | stderr_dest = message 7 | -------------------------------------------------------------------------------- /tango/default/data/ui/nav/default.xml: -------------------------------------------------------------------------------- 1 | 27 | -------------------------------------------------------------------------------- /tango/default/data/ui/views/attacker_overview.xml: -------------------------------------------------------------------------------- 1 |
2 | 3 | Provides general information on the amount of attacks seen recently. 4 |
5 | 6 | 7 | 8 | -12h 9 | now 10 | 11 | 12 |
13 | 14 | 15 | Provides statistics on the sources and locations of the attackers 16 |
17 | 18 | 19 | 20 | -12h@h 21 | now 22 | 23 | 24 |
25 |
26 | 27 | 28 | Daily Overview (vs. Yesterday) 29 | 30 | Successful Logins 31 | 32 | sourcetype=cowrie eventtype=login_success | timechart span=24h count | reverse 33 | -48h 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | Failed Logins 51 | 52 | sourcetype=cowrie eventtype=login_attempt | timechart span=24h count | reverse 53 | -48h 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | Distinct IP Addresses 71 | 72 | sourcetype=cowrie | timechart span=24h dc(src_ip) as count 73 | -48h 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | Files Downloaded 91 | 92 | sourcetype=cowrie shasum=* | timechart span=24h dc(shasum) as count 93 | -48h 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | Login Attempts vs Successes 114 | 115 | 116 | sourcetype=cowrie | timechart count by eventtype usenull=F | rename login_attempt AS "Login Attempt" login_success AS "Login Success" 117 | $field1.earliest$ 118 | $field1.latest$ 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | Latest Successful Logins 148 | 149 | 150 | sourcetype=cowrie | transaction session | search eventtype=login_success | iplocation prefix=iploc_ allfields=true src_ip | table src_ip, iploc_Country, _time| fields - percent | eval src_ip_country_name = if(isnull(iploc_Country),"Unknown",iploc_Country) | eval Time=strftime(_time,"%m/%d/%y %H:%M:%S") | rename src_ip AS "Source IP" count as "Count" src_ip_country_name AS "Country" Time AS "Login Time" iploc_Country AS "Country"| fields - _time | sort 10 - "Login Time" 151 | $field1.earliest$ 152 | $field1.latest$ 153 | 154 | 155 | 156 | 157 | 158 | 159 |
160 |
161 | 162 | Attackers Logging Into Multiple Sensors 163 | 164 | 165 | sourcetype=cowrie | transaction session | search eventtype=login_success | stats dc(host) AS count, values(host) AS Sensors by src_ip | where count > 1 | sort 10 -count | rename src_ip AS "Attacker IP" | fields - count | rename "Sensors" AS "Sensors Logged Into" 166 | $field1.earliest$ 167 | $field1.latest$ 168 | 169 | 170 | 171 | 172 | 173 | 174 |
175 |
176 |
177 | -------------------------------------------------------------------------------- /tango/default/data/ui/views/attacker_profile.xml: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | 6 | 7 | -24h@h 8 | now 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | Attacker Location 18 | 19 | 20 | src_ip=$ipaddress$| iplocation prefix=iploc_ allfields=true src_ip | table iploc_* | fields - iploc_Continent iploc_MetroCode | dedup iploc_City | rename iploc_City AS "City" iploc_Country AS "Country" iploc_Region AS "Region" iploc_Timezone AS "Timezone" iploc_lat AS "Latitude" iploc_lon AS "Longitude" | eval City = if(isnull(City) OR City="", "Unknown", City) | eval Country = if(isnull(Country) OR Country="", "Unknown", Country) | eval Region = if(isnull(Region) OR Region="", "Unknown", Region) 21 | $field2.earliest$ 22 | $field2.latest$ 23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 |
31 |
32 | 33 | 34 | 35 | 36 | src_ip=$ipaddress$ | fields src_ip | iplocation prefix=iploc_ allfields=true src_ip | dedup src_ip | geostats latfield=iploc_lat longfield=iploc_lon count by src_ip 37 | $field2.earliest$ 38 | $field2.latest$ 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | Times Attacker Seen 56 | 57 | Earliest Time Seen 58 | 59 | sourcetype=cowrie [ search sourcetype=cowrie src_ip=$ipaddress$ | stats count by session | fields session ] | transaction session | stats earliest(_time) as Time | eval Time=strftime(Time,"%m/%d/%y %H:%M:%S") 60 | 0 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | Latest Time Seen 77 | 78 | sourcetype=cowrie [ search sourcetype=cowrie src_ip=$ipaddress$ | stats count by session | fields session ] | transaction session | stats latest(_time) as Time | eval Time=strftime(Time,"%m/%d/%y %H:%M:%S") 79 | 0 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | SSH Clients Seen 97 | 98 | 99 | sourcetype=cowrie [ search sourcetype=cowrie src_ip=$ipaddress$ | stats count by session | fields session ] | transaction session | stats count by version | rename version AS "SSH Client" | fields - count 100 | 0 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 |
109 |
110 |
111 | 112 | 113 | Sessions with Interaction 114 | 115 | 116 | sourcetype=cowrie [ search sourcetype=cowrie eventtype=login_success | stats count by session | fields session ] | transaction session| search src_ip=$ipaddress$ | stats count(input) as count by session | where count > 1 | fields - count | rename session as "Session" 117 | $field2.earliest$ 118 | $field2.latest$ 119 | 120 | 121 | 122 | 123 | 125 | $row.Session$ 126 | 127 | $row.Session$ 128 | 129 | 130 | 131 | 132 | 133 |
134 |
135 |
136 | 137 | 138 | Session Playlog 139 | 140 | Session: $session$ 141 | 142 | sourcetype=cowrie session=$session$ input=* | table input, timestamp | rename input AS "Command" timestamp AS "Timestamp" | sort +"Timestamp" 143 | $field2.earliest$ 144 | $field2.latest$ 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 |
180 |
181 |
182 | 183 | 184 | Files Downloaded 185 | 186 | 187 | sourcetype=cowrie [ search sourcetype=cowrie shasum=* | stats count by session | fields session ] | transaction session | search src_ip=$ipaddress$ | table url, shasum | dedup shasum | lookup virustotal.csv "SHA256 Hash" AS shasum OUTPUT "Vendor Signatures" | rename url AS "URL" shasum AS "SHA256 Hash" | makemv delim="|" "Vendor Signatures" | fillnull value="Unknown" 188 | $field2.earliest$ 189 | $field2.latest$ 190 | 191 | 192 | 193 | 194 | 195 | 196 |
197 |
198 |
199 |
-------------------------------------------------------------------------------- /tango/default/data/ui/views/attacker_session_analysis.xml: -------------------------------------------------------------------------------- 1 |
2 | 3 | This dashboard provides insights into the various details about the attacker sessions 4 |
5 | 6 | 7 | 8 | -12h@h 9 | now 10 | 11 | 12 |
13 | 14 | 15 | Human vs. Bot Identification (Best Guess) 16 | 17 | 18 | sourcetype=cowrie version=* | eval identification=if(searchmatch("version=*openssh*"),"Human","Bot") | stats count by identification 19 | $field1.earliest$ 20 | $field1.latest$ 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | SSH Versions 50 | 51 | 52 | sourcetype=cowrie | stats count by version | rename version AS "Attacker SSH Versions" | sort - count 53 | $field1.earliest$ 54 | $field1.latest$ 55 | 56 | 57 | 58 | 59 | 60 | 61 |
62 |
63 |
64 | 65 | 66 | Environment Details 67 | 68 | 69 | sourcetype=cowrie | stats count by terminal_size | rename terminal_size AS "Session Environment Details" 70 | $field1.earliest$ 71 | $field1.latest$ 72 | 73 | 74 | 75 | 76 | 77 | 78 |
79 |
80 | 81 | Sessions with Command Interaction 82 | 83 | 84 | sourcetype=cowrie input=* | stats dc(session) AS dcount | appendcols [search sourcetype=cowrie | stats dc(session) AS ddcount] | eval total=(dcount/ddcount*100) | fields - dcount ddcount | eval total=round(total,2) 85 | $field1.earliest$ 86 | $field1.latest$ 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 |
103 | 104 | 105 | Top Commands Entered During Session 106 | 107 | 108 | sourcetype=cowrie | top input | fields - percent | rename input AS "Command Entered" 109 | $field1.earliest$ 110 | $field1.latest$ 111 | 112 | 113 | 114 | 115 | 116 | 117 |
118 |
119 | 120 | Rare Commands Entered During Session 121 | 122 | 123 | sourcetype=cowrie | rare input | fields - percent | rename input AS "Command Entered" 124 | $field1.earliest$ 125 | $field1.latest$ 126 | 127 | 128 | 129 | 130 | 131 | 132 |
133 |
134 |
135 |
-------------------------------------------------------------------------------- /tango/default/data/ui/views/edit_sensor.xml: -------------------------------------------------------------------------------- 1 |
2 | 3 | In this dashboard, you are able to add in additional sensor information, such as the owner and owners email. 4 |
5 | 6 | 7 | 8 | sourcetype=sensor | stats count by host | fields - count 9 | -24h@h 10 | now 11 | 12 | host 13 | host 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | Updated Sensor Information 28 | 29 | 30 | |stats count | eval "Sensor Name"="$sensor$" | eval "Owner"="$owner$" | eval "Owner Email"="$owner_email$" | eval Comment="$comment$" | fields - count | inputlookup sensors.csv append=true | stats first(ASN) AS "ASN" first("ASN Country") AS "ASN Country" first("Last Active") AS "Last Active" first("Network Name") AS "Network Name" first("Network Range") AS "Network Range" first("Sensor IP Address") AS "Sensor IP Address" first("Owner") AS "Owner" first("Owner Email") AS "Owner Email" first(Comment) AS "Comment" by "Sensor Name" | outputlookup sensors.csv 31 | 0 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |
47 |
48 |
49 |
-------------------------------------------------------------------------------- /tango/default/data/ui/views/file_analysis.xml: -------------------------------------------------------------------------------- 1 |
2 | 3 | Provides insights into the potential Malware downloaded on the Honeypots 4 |
5 | 6 | 7 | 8 | -12h@h 9 | now 10 | 11 | 12 |
13 | 14 | 15 | Latest Files Downloaded 16 | 17 | 18 | sourcetype=cowrie [ search sourcetype=cowrie shasum=* | stats count by session | fields session ] | transaction session | table url, shasum, src_ip, host, session, _time | rename url AS "URL" shasum AS "SHA256 Hash" host AS "Sensor" session AS "Session" _time AS "Timestamp" src_ip AS "Attacker IP"| eval Time=strftime(Timestamp,"%m/%d/%y %H:%M:%S") | fields - Timestamp 19 | $field1.earliest$ 20 | $field1.latest$ 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 |
30 | 31 | 32 | Latest Attempted File Downloads 33 | 34 | 35 | sourcetype=cowrie [search sourcetype=cowrie attempted_url=* | stats count by session | fields session ] | transaction session | search NOT shasum=* | table attempted_url,src_ip, host, session, _time | rename url AS "URL" shasum AS "SHA256 Hash" host AS "Sensor" session AS "Session" _time AS "Timestamp" attempted_url AS "URL" src_ip AS "Attacker IP" | eval Time=strftime(Timestamp,"%m/%d/%y %H:%M:%S") | fields - Timestamp 36 | $field1.earliest$ 37 | $field1.latest$ 38 | 39 | 40 | 41 | 42 | 43 | 44 |
45 |
46 |
47 | 48 | 49 | VirusTotal SHA Lookup 50 | 51 | 52 | 53 | sourcetype=kippojson shasum=* | table shasum | dedup shasum 54 | $field1.earliest$ 55 | $field1.latest$ 56 | 57 | shasum 58 | shasum 59 | 60 | 61 | 62 | | vt $shasums$ | makemv delim="|" signatures | table scan_date, shasum, vendors, signatures | rename scan_date AS "Date Scanned", shasum AS "SHA256 Hash" vendors AS "Vendors Identified" signatures AS "Vendor Signatures" | fillnull value="Unknown" | outputlookup append=true virustotal.csv 63 | $field1.earliest$ 64 | $field1.latest$ 65 | 66 | 67 | 68 | 69 | 70 | 71 |
72 |
73 |
74 |
-------------------------------------------------------------------------------- /tango/default/data/ui/views/ioc_feed.xml: -------------------------------------------------------------------------------- 1 |
2 | 3 | Provides the Indicators of Compromise (IOC) for C2 IP Addresses, File Hashes, File Names, etc. 4 |
5 | 6 | 7 | 8 | -24h@h 9 | now 10 | 11 | 12 |
13 | 14 | 15 | Indicator Count 16 | 17 | 18 | sourcetype=cowrie | stats dc(src_ip) AS count 19 | $field1.earliest$ 20 | $field1.latest$ 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | sourcetype=cowrie | stats dc(attempted_url) 42 | $field1.earliest$ 43 | $field1.latest$ 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | sourcetype=cowrie | stats dc(shasum) 65 | $field1.earliest$ 66 | $field1.latest$ 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | sourcetype=cowrie | stats dc(domain) 84 | $field1.earliest$ 85 | $field1.latest$ 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | sourcetype=cowrie | stats dc(filename) 103 | $field1.earliest$ 104 | $field1.latest$ 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | IP Addresses 124 | 125 | 126 | sourcetype=cowrie | stats count by src_ip | fields src_ip | rename src_ip AS "IP Address" 127 | $field1.earliest$ 128 | $field1.latest$ 129 | 130 | 131 | 132 | 133 | 134 | 135 |
136 |
137 | 138 | Potentially Malicious URLs 139 | 140 | 141 | sourcetype=cowrie | stats count by attempted_url | fields attempted_url | rename attempted_url AS "URL" 142 | $field1.earliest$ 143 | $field1.latest$ 144 | 145 | 146 | 147 | 148 | 149 | 150 |
151 |
152 |
153 | 154 | 155 | SHA File Hashes 156 | 157 | 158 | sourcetype=cowrie | stats count by shasum | fields shasum | rename shasum AS "SHA Hash" 159 | $field1.earliest$ 160 | $field1.latest$ 161 | 162 | 163 | 164 | 165 | 166 | 167 |
168 |
169 | 170 | Potentially Malicious Domains 171 | 172 | 173 | sourcetype=cowrie | stats count by domain | fields domain | rename domain AS "Domain" 174 | $field1.earliest$ 175 | $field1.latest$ 176 | 177 | 178 | 179 | 180 | 181 | 182 |
183 |
184 |
185 | 186 | 187 | File Names 188 | 189 | 190 | sourcetype=cowrie filename=* | stats count by filename | fields filename | rename filename AS "Filename" 191 | $field1.earliest$ 192 | $field1.latest$ 193 | 194 | 195 | 196 | 197 | 198 | 199 |
200 |
201 |
202 |
-------------------------------------------------------------------------------- /tango/default/data/ui/views/location_overview.xml: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | 6 | 7 | -12h@h 8 | now 9 | 10 | 11 |
12 | 13 | 14 | Top Countries w/ Login 15 | 16 | 17 | sourcetype=cowrie | transaction session | search eventtype=login_success | iplocation prefix=iploc_ allfields=true src_ip | top iploc_Country limit=5 18 | $field1.earliest$ 19 | $field1.latest$ 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | Top Country Scanning 49 | 50 | 51 | sourcetype=cowrie | transaction session | iplocation prefix=iploc_ allfields=true src_ip | top iploc_Country limit=5 52 | $field1.earliest$ 53 | $field1.latest$ 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | Top Sensors Attacked 83 | 84 | 85 | sourcetype=cowrie eventtype=login_success | stats count by host | head 5 86 | $field1.earliest$ 87 | $field1.latest$ 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | Attacker Location Map 119 | 120 | 121 | sourcetype=cowrie | stats count by src_ip | fields src_ip | iplocation prefix=iploc_ allfields=true src_ip | geostats latfield=iploc_lat longfield=iploc_lon count by src_ip 122 | $field1.earliest$ 123 | $field1.latest$ 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 |
-------------------------------------------------------------------------------- /tango/default/data/ui/views/malware_analysis.xml: -------------------------------------------------------------------------------- 1 |
2 | 3 | Provides information on legitimate malware files seen as well as files that are possible malware. 4 |
5 | 6 | 7 | 8 | -12h 9 | now 10 | 11 | 12 |
13 | 14 | 15 | Top 10 Malware Signatures Seen Over Time 16 | 17 | 18 | | inputlookup virustotal.csv | dedup "SHA256 Hash" | makemv delim="|" "Vendor Signatures" | mvexpand "Vendor Signatures" | top "Vendor Signatures" | fields - percent 19 | $field1.earliest$ 20 | $field1.latest$ 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | Legitimate Malware Seen 50 | 51 | 52 | sourcetype=cowrie shasum=* | table shasum, url, session | lookup virustotal.csv "SHA256 Hash" as shasum OUTPUT "Vendor Signatures" | search "Vendor Signatures"!="Unknown" | makemv delim="|" "Vendor Signatures" | mvexpand "Vendor Signatures" | stats values(shasum) AS "SHA256 Hash" values("Vendor Signatures") AS "Vendor Signatures" values(session) AS "Session" by url | rename url AS "URL" 53 | $field1.earliest$ 54 | $field1.latest$ 55 | 56 | 57 | 58 | 59 | 60 | 61 |
62 |
63 |
64 | 65 | 66 | Potential Malware Files (Produced No Results in VirusTotal) 67 | 68 | 69 | sourcetype=cowrie [ | inputlookup virustotal.csv | search "Vendors Identified"=Unknown OR "Vendors Identified"=0 | fields "SHA256 Hash" | rename "SHA256 Hash" AS shasum] | stats values(url) AS "URL", values(session) AS "Session" by shasum | rename shasum AS "SHA256 Hash" 70 | $field1.earliest$ 71 | $field1.latest$ 72 | 73 | 74 | 75 | 76 | 77 | 78 |
79 |
80 |
81 |
-------------------------------------------------------------------------------- /tango/default/data/ui/views/malware_campaigns.xml: -------------------------------------------------------------------------------- 1 |
2 | 3 | Lists URL's, Domains, Filenames and SHA hashes that have been seen in multiple sessions. 4 |
5 | 6 | 7 | 8 | -12h@h 9 | now 10 | 11 | 12 |
13 | 14 | 15 | Potential Malware Campaigns (By URL) 16 | 17 | 18 | sourcetype=cowrie [search sourcetype=cowrie url=* | stats count by session | fields session ] | transaction session | stats dc(src_ip) AS Count values(session) AS "Session" values(src_ip) as "Attacker IP" by url | where Count > 1| rename url AS "URL" | sort - Count | fields - Count 19 | $field1.earliest$ 20 | $field1.latest$ 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 | 30 | Potential Malware Campaigns (By Domain) 31 | 32 | 33 | sourcetype=cowrie [ search sourcetype=cowrie domain=* | stats count by session | fields session ] | transaction session | stats dc(src_ip) AS Count values(session) AS "Session" values(src_ip) as "Attacker IP" by domain | where Count > 1| rename domain AS "Domain" | sort - Count | fields - Count 34 | $field1.earliest$ 35 | $field1.latest$ 36 | 37 | 38 | 39 | 40 | 41 | 42 |
43 |
44 |
45 | 46 | 47 | Potential Malware Campaigns (By Filename) 48 | 49 | 50 | sourcetype=cowrie [search sourcetype=cowrie filename=* | stats count by session | fields session ] | transaction session | stats dc(src_ip) AS Count values(src_ip) as "Attacker IP" values(session) AS "Session" values(url) AS "URL" by filename | where Count > 1| rename filename AS "File Downloaded" | sort - Count | fields - Count 51 | $field1.earliest$ 52 | $field1.latest$ 53 | 54 | 55 | 56 | 57 | 58 | 59 |
60 |
61 | 62 | Potential Malware Campaings (By SHA Hash) 63 | 64 | 65 | sourcetype=cowrie [search sourcetype=cowrie shasum=* | stats count by session | fields session ] | transaction session | stats dc(src_ip) AS Count values(src_ip) as "Attacker IP" values(session) AS "Session" values(url) AS "URL" by shasum | where Count > 1| rename shasum AS "SHA256 Hash" | sort - Count | fields - Count 66 | $field1.earliest$ 67 | $field1.latest$ 68 | 69 | 70 | 71 | 72 | 73 | 74 |
75 |
76 |
77 |
-------------------------------------------------------------------------------- /tango/default/data/ui/views/network_analysis.xml: -------------------------------------------------------------------------------- 1 |
2 | 3 | Gives analytics on the Domains, IP's, URI's, URL's seen on the Honeypots 4 |
5 | 6 | 7 | 8 | -12h 9 | now 10 | 11 | 12 |
13 | 14 | 15 | Top Domains Seen 16 | 17 | 18 | sourcetype=cowrie | top domain | fields - percent | rename domain AS "Domain" count AS "Count" 19 | $field1.earliest$ 20 | $field1.latest$ 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 | 30 | Same URI on Multiple Domains 31 | 32 | 33 | sourcetype=cowrie | stats dc(domain) as Count values(domain) as domain by uri | where Count > 1 | sort - Count | fields - Count 34 | $field1.earliest$ 35 | $field1.latest$ 36 | 37 | 38 | 39 | 40 | 41 | 42 |
43 |
44 |
45 | 46 | 47 | Latest IP Addresses Seen 48 | 49 | 50 | sourcetype=cowrie | transaction session | search ip=* | table ip, command, session, src_ip, _time | rename ip AS "IP Address" session AS "Session" src_ip AS "Attacker IP", _time AS "Time", command AS "Command" | eval Time=strftime(Time,"%m/%d/%y %H:%M:%S") | sort - Time 51 | $field1.earliest$ 52 | $field1.latest$ 53 | 54 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |
62 |
-------------------------------------------------------------------------------- /tango/default/data/ui/views/password_analysis.xml: -------------------------------------------------------------------------------- 1 |
2 | 3 | Provides detailed statistics and analysis of usernames and passwords attempted by attackers 4 |
5 | 6 | 7 | 8 | -24h@h 9 | now 10 | 11 | 12 |
13 | 14 | 15 | Top 10 Usernames 16 | 17 | 18 | sourcetype=cowrie username=* | top username | rename username AS "Username" count AS "Count" | fields - percent 19 | $field1.earliest$ 20 | $field1.latest$ 21 | 22 | 23 | 24 | 25 | 26 | 27 |
28 |
29 | 30 | Top 10 Passwords 31 | 32 | 33 | sourcetype=cowrie password=* | top password | rename password AS "Password" count AS "Count" | fields - percent 34 | $field1.earliest$ 35 | $field1.latest$ 36 | 37 | 38 | 39 | 40 | 41 | 42 |
43 |
44 |
45 | 46 | 47 | Top Username/Password Combinations 48 | 49 | 50 | sourcetype=cowrie login_combo=* | top login_combo | rename login_combo AS "Username/Password Combination" count AS "Count" | fields - percent 51 | $field1.earliest$ 52 | $field1.latest$ 53 | 54 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |
62 |
-------------------------------------------------------------------------------- /tango/default/data/ui/views/sensor_status.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Provides information on each Tango Sensor 4 | 5 | 6 | Sensor Information 7 | 8 | 9 | | inputlookup sensors.csv | stats first(ASN) AS "ASN" first("ASN Country") AS "Country" first("Last Active") AS Time first("Network Name") AS "Network Name" first("Sensor IP Address") AS "Sensor IP Address" first("Owner") AS "Owner" first("Owner Email") AS "Owner Email" first("Comment") AS "Comment" by "Sensor Name" | eval Time=strftime(Time,"%m/%d/%y %H:%M:%S") | rename Time as "Last Active" 10 | -24h@h 11 | now 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 |
21 | 22 | 23 | Sensor Location 24 | 25 | 26 | sourcetype=sensor | stats count by sensorIP | fields sensorIP | iplocation prefix=iploc_ allfields=true sensorIP | geostats latfield=iploc_lat longfield=iploc_lon count by sensorIP 27 | -24h@h 28 | now 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |
-------------------------------------------------------------------------------- /tango/default/data/ui/views/session_overview.xml: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 5 | 6 | 7 | -12h 8 | now 9 | 10 | 11 |
12 | 13 | 14 | Sessions with Interaction 15 | 16 | 17 | 18 | sourcetype=kippojson command=* | table host | dedup host 19 | -7d@h 20 | now 21 | 22 | host 23 | host 24 | All 25 | * 26 | 27 | 28 | 29 | sourcetype=cowrie host=$sensor$ | stats earliest(_time) as Time, values(src_ip) AS "Attacker IP", values(host) as "Sensor", count(input) as msgcount by session | where msgcount > 1 | eval Time=strftime(Time,"%m/%d/%y %H:%M:%S") | rename msgcount AS "Message Count" session AS "Session"| sort - Time 30 | $field1.earliest$ 31 | $field1.latest$ 32 | 33 | 34 | 35 | 36 | 38 | $row.Session$ 39 | 40 | $row.Session$ 41 | 42 | 43 | 44 | 45 | 46 |
47 |
48 |
49 | 50 | 51 | Session Time 52 | 53 | 54 | sourcetype=cowrie session=$session$ | transaction session | rename _time as starttime | eval starttime=strftime(starttime,"%m/%d/%y %H:%M:%S") | table starttime 55 | $field1.earliest$ 56 | $field1.latest$ 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | sourcetype=cowrie session=$session$ | transaction session | eval starttime=_time | eval endtime=_time+duration | eval starttime=strftime(starttime,"%m/%d/%y %H:%M:%S") | eval endtime=strftime(endtime,"%m/%d/%y %H:%M:%S") | table endtime 78 | $field1.earliest$ 79 | $field1.latest$ 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | sourcetype=cowrie session=$session$ | transaction session | table duration | eval duration=round(duration/60,2) 101 | $field1.earliest$ 102 | $field1.latest$ 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | Passwords Accepted 122 | 123 | 124 | sourcetype=cowrie session=$session$ eventtype=login_success | table password | rename password AS "Password Accepted" 125 | $field1.earliest$ 126 | $field1.latest$ 127 | 128 | 129 | 130 | 131 | 132 | 133 |
134 |
135 | 136 | Passwords Attempted 137 | 138 | 139 | sourcetype=cowrie session=$session$ eventtype=login_attempt | table password | rename password AS "Password Attempted" 140 | $field1.earliest$ 141 | $field1.latest$ 142 | 143 | 144 | 145 | 146 | 147 | 148 |
149 |
150 |
151 | 152 | 153 | Commands Entered During Session 154 | 155 | Session: $session$ 156 | 157 | sourcetype=cowrie session=$session$ input=* | table input, timestamp | rename input AS "Command" timestamp AS "Timestamp" 158 | 0 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 |
195 |
196 |
197 | 198 | 199 | Files Downloaded During Session 200 | 201 | 202 | sourcetype=cowrie [ search sourcetype=cowrie shasum=* session=$session$ | stats count by session | fields session ] | transaction session | table url, shasum | dedup shasum | lookup virustotal.csv "SHA256 Hash" AS shasum OUTPUT "Vendor Signatures" | makemv delim="|" "Vendor Signatures" |fillnull value="Unknown" "Vendor Signatures"| mvexpand "Vendor Signatures" | dedup "Vendor Signatures" | stats values(url) AS "URL" values(shasum) AS "SHA256 Hash" values("Vendor Signatures") AS "Vendor Signatures" 203 | $field1.earliest$ 204 | $field1.latest$ 205 | 206 | 207 | 208 | 209 | 210 | 211 |
212 |
213 |
214 | 215 | 216 | Raw Session Log 217 | 218 | 219 | sourcetype=cowrie session=$session$ | table _raw | sort + _time | rename _raw AS "Raw Logs" 220 | $field1.earliest$ 221 | $field1.latest$ 222 | 223 | 224 | 225 | 226 | 227 | 228 |
229 |
230 |
231 |
-------------------------------------------------------------------------------- /tango/default/eventtypes.conf: -------------------------------------------------------------------------------- 1 | [login_success] 2 | priority=1 3 | search = sourcetype=cowrie "login attempt" "succeeded" 4 | 5 | [login_attempt] 6 | priority=1 7 | search = sourcetype=cowrie "login attempt" "failed" 8 | -------------------------------------------------------------------------------- /tango/default/indexes.conf: -------------------------------------------------------------------------------- 1 | [honeypot] 2 | homePath = $SPLUNK_DB/honeypot/db 3 | coldPath = $SPLUNK_DB/honeypot/colddb 4 | thawedPath = $SPLUNK_DB/honeypot/thaweddb 5 | -------------------------------------------------------------------------------- /tango/default/props.conf: -------------------------------------------------------------------------------- 1 | [cowrie] 2 | NO_BINARY_CHECK = true 3 | category = Custom 4 | disabled = false 5 | pulldown_type = true 6 | KV_MODE = JSON 7 | REPORT-JSON_EXTRACTS = extract_terminal_size, extract_domain, extract_IP, extract_command, extract_url, extract_uri, extract_filename, extract_login_combo 8 | SHOULD_LINEMERGE = false 9 | LINE_BREAKER = ([\r\n]+){ 10 | TRUNCATE=5000 11 | EVAL-terminal_size = width."x".height 12 | EVAL-login_combo = username."/".password 13 | -------------------------------------------------------------------------------- /tango/default/savedsearches.conf: -------------------------------------------------------------------------------- 1 | [Populate_sensor_lookup] 2 | alert.digest_mode = True 3 | alert.suppress = 0 4 | alert.track = 0 5 | auto_summarize.dispatch.earliest_time = -1d@h 6 | counttype = number of events 7 | cron_schedule = 5 * * * * 8 | description = Populates the sensors lookup table with any new sensors seen 9 | dispatch.earliest_time = -1d@d 10 | dispatch.latest_time = @d 11 | enableSched = 1 12 | quantity = 0 13 | relation = less than 14 | search = sourcetype=sensor | dedup host | table _time host sensorIP ASN ASN_Country description network_name network_range | rename _time as "Last Active" host as "Sensor Name" sensorIP as "Sensor IP Address" ASN_Country as "ASN Country" network_name as "Network Name" network_range as "Network Range" | inputlookup sensors.csv append=true | stats first(ASN) as ASN first("ASN Country") as "ASN Country" first("Last Active") as "Last Active" first("Network Name") as "Network Name" first("Network Range") as "Network Range" first("Sensor IP Address") as "Sensor IP Address" first("Owner") as Owner first("Owner Email") as "Owner Email" first("Comment") as "Comment" by "Sensor Name" | outputlookup sensors.csv 15 | -------------------------------------------------------------------------------- /tango/default/transforms.conf: -------------------------------------------------------------------------------- 1 | [extract_terminal_size] 2 | REGEX = Terminal\ssize:\s(?.*) 3 | SOURCE_KEY = message 4 | 5 | [extract_command] 6 | REGEX = "command":\s+"(?.*)",\s+ 7 | 8 | [extract_url] 9 | SOURCE_KEY = input 10 | REGEX = (?https?://[^\s|\>|\)|\*|\"|\;|&|\'\`]*) 11 | MV_ADD = TRUE 12 | 13 | [extract_domain] 14 | SOURCE_KEY = input 15 | REGEX = (?https?://[^//]*) 16 | 17 | [extract_IP] 18 | REGEX = (?\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) 19 | SOURCE_KEY = input 20 | MV_ADD = true 21 | 22 | [extract_uri] 23 | REGEX = https?://[^/]+(?/.*) 24 | SOURCE_KEY = input 25 | 26 | [extract_filename] 27 | REGEX = https?://.+(?/[^\r\n]+) 28 | SOURCE_KEY = input 29 | 30 | [extract_login_combo] 31 | REGEX = Login\sfailed\s\[(?[^\]\r|\n]+) 32 | -------------------------------------------------------------------------------- /tango/lookups/sensors.csv: -------------------------------------------------------------------------------- 1 | "Sensor Name",ASN,"ASN Country","Last Active","Network Name","Network Range","Sensor IP Address",Owner,"Owner Email",Comment 2 | ,,,,,,,,, 3 | -------------------------------------------------------------------------------- /tango/lookups/virustotal.csv: -------------------------------------------------------------------------------- 1 | "Date Scanned","SHA256 Hash","Vendors Identified","Vendor Signatures" 2 | ,,, 3 | -------------------------------------------------------------------------------- /tango/metadata/default.meta: -------------------------------------------------------------------------------- 1 | [] 2 | access = read : [ * ], write : [ admin, power ] 3 | export = none 4 | 5 | [tags] 6 | export = system 7 | 8 | [props] 9 | export = system 10 | 11 | [transforms] 12 | export = system 13 | 14 | [lookups] 15 | export = system 16 | 17 | [viewstates] 18 | access = read : [ * ], write : [ * ] 19 | export = system 20 | -------------------------------------------------------------------------------- /tango/metadata/local.meta: -------------------------------------------------------------------------------- 1 | [app/ui] 2 | version = 6.2.0 3 | modtime = 1423169402.439322000 4 | 5 | [app/launcher] 6 | version = 6.2.0 7 | modtime = 1423169402.443881000 8 | 9 | [views/attacker_overview] 10 | owner = admin 11 | version = 6.2.0 12 | modtime = 1425832786.986144000 13 | 14 | [views/session_overview] 15 | owner = admin 16 | version = 6.2.0 17 | modtime = 1425997396.044104000 18 | 19 | [views/sensor_status] 20 | owner = admin 21 | version = 6.2.0 22 | modtime = 1425907244.237153000 23 | 24 | [eventtypes/login_success] 25 | export = system 26 | owner = admin 27 | version = 6.2.0 28 | modtime = 1423171995.804361000 29 | 30 | [eventtypes/login_attempt] 31 | export = system 32 | owner = admin 33 | version = 6.2.0 34 | modtime = 1423236165.068729000 35 | 36 | [] 37 | access = read : [ * ], write : [ admin, power ] 38 | export = system 39 | version = 6.2.0 40 | modtime = 1423258170.674361000 41 | 42 | [views/attacker_session_analysis] 43 | owner = admin 44 | version = 6.2.0 45 | modtime = 1425316905.735096000 46 | 47 | [views/ioc_feed] 48 | owner = admin 49 | version = 6.2.0 50 | modtime = 1425334513.209830000 51 | 52 | [views/location_overview] 53 | owner = admin 54 | version = 6.2.0 55 | modtime = 1425755103.852408000 56 | 57 | [views/malware_campaigns] 58 | owner = admin 59 | version = 6.2.0 60 | modtime = 1425333869.087322000 61 | 62 | [views/network_analysis] 63 | owner = admin 64 | version = 6.2.0 65 | modtime = 1425323073.766801000 66 | 67 | [lookups/virustotal.csv] 68 | export = system 69 | owner = admin 70 | version = 6.2.0 71 | modtime = 1424468625.545050000 72 | 73 | [views/password_analysis] 74 | export = system 75 | owner = admin 76 | version = 6.2.0 77 | modtime = 1425322871.182431000 78 | 79 | [views/file_analysis] 80 | owner = admin 81 | version = 6.2.0 82 | modtime = 1425322895.887983000 83 | 84 | [views/attacker_profile] 85 | owner = admin 86 | version = 6.2.0 87 | modtime = 1425997569.192176000 88 | 89 | [lookups/sensors.csv] 90 | access = read : [ * ], write : [ admin ] 91 | export = none 92 | owner = admin 93 | version = 6.2.0 94 | modtime = 1425657749.932432000 95 | 96 | [views/edit_sensor] 97 | owner = admin 98 | version = 6.2.2 99 | modtime = 1425681837.113060000 100 | 101 | [savedsearches/Populate_sensor_lookup] 102 | access = read : [ * ], write : [ admin ] 103 | export = none 104 | owner = admin 105 | version = 6.2.0 106 | modtime = 1425755740.980648000 107 | -------------------------------------------------------------------------------- /tango/static/appIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/static/appIcon.png -------------------------------------------------------------------------------- /tango/static/appIconAlt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/static/appIconAlt.png -------------------------------------------------------------------------------- /tango/static/appIconAlt_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/static/appIconAlt_2x.png -------------------------------------------------------------------------------- /tango/static/appIcon_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aplura/Tango/38aa3f8cd35f3cf05e6dcfc10c0d068b03e38778/tango/static/appIcon_2x.png -------------------------------------------------------------------------------- /tango_input/bin/input.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from ipwhois import IPWhois 3 | 4 | r = requests.get('http://ipv4.icanhazip.com') 5 | 6 | ip = r.text 7 | 8 | ip = ip.rstrip() 9 | obj = IPWhois(ip) 10 | results = obj.lookup_whois() 11 | print "sensorIP="+str(ip)+", ASN="+str(results['asn'])+", ASN_Country="+str(results['asn_country_code'])+", description="+str(results['nets'][0]['description']) + ", network_name="+str(results['nets'][0]['name'])+", network_range="+str(results['nets'][0]['range']) 12 | -------------------------------------------------------------------------------- /tango_input/bin/input.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | unset LD_LIBRARY_PATH 3 | python /opt/splunkforwarder/etc/apps/tango_input/bin/input.py 4 | -------------------------------------------------------------------------------- /tango_input/default/app.conf: -------------------------------------------------------------------------------- 1 | [install] 2 | is_configured = true 3 | state = enabled 4 | 5 | [launcher] 6 | author=Aplura LLC 7 | 8 | [ui] 9 | is_visible=false 10 | -------------------------------------------------------------------------------- /tango_input/default/inputs.conf: -------------------------------------------------------------------------------- 1 | [monitor:///opt/cowrie/log/cowrie.json*] 2 | disabled = false 3 | index = honeypot 4 | sourcetype = cowrie 5 | host = test 6 | 7 | [script://./bin/input.sh] 8 | disabled=false 9 | sourcetype=sensor 10 | index=honeypot 11 | interval=86400 12 | host = test 13 | -------------------------------------------------------------------------------- /tango_input/default/outputs.conf: -------------------------------------------------------------------------------- 1 | [tcpout] 2 | defaultGroup = default-autolb-group 3 | 4 | [tcpout:default-autolb-group] 5 | server = test 6 | 7 | [tcpout-server://test] 8 | -------------------------------------------------------------------------------- /uf_only.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #Universal Forwarder Install Only for Tango Honeypot 3 | #Should be compatible with Ubuntu and Debian. 4 | 5 | #Disclaimer. Continues for yes, quits for no. 6 | while true; do 7 | read -p "[!] You are about to install Cowrie and the Splunk Universal Forwarder. By running this installer, you accept Splunk's EULA. Do you wish to proceed? (Yes/No)" yn 8 | case $yn in 9 | [Yy]* ) break;; 10 | [Nn]* ) exit;; 11 | * ) echo "Please answer Yes or No.";; 12 | esac 13 | done 14 | 15 | ######################################## 16 | 17 | #User input variables 18 | #Splunk Indexer hostname/IP address from user 19 | read -e -p "[?] Enter the Splunk Indexer to forward logs to: (example: splunk.test.com:9997) " SPLUNK_INDEXER 20 | 21 | #Sensor hostname from user 22 | read -e -p "[?] Enter Sensor name: (example: hp-US-Las_Vegas-01) " HOST_NAME 23 | 24 | #Kippo Logs 25 | read -e -p "[?] Enter the full path to where your Cowrie logs are stored: (example:/opt/cowrie/log/) " KIPPO_LOG_LOCATION 26 | 27 | ######################################## 28 | 29 | 30 | 31 | # Logging setup. This is done to log all the output from commands executed in the script to a file. This provides us troubleshooting data if the script fails. 32 | logfile=/var/log/tango_install.log 33 | mkfifo ${logfile}.pipe 34 | tee < ${logfile}.pipe $logfile & 35 | exec &> ${logfile}.pipe 36 | rm ${logfile}.pipe 37 | 38 | ######################################## 39 | 40 | #metasploit-like print statements. Status messages, error messages, good status returns. I added in a notification print for areas users should definitely pay attention to. 41 | 42 | function print_status () 43 | { 44 | echo -e "\x1B[01;34m[*]\x1B[0m $1" 45 | } 46 | 47 | function print_good () 48 | { 49 | echo -e "\x1B[01;32m[*]\x1B[0m $1" 50 | } 51 | 52 | function print_error () 53 | { 54 | echo -e "\x1B[01;31m[*]\x1B[0m $1" 55 | } 56 | 57 | function print_notification () 58 | { 59 | echo -e "\x1B[01;33m[*]\x1B[0m $1" 60 | } 61 | ######################################## 62 | 63 | #Script does a lot of error checking. Decided to insert an error check function. If a task performed returns a non zero status code, something very likely went wrong. 64 | 65 | function error_check 66 | { 67 | 68 | if [ $? -eq 0 ]; then 69 | print_good "$1 successfully completed." 70 | else 71 | print_error "$1 failed. Please check $logfile for more details." 72 | exit 1 73 | fi 74 | 75 | } 76 | 77 | ######################################## 78 | 79 | #BEGIN MAIN# 80 | 81 | ######################################## 82 | 83 | # These Variables Need to be set! # 84 | 85 | #SPLUNK_INDEXER: This is the box that is going to process your splunk logs. Can be a hostname or an IP address. The default port is 9997/tcp. # 86 | #SPLUNK_INDEXER="splunkserver.yourdomain.com:9997" 87 | 88 | #HOST_NAME: This controls what name your cowrie server will have when reviewing its data in the Tango Splunk App. # 89 | # Use unique names. Suggestion: "hp-{country code}-{city}-{number}" such as: hp-US-Las_Vegas-01 # 90 | #HOST_NAME="hp-countrycode-city-01" 91 | 92 | #KIPPO_LOG_LOCATION: What is the location of your cowrie honeypot logs? # 93 | #For most bang for the buck, you'll want to send splunk "cowrielog.json logs. # 94 | #Assuming you are running Michel Oosterhof's branch of cowrie (https://github.com/micheloosterhof/kippo).. # 95 | #You should be getting shiny JSON logs by default. If not find the following section in cowrie.cfg: # 96 | #[database_jsonlog3] 97 | #logfile = log/cowrielog.json# 98 | #Verify that these lines are uncommented. The log file (as indicated above will be in the cowrie/log/kippolog.json.* # 99 | #Set KIPPO_LOG_LOCATION to the absolutely directory path of the directory containing your cowrielog.json files 100 | #For example, /opt/cowrie/log/ or /home/user/kippo/log/# 101 | #KIPPO_LOG_LOCATION='/opt/cowrie/log/' 102 | 103 | ######################################## 104 | 105 | # Set the directory we are initially executing the script in. 106 | execdir=`pwd` 107 | 108 | ######################################## 109 | 110 | #We need root privs to run most of this, this is a quick check to ensure that we are root. If not, bail. 111 | 112 | print_status "Checking for root privs.." 113 | if [ $(whoami) != "root" ]; then 114 | print_error "This script must be ran with sudo or root privileges." 115 | exit 1 116 | else 117 | print_good "We are root." 118 | fi 119 | 120 | ######################################## 121 | 122 | #We check what architecture the system is and download the correct splunk Universal Forwarder for that CPU arch. 123 | 124 | arch=`uname -m` 125 | 126 | if [[ $arch == "x86_64" ]]; then 127 | INSTALL_FILE="splunkforwarder-7.2.0-8c86330ac18-Linux-x86_64.tgz" 128 | print_notification "System is $arch. Downloading: $INSTALL_FILE to /opt.." 129 | wget -O /opt/splunkforwarder-7.2.0-8c86330ac18-Linux-x86_64.tgz 'https://www.splunk.com/bin/splunk/DownloadActivityServlet?architecture=x86_64&platform=linux&version=7.2.0&product=universalforwarder&filename=splunkforwarder-7.2.0-8c86330ac18-Linux-x86_64.tgz&wget=true' &>> $logfile 130 | error_check 'Splunk Forwarder Download' 131 | elif [[ $arch == "i686" ]]; then 132 | INSTALL_FILE="splunkforwarder-7.1.2-a0c72a66db66-Linux-i686.tgz" 133 | print_notification "System is $arch. Downloading: $INSTALL_FILE to /opt.." 134 | wget -O /opt/splunkforwarder-7.1.2-a0c72a66db66-Linux-i686.tgz 'https://www.splunk.com/page/download_track?file=7.1.2/linux/splunkforwarder-7.1.2-a0c72a66db66-Linux-i686.tgz&ac=&wget=true&name=wget&platform=Linux&architecture=x86&version=7.1.2&product=universalforwarder&typed=release' &>> $logfile 135 | error_check 'Splunk Forwarder Download' 136 | else 137 | print_error "System arch is not x86_64 or i686. Tango Honeypot is not yet supported on other CPU architectures." 138 | exit 1 139 | fi 140 | 141 | ######################################## 142 | 143 | # Based on the OS (Debian or Redhat based), use the OS package manger to download required packages 144 | 145 | if [ -f /etc/debian_version ]; then 146 | apt-get -y update &>> $logfile 147 | print_notification "Installing required packages via apt-get.." 148 | apt-get -y install python-dev python-openssl python-pyasn1 authbind git libgnutls-dev libcurl4-gnutls-dev libssl-dev &>> $logfile 149 | curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py" &>> $logfile 150 | python get-pip.py &>> $logfile 151 | error_check 'Apt Package Installation' 152 | iptables -t nat -A PREROUTING -p tcp --dport 22 -j REDIRECT --to-port 2222 153 | print_notification "Installing required python packages via pip.." 154 | pip install pycurl service_identity ipwhois &>> $logfile 155 | error_check 'Python pip' 156 | elif [ -f /etc/redhat-release ]; then 157 | yum -y update &>> $logfile 158 | print_notification "Installing required packages via yum.." 159 | yum -y install wget python-devel python-zope-interface unzip git gnutls-devel gcc gcc-c++ &>> $logfile 160 | error_check 'Yum Package Installation' 161 | 162 | print_notification "Installing required python packages via easy_install.." 163 | easy_install pycrypto pyasn1 &>> $logfile 164 | error_check 'Python easy_install' 165 | else 166 | print_error "Unable to determine correct package manager to use. This script currently supports apt-based Operating Systems (Debian, Ubuntu, Kali) and yum-based Operating Systems (Redhat, CentOS, etc.) and relies on either /etc/redhat-release or /etc/debian_version being present to determine the correct package manager to use." 167 | exit 1 168 | fi 169 | 170 | ######################################## 171 | 172 | # Adding splunk user for service to run as. Shell is set to /bin/false. 173 | 174 | print_status "Checking for splunk user and group.." 175 | 176 | getent passwd splunk &>> $logfile 177 | if [ $? -eq 0 ]; then 178 | print_status "splunk user exists. Verifying group exists.." 179 | id -g splunk &>> $logfile 180 | if [ $? -eq 0 ]; then 181 | print_notification "splunk group exists." 182 | else 183 | print_notification "splunk group does not exist. Creating.." 184 | groupadd splunk &>> $logfile 185 | usermod -G splunk splunk &>> $logfile 186 | error_check 'Creation of Splunk group and Addition of Splunk user to group' 187 | fi 188 | else 189 | print_status "Creating splunk user and group.." 190 | groupadd splunk &>> $logfile 191 | useradd -g splunk splunk -d /home/splunk -s /bin/false &>> $logfile 192 | mkdir /home/splunk 193 | chown -R splunk:splunk /home/splunk 194 | error_check 'Splunk user and group creation' 195 | 196 | fi 197 | 198 | chown -R splunk:splunk /home/splunk &>> $logfile 199 | 200 | ######################################## 201 | 202 | # Installing Splunk Universal Forwarder and setting it to persist on reboot 203 | 204 | print_notification "Installing Splunk Universal Forwarder.." 205 | cd /opt 206 | tar -xzf $INSTALL_FILE &>> $logfile 207 | chown -R splunk:splunk splunkforwarder &>> $logfile 208 | sudo -u splunk /opt/splunkforwarder/bin/splunk start --accept-license --answer-yes --auto-ports --no-prompt &>> $logfile 209 | error_check 'Universal Forwarder Configuration' 210 | /opt/splunkforwarder/bin/splunk enable boot-start -user splunk &>> $logfile 211 | error_check 'Universal Forwarder Install' 212 | 213 | ######################################## 214 | 215 | # Check to see if the user tried to execute uf_only outside of the Tango directory. Yell at them if they did. Grab tango_input from the Tango directory, configure inputs.conf, start up the forwarder. We done here. 216 | 217 | print_notification "Installing tango_input.." 218 | 219 | if [ ! -d "$execdir/tango_input" ]; then 220 | print_error "Unable to find tango_input directory in $execdir. tango_input should be in the same directory as uf_only.sh. Please correct this and run the script again." 221 | exit 1 222 | else 223 | cp -r "$execdir/tango_input" /opt/splunkforwarder/etc/apps &>> $logfile 224 | fi 225 | 226 | print_notification "Configuring /opt/splunkforwarder/etc/apps/tango_input/default/inputs.conf and outputs.conf.." 227 | 228 | cd /opt/splunkforwarder/etc/apps/tango_input/default 229 | sed -i "s/test/$HOST_NAME/" inputs.conf &>> $logfile 230 | sed -i "s,/opt/cowrie/log/,${KIPPO_LOG_LOCATION}," inputs.conf &>> $logfile 231 | sed -i "s/test/$SPLUNK_INDEXER/" outputs.conf &>> $logfile 232 | 233 | chown -R splunk:splunk /opt/splunkforwarder &>> $logfile 234 | /opt/splunkforwarder/bin/splunk restart &>> $logfile 235 | error_check 'Tango_input installation' 236 | 237 | print_notification "If the location of your cowrie log files changes or the hostname/ip of the indexer changes, you will need to modify /opt/splunkfowarder/etc/apps/tango_input/default/inputs.conf and outputs.conf respectively." 238 | 239 | print_good "Install Completed. The splunk forwarder should be reporting and sending data to your indexer. Log file is located at /var/log/tango_install.log" 240 | 241 | exit 0 242 | --------------------------------------------------------------------------------