├── README.md ├── TechStack.sh └── art.txt /README.md: -------------------------------------------------------------------------------- 1 | # TechStack 2 | 3 | This project exists as an alternative to paid services that show you what technologies are running on a given website. 4 | 5 | The impetus was another project of mine, Adaptive Testing Methodology, which gives a customized set of testing steps based on what site you're testing and how much time you have. 6 | 7 | But in order to do that, you have to know the technology stack for a given site. I started by trying to use existing services, but quickly got hit by either call limits or significant costs. 8 | 9 | So I have created this as a free alternative. 10 | 11 | ## Approach 12 | 13 | One thing that's different about this approach is that I'm looking for certain things and telling you if you have them (with a focus on the big blocks that make up a site and could affect its security). 14 | 15 | The point is that I am not listing every possible thing on the site. I'm not mentioning that there is JavaScript, or HTML, or fonts, or whitespace. I don't find knowing those things to be terribly useful. 16 | -------------------------------------------------------------------------------- /TechStack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ############################################################## 4 | # TechStack: Find out the technologies that a site is running 5 | # using Bash because checking for 200's using curl seemed 6 | # easier at the time but now realize I should have done it in 7 | # Ruby from the beginning (deep breath) 8 | # By Daniel Miessler (Jan 2016) 9 | ############################################################## 10 | 11 | ######################### 12 | # Variables 13 | ######################### 14 | 15 | URL=$1 16 | STACKFILE=./sitestack.txt 17 | SITECONTENT=./sitecontent.html 18 | OUTPUT=./output.html 19 | SORTEDSITESTACK=./sortedsitestack.txt 20 | 21 | # Cleanup 22 | if [ -f $STACKFILE ] ; then 23 | rm -f $STACKFILE 24 | fi 25 | 26 | if [ -f $OUTPUT ] ; then 27 | rm -f $OUTPUT 28 | fi 29 | 30 | if [ -f $SITECONTENT ] ; then 31 | rm -f $SITECONTENT 32 | fi 33 | 34 | if [ -f $SORTEDSITESTACK ] ; then 35 | rm -f $SORTEDSITESTACK 36 | fi 37 | 38 | # Output 39 | echo " " 40 | echo " " 41 | echo "Currently scanning $URL..." 42 | echo " " 43 | 44 | # Help 45 | if [[ $# -ne 1 ]] ; then 46 | echo 'Usage:' 47 | echo './TechStack url' 48 | echo 'Example: ./TechStack google.com, or ./TechStack https://www.google.com' 49 | exit 50 | fi 51 | 52 | #################################################################################### 53 | # CHECK THE SITE 54 | #################################################################################### 55 | 56 | # Get headers 57 | curl -skLIA "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36" "$URL" -o ./output.html 58 | 59 | curl -sLKA "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36" "$URL" >> ./output.html 60 | 61 | ################### 62 | ## WORDPRESS CHECKS 63 | ################### 64 | 65 | # Check for wp-admin 66 | 67 | WPADMIN="$(curl -skLKA "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36" -w "%{http_code}" "$URL/wp-admin/" -o ./sitecontent.html)" 68 | 69 | WPREADME="$(curl -skLA "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36" -w "%{http_code}" "$URL/readme.txt" -o ./sitecontent.html)" 70 | 71 | # Check for status of requests 72 | if [ "$WPADMIN" = "200" ] && [ "$WPREADME" = "200" ]; then 73 | echo "[X] wp-admin and a readme.txt file have been found." 74 | echo "Wordpress" >> ./sitestack.txt 75 | echo "PHP" >> ./sitestack.txt 76 | fi 77 | 78 | # Check for Wordpress in response 79 | if grep -i generator ./sitecontent.html | grep -qi wordpress 80 | then 81 | echo "[X] Wordpress found in headers." 82 | echo "Wordpress" >> ./sitestack.txt 83 | echo "PHP" >> ./sitestack.txt 84 | fi 85 | 86 | ################### 87 | ## DRUPAL CHECKS 88 | ################### 89 | 90 | # Check for drupal.js 91 | DRUPALJS="$(curl -skLA "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10) AppleWebKit/600.1.25 (KHTML, like Gecko) Version/8.0 Safari/600.1.25" -w "%{http_code}" "$URL/misc/drupal.js" -o ./sitecontent.html)" 92 | 93 | # Check for changelog 94 | DRUPALCHANGELOG="$(curl -skLA "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10) AppleWebKit/600.1.25 (KHTML, like Gecko) Version/8.0 Safari/600.1.25" -w "%{http_code}" "$URL/CHANGELOG.txt" -o ./sitecontent.html)" 95 | 96 | # Check for status of requests 97 | if [ "$DRUPALJS" = "200" ] && [ "$DRUPALCHANGELOG" = "200" ]; then 98 | echo "[X] Drupal JS and the change log have been found." 99 | echo "Drupal" >> ./sitestack.txt 100 | echo "PHP" >> ./sitestack.txt 101 | fi 102 | 103 | # Check for Drupal in response 104 | if grep -i generator ./sitecontent.html | grep -qi drupal 105 | then 106 | echo "[X] Drupal found in headers." 107 | echo "Drupal" >> ./sitestack.txt 108 | echo "PHP" >> ./sitestack.txt 109 | fi 110 | 111 | ################### 112 | ## JOOMLA CHECKS 113 | ################### 114 | 115 | # Check for administrator directory 116 | JOOMLAADMIN="$(curl -skLA "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10) AppleWebKit/600.1.25 (KHTML, like Gecko) Version/8.0 Safari/600.1.25" -w "%{http_code}" "$URL/administrator/" -o ./sitecontent.html)" 117 | 118 | # Check for status of requests 119 | if [ "$JOOMLAADMIN" = "200" ] ; then 120 | echo "[X] An admnistrator directory has been found in the root (Joomla?)." 121 | echo "Joomla" >> ./sitestack.txt 122 | echo "PHP" >> ./sitestack.txt 123 | fi 124 | 125 | # Check for Joomla in response 126 | if grep -i generator ./sitecontent.html | grep -qi joomla 127 | then 128 | echo "[X] Joomla found in headers." 129 | echo "Joomla" >> ./sitestack.txt 130 | echo "PHP" >> ./sitestack.txt 131 | 132 | fi 133 | 134 | ################### 135 | ## APACHE CHECKS 136 | ################### 137 | 138 | # Check for Apache in response 139 | if grep -i "Server:" ./output.html | grep -qi apache 140 | then 141 | echo "[X] Apache found in headers." 142 | echo "Apache" >> ./sitestack.txt 143 | fi 144 | 145 | ################### 146 | ## NGINX CHECKS 147 | ################### 148 | 149 | # Check for Nginx in response 150 | if grep -i "Server:" ./output.html | grep -qi nginx 151 | then 152 | echo "[X] Nginx found in headers." 153 | echo "Nginx" >> ./sitestack.txt 154 | fi 155 | 156 | ################### 157 | ## IIS CHECKS 158 | ################### 159 | 160 | # Check for Nginx in response 161 | if grep -i "Server:" ./output.html | grep -qi IIS 162 | then 163 | echo "[X] IIS found in headers." 164 | echo "IIS" >> ./sitestack.txt 165 | echo "Windows" >> ./sitestack.txt 166 | fi 167 | 168 | ################### 169 | ## TLS CHECKS 170 | ################### 171 | 172 | # Check for HTTPS in redirect 173 | if grep -i "Location:" ./output.html | grep -qi https 174 | then 175 | echo "[X] TLS in URL or TLS redirect found in headers." 176 | echo "TLS" >> ./sitestack.txt 177 | fi 178 | 179 | if [[ "$URL" == *"https"* ]] 180 | then 181 | echo "[X] TLS found in headers." 182 | echo "TLS" >> ./sitestack.txt 183 | fi 184 | 185 | ################### 186 | ## .NET CHECKS 187 | ################### 188 | 189 | # Check for .NET in headers 190 | if grep -i "X-Powered-By:" ./output.html | grep -qi ".NET" 191 | then 192 | echo "[X] .NET found in headers." 193 | echo ".NET" >> ./sitestack.txt 194 | fi 195 | 196 | ################### 197 | ## GENTOO CHECKS 198 | ################### 199 | 200 | # Check for Gentoo in headers 201 | if grep -i "X-Powered-By:" ./output.html | grep -qi gentoo 202 | then 203 | echo "[X] Gentoo found in headers." 204 | echo "Gentoo" >> ./sitestack.txt 205 | echo "Linux" >> ./sitestack.txt 206 | fi 207 | 208 | ################### 209 | ## DEBIAN CHECKS 210 | ################### 211 | 212 | # Check for Debian in headers 213 | if grep -i "X-Powered-By:" ./output.html | grep -qi dotdeb 214 | then 215 | echo "[X] Debian found in headers." 216 | echo "Debian" >> ./sitestack.txt 217 | echo "Linux" >> ./sitestack.txt 218 | fi 219 | 220 | if grep -i "X-Powered-By:" ./output.html | grep -qi "deb*u" 221 | then 222 | echo "[X] Debian found in headers." 223 | echo "Debian" >> ./sitestack.txt 224 | echo "Linux" >> ./sitestack.txt 225 | fi 226 | 227 | if grep -i "Server:" ./output.html | grep -qi debian 228 | then 229 | echo "[X] Debian found in headers." 230 | echo "Debian" >> ./sitestack.txt 231 | echo "Linux" >> ./sitestack.txt 232 | fi 233 | 234 | ################### 235 | ## PHP CHECKS 236 | ################### 237 | 238 | # Check for PHP in headers 239 | if grep -i "X-Powered-By:" ./output.html | grep -qi PHP 240 | then 241 | echo "[X] PHP found in headers." 242 | echo "PHP" >> ./sitestack.txt 243 | fi 244 | 245 | ################### 246 | ## FREEBSD CHECKS 247 | ################### 248 | 249 | # Check for FreeBSD in headers 250 | if grep -i "Server:" ./output.html | grep freebsd 251 | then 252 | echo "[X] FreeBSD found in headers." 253 | echo "FreeBSD" >> ./sitestack.txt 254 | fi 255 | 256 | ################### 257 | ## CLOUDFLARE CHECKS 258 | ################### 259 | 260 | # Check for Cloudflare in headers 261 | if grep -i "Server:" ./output.html | grep -qi cloudflare 262 | then 263 | echo "[X] Cloudflare found in headers." 264 | echo "Cloudflare" >> ./sitestack.txt 265 | fi 266 | 267 | ################### 268 | ## EXPRESS CHECKS 269 | ################### 270 | 271 | # Check for in Express in headers 272 | if grep -i "X-Powered-By:" ./output.html | grep -qi express 273 | then 274 | echo "[X] Express found in headers." 275 | echo "Express" >> ./sitestack.txt 276 | echo "Node" >> ./sitestack.txt 277 | fi 278 | 279 | ################### 280 | ## JBOSS CHECKS 281 | ################### 282 | 283 | # Check for in JBoss in headers 284 | if grep -i "X-Powered-By:" ./output.html | grep -qi jboss 285 | then 286 | echo "[X] JBoss found in headers." 287 | echo "JBoss" >> ./sitestack.txt 288 | fi 289 | 290 | ################### 291 | ## TOMCAT CHECKS 292 | ################### 293 | 294 | # Check for in Tomcat in headers 295 | if grep -i "X-Powered-By:" ./output.html | grep -qi tomcat 296 | then 297 | echo "[X] Tomcat found in headers." 298 | echo "Tomcat" >> ./sitestack.txt 299 | fi 300 | 301 | ################### 302 | ## GITHUB Checks 303 | ################### 304 | 305 | # Check for in Github in headers 306 | if grep -i "Server:" ./output.html | grep -qi github 307 | then 308 | echo "[X] Github found in headers." 309 | echo "Github" >> ./sitestack.txt 310 | fi 311 | 312 | ################### 313 | ## GSE Checks 314 | ################### 315 | 316 | # Check for in GSE in headers 317 | if grep -i "Server:" ./output.html | grep -qi gse 318 | then 319 | echo "[X] GSEfound in headers." 320 | echo "GSE" >> ./sitestack.txt 321 | fi 322 | 323 | ################### 324 | ## AMAZONS3 Checks 325 | ################### 326 | 327 | # Check for in AmazonS3 in headers 328 | if grep -i "Server:" ./output.html | grep -qi amazons3 329 | then 330 | echo "[X] Amazon S3 found in headers." 331 | echo "AmazonS3" >> ./sitestack.txt 332 | fi 333 | 334 | ################### 335 | ## BAIDU Checks 336 | ################### 337 | 338 | # Check for in Baidu in headers 339 | if grep -i "Server:" ./output.html | grep -qi bws 340 | then 341 | echo "[X] Amazon S3 found in headers." 342 | echo "BWS" >> ./sitestack.txt 343 | fi 344 | 345 | ################### 346 | ## ATS Checks 347 | ################### 348 | 349 | # Check for in ATS in headers 350 | if grep -i "Server:" ./output.html | grep -qi ats 351 | then 352 | echo "[X] Apache ATS found in headers." 353 | echo "ATS" >> ./sitestack.txt 354 | fi 355 | 356 | ################### 357 | ## SQUID Checks 358 | ################### 359 | 360 | # Check for in ATS in headers 361 | if grep -i "Server:" ./output.html | grep -qi squid 362 | then 363 | echo "[X] Squid found in headers." 364 | echo "Squid" >> ./sitestack.txt 365 | fi 366 | 367 | ################### 368 | ## WEIBO Checks 369 | ################### 370 | 371 | # Check for in Weibo in headers 372 | if grep -i "Server:" ./output.html | grep -qi weibo 373 | then 374 | echo "[X] Weibo found in headers." 375 | echo "Weibo" >> ./sitestack.txt 376 | fi 377 | 378 | ################### 379 | ## GWS Checks 380 | ################### 381 | 382 | # Check for in GWS in headers 383 | if grep -i "Server:" ./output.html | grep -qi gws 384 | then 385 | echo "[X] GWS found in headers." 386 | echo "GWS" >> ./sitestack.txt 387 | fi 388 | 389 | ################### 390 | ## UBUNTU Checks 391 | ################### 392 | 393 | # Check for in Ubuntu in headers 394 | if grep -i "X-Powered-By:" ./output.html | grep -qi ubuntu 395 | then 396 | echo "[X] Ubuntu found in headers." 397 | echo "Ubuntu" >> ./sitestack.txt 398 | echo "Linux" >> ./sitestack.txt 399 | fi 400 | 401 | ################### 402 | ## PHP Checks 403 | ################### 404 | 405 | # Check for in PHP in headers 406 | if grep -i "X-Powered-By:" ./output.html | grep -qi php 407 | then 408 | echo "[X] PHP found in headers." 409 | echo "PHP" >> ./sitestack.txt 410 | fi 411 | 412 | ################### 413 | ## HHVM Checks 414 | ################### 415 | 416 | # Check for in HHVM in headers 417 | if grep -i "X-Powered-By:" ./output.html | grep -qi hhvm 418 | then 419 | echo "[X] HHVM found in headers." 420 | echo "HHVM" >> ./sitestack.txt 421 | fi 422 | 423 | ################### 424 | ## W3 TOTAL CACHE CHECKS 425 | ################### 426 | 427 | # Check for in W3 Total Cache in headers 428 | if grep -i "X-Powered-By:" ./output.html | grep -qi "w3 total cache" 429 | then 430 | echo "[X] W3 Total Cache found in headers." 431 | echo "W3TotalCache" >> ./sitestack.txt 432 | echo "Wordpress" >> ./sitestack.txt 433 | fi 434 | 435 | ################### 436 | ## TOMCAT CHECKS 437 | ################### 438 | 439 | # Check for in Tomcat in headers 440 | if grep -i "Server:" ./output.html | grep -qi tomcat 441 | then 442 | echo "[X] Tomcat found in headers." 443 | echo "Tomcat" >> ./sitestack.txt 444 | echo "Apache" >> ./sitestack.txt 445 | fi 446 | 447 | ################### 448 | ## SUSE CHECKS 449 | ################### 450 | 451 | # Check for Suse in headers 452 | if grep -i "Server:" ./output.html | grep -qi suse 453 | then 454 | echo "[X] Tomcat found in headers." 455 | echo "Tomcat" >> ./sitestack.txt 456 | echo "Apache" >> ./sitestack.txt 457 | fi 458 | 459 | ################### 460 | ## CENTOS CHECKS 461 | ################### 462 | 463 | # Check for CentOS in headers 464 | if grep -i "Server:" ./output.html | grep -qi centos 465 | then 466 | echo "[X] CentOS found in headers." 467 | echo "CentOS" >> ./sitestack.txt 468 | echo "Linux" >> ./sitestack.txt 469 | fi 470 | 471 | ################### 472 | ## REDHAT CHECKS 473 | ################### 474 | 475 | # Check for Red Hat in headers 476 | if grep -i "Server:" ./output.html | grep -qi "red hat" 477 | then 478 | echo "[X] Red Hat found in headers." 479 | echo "Redhat" >> ./sitestack.txt 480 | echo "Linux" >> ./sitestack.txt 481 | fi 482 | 483 | ################### 484 | ## UNIX CHECKS 485 | ################### 486 | 487 | # Check for Unix in headers 488 | if grep -i "Server:" ./output.html | grep -qi unix 489 | then 490 | echo "[X] Unix found in headers." 491 | echo "Unix" >> ./sitestack.txt 492 | fi 493 | 494 | ################### 495 | ## ORACLE CHECKS 496 | ################### 497 | 498 | # Check for Oracle in headers 499 | if grep -i "Server:" ./output.html | grep -qi oracle 500 | then 501 | echo "[X] Oracle App Server found in headers." 502 | echo "OracleAppServer" >> ./sitestack.txt 503 | fi 504 | 505 | ################### 506 | ## SUCURI CHECKS 507 | ################### 508 | 509 | # Check for Sucuri in headers 510 | if grep -i "Server:" ./output.html | grep -qi sucuri 511 | then 512 | echo "[X] Sucuri found in headers." 513 | echo "Sucuri" >> ./sitestack.txt 514 | fi 515 | 516 | ################### 517 | ## VARNISH CHECKS 518 | ################### 519 | 520 | # Check for Varnish in headers 521 | if grep -i "Server:" ./output.html | grep -qi varnish 522 | then 523 | echo "[X] Varnish found in headers." 524 | echo "Varnish" >> ./sitestack.txt 525 | fi 526 | 527 | ################### 528 | ## LIGHTHTTPD CHECKS 529 | ################### 530 | 531 | # Check for Light HTTPD in headers 532 | if grep -i "Server:" ./output.html | grep -qi lighttpd 533 | then 534 | echo "[X] Light HTTPD found in headers." 535 | echo "LightHTTPD" >> ./sitestack.txt 536 | fi 537 | 538 | ################### 539 | ## SUN CHECKS 540 | ################### 541 | 542 | # Check for Sun in headers 543 | if grep -i "Server:" ./output.html | grep -qi sun 544 | then 545 | echo "[X] Sun found in headers." 546 | echo "Sun" >> ./sitestack.txt 547 | echo "Unix" >> ./sitestack.txt 548 | fi 549 | 550 | ##################################################################################### 551 | # OUTPUT 552 | ##################################################################################### 553 | 554 | ######################## 555 | # CLEANUP 556 | ######################## 557 | 558 | if [ -f $STACKFILE ] ; then 559 | sort ./sitestack.txt > ./sortedsitestack.txt 560 | uniq ./sortedsitestack.txt > ./sitestack.txt 561 | fi 562 | 563 | if [ -f $STACKFILE ] ; then 564 | echo " " 565 | cat art.txt 566 | echo " " 567 | echo "The site APPEARS to be running..." 568 | echo " " 569 | echo "--" 570 | cat ./sitestack.txt 571 | echo "--" 572 | echo " " 573 | echo "NOTE: It's easy to fool this kind of magic." 574 | else 575 | echo " " 576 | echo "No technologies were detected on this site." 577 | echo " " 578 | fi 579 | 580 | # Cleanup 581 | if [ -f $STACKFILE ] ; then 582 | rm -f $STACKFILE 583 | fi 584 | 585 | if [ -f $OUTPUT ] ; then 586 | rm -f $OUTPUT 587 | fi 588 | 589 | if [ -f $SITECONTENT ] ; then 590 | rm -f $SITECONTENT 591 | fi 592 | 593 | if [ -f $SORTEDSITESTACK ] ; then 594 | rm -f $SORTEDSITESTACK 595 | fi 596 | -------------------------------------------------------------------------------- /art.txt: -------------------------------------------------------------------------------- 1 | ____ 2 | .'* *.' 3 | __/_*_*(_ 4 | / _______ \ 5 | _\_)/___\(_/_ 6 | / _((\- -/))_ \ 7 | \ \())(-)(()/ / 8 | ' \(((()))/ ' 9 | / ' \)).))/ ' \ 10 | / _ \ - | - /_ \ 11 | ( ( .;''';. .' ) 12 | _\"__ / )\ __"/_ 13 | \/ \ ' / \/ 14 | .' '...' ' ) 15 | / / | \ \ 16 | / . . . \ 17 | / . . \ 18 | / / | \ \ 19 | .' / b '. '. 20 | _.-' / Bb '-. '-._ 21 | _.-' | BBb '-. '-. 22 | (________mrf\____.dBBBb.________)____) 23 | 24 | 25 | --------------------------------------------------------------------------------