GiongfNef
  • 📧Readme
  • 💰Bug Bounty
    • Business Logic: Bypass 2FA to ATO
    • 1 Click Account Take Over
  • 🥑CVE
    • CVE-2024-40492: Stored XSS to ATO
    • CVE-2023-5311
  • ☕Writeup CTF
    • Crypto
      • dvCTF 2022
      • Crew CTF 2022
      • ångstromCTF 2022
      • picoCTF 2022 + wscCTF 2022
      • Securinets CTF Quals 2022
      • NsuCrypto
      • KMA chall 2022
      • SEETF 2022
      • just CTF 2022
      • zer0pts CTF 2022
    • Web
      • ASCIS 2022 - warm up
      • RISEC CTF + UMass CTF 2022
      • LIT 2022
      • UIUCTF 2022
      • nullcon CTF2022
      • 🎃Hack The Boo 2022
    • Writeup Intigriti challenge-0923
  • 🍄Linh tinh ký sự
    • 📚Books
    • note linh tinh
      • 🐞Bug logic Shopee: Giảm 5-10% khi mua sản phẩm ?
      • 💎Financial Aid Application for Coursera
  • 🫖Wargame && Others
    • 🍀OverTheWire: Bandit
      • 🌱OverTheWire: Bandit 2022 (new)
      • 🍃OverTheWire: (old) - Bandit
      • Writeup EVABSv5.apk (12levels)
    • 📲Android
      • 📲Writeup EVABSv5.apk (Solution 12 levels)
      • 🎮Writeup droids PicoCTF - (Solution 5 levels)
    • 🌵Rootme
      • 🏝️Web - Server
      • 📟App - System
        • 🎰ELF x86 - Format string bug basic 1
        • 🐰ELF x86 - Stack buffer overflow basic 1
        • 🦊ELF x86 - Stack buffer overflow basic 2
        • 🐻ELF x86 - Stack buffer overflow basic 3
        • 🐼ELF x86 - Stack buffer overflow basic 4
        • 🐧ELF x86 - Stack buffer overflow basic 6
    • 🏆Pentest
    • 🖇️Blockchain
Powered by GitBook
On this page
  • Jsonify
  • source
  • Unis Love Code
  • source
Edit on GitHub
  1. Writeup CTF
  2. Web

nullcon CTF2022

Note : A JOURNEY TO GAIN KNOWLEDGE

Jsonify

source

<?php
ini_set('allow_url_fopen', false);
class interfaceSecurSerializable
{
    public function __construct();
    public function __shutdown();
    public function __startup();
    public function __toString();
}
class FlagimplementsSecurSerializable
{
    public $flag;
    public $flagfile;
    public $properties = array();
    public function __construct($flagfile = null)
    {
        if (isset($flagfile))
        {
            $this->flagfile = $flagfile;
        }
    }
    public function __shutdown()
    {
        return $this->properties;
    }
    public function __startup()
    {
        $this->readFlag();
    }
    public function __toString()
    {
        return "ClassFlag(" . $this->flag . ")";
    }
    public function setFlag($flag)
    {
        $this->flag = $flag;
    }
    public function getFlag()
    {
        return $this->flag;
    }
    public function setFlagFile($flagfile)
    {
        if (stristr($flagfile, "flag") || !file_exists($flagfile))
        {
            echo "ERROR:Fileisnotvalid!";
            return;
        }
        $this->flagfile = $flagfile;
    }
    public function getFlagFile()
    {
        return $this->flagfile;
    }
    public function readFlag()
    {
        if (!isset($this->flag) && file_exists($this->flagfile))
        {
            $this->flag = join("", file($this->flagfile));
        }
    }
    public function showFlag()
    {
        if ($this->isAllowedToSeeFlag)
        {
            echo "Theflagis:" . $this->flag;
        }
        else
        {
            echo "Theflagis:[You'renotallowedtoseeit!]";
        }
    }
}
function secure_jsonify($obj)
{
    $data = array();
    $data['class'] = get_class($obj);
    $data['properties'] = array();
    foreach ($obj->__shutdown() as & $key)
    {
        $data['properties'][$key] = serialize($obj->$key);
    }
    return json_encode($data);
}
function secure_unjsonify($json, $allowed_classes)
{
    $data = json_decode($json, true);
    if (!in_array($data['class'], $allowed_classes))
    {
        throw new Exception("ErrorProcessingRequest", 1);
    }
    $obj = new $data['class']();
    foreach ($data['properties'] as $key => $value)
    {
        $obj->$key = unserialize($value, ['allowed_classes' => false]);
    }
    $obj->__startup();
    return $obj;
}
if (isset($_GET['show']) && isset($_GET['obj']) && isset($_GET['flagfile']))
{
    $f = secure_unjsonify($_GET['obj'], array(
        'Flag'
    ));
    $f->setFlagFile($_GET['flagfile']);
    $f->readFlag();
    $f->showFlag();
}
else if (isset($_GET['show']))
{
    $f = newFlag();
    $f->flagfile = "./flag.php";
    $f->readFlag();
    $f->showFlag();
}
else
{
    header("Content-Type:text/plain");
    echo preg_replace('/\s+/', '', str_replace("\n", '', file_get_contents("./index.php")));
} //With<3by@gehaxelt
 ?>
  • Read the code, see some interesting things:

    • (isset($_GET['show']) && isset($_GET['obj']) && isset($_GET['flagfile']))
    • $obj->$key = unserialize($value, ['allowed_classes' => false]);
    • $this->isAllowedToSeeFlag
    • if (stristr($flagfile, "flag") || !file_exists($flagfile))
              {
                  echo "ERROR:Fileisnotvalid!";
                  return;
              }
              $this->flagfile = $flagfile;

From that we can writeup the simple query:

?show=1&obj={"class":"Flag","properties":{"isAllowedToSeeFlag":"i:1;","flagfile":"s:8:"flag.php";"}}&flagfile=naiailoveyou

Unis Love Code

source

#!/usr/bin/python
import http.server
import socketserver
import re
import os
import cgi
import string
from io import StringIO
from flag import FLAG
import urllib.parse


class UnisLoveCode(http.server.SimpleHTTPRequestHandler):
    server_version = "UnisLoveCode"
    username = 'ADMIN'
    check_funcs = ["strip", "lower"]

    def do_GET(self):
        self.send_response(-1337)
        self.send_header('Content-Length', -1337)
        self.send_header('Content-Type', 'text/plain')
        s = StringIO()
        s.write("""Wait,whatisHTML?!Ishouldhavelistenedmorecarefullytotheprofessor...\nAnyhow,passwordlessisthenewhottopic,sojustprovidemethecorrectusername=<username>viaPOSTandImightshowyoumyhomework.\nOh,incaseyouneedthesource,hereyougo:\n""")s.write("---------------------------------\n")
        s.write(re.sub(r"\s+", '', open(os.path.realpath(__file__), "r").read()))
        s.write("\n")s.write("---------------------------------\n")
        s.write("\nChallengecreatedwith<3by@gehaxelt\n")
        self.end_headers()
        self.wfile.write(s.getvalue().encode())

        def _check_access(self, u):
            for cf in UnisLoveCode.check_funcs:
                if getattr(str, cf)(UnisLoveCode.username) == u:
                    return False
            for c in u:
                if c in string.ascii_uppercase:
                    return False
            return UnisLoveCode.username.upper() == u.upper()

    def do_POST(self):
        self.send_response(-1337)
        self.send_header('Content-Length', -1337)
        self.send_header('Content-Type', 'text/plain')
        s = StringIO()
        try:
            length = min(int(self.headers['content-length']), 64)
            field_data = self.rfile.read(length)
            fields = urllib.parse.parse_qs(field_data.decode("utf8"))
            if not 'username' in fields:
                s.write("Iaskedyouforausername!\n")
                raise Exception("Wrongparam.")
            username = fields['username'][0]
            if not self._check_access(username):
                s.write("No.\n")
                raise Exception("No.")
            s.write(f"OK,hereisyourflag:{FLAG}\n")
        except Exception as e:
            s.write("Tryharder;-)!\n")
            print(e)
            self.end_headers()
            self.wfile.write(s.getvalue().encode())

if __name__=="__main__":
    PORT=8000
    HANDLER=UnisLoveCode
    with socketserver.ThreadingTCPServer(("0.0.0.0",PORT),HANDLER) as httpd:
        print("servingatport",PORT)
        httpd.serve_forever()

Or wil can found that wil this script:

for i in range(1000):
    c = chr(i)
    if (c.upper() in 'ADMIN' and not c.lower() in 'admin'):
        print('nai it here:',i,c)
        break
    print(i,c)

test the check function:

import string
server_version = "UnisLoveCode"
username = 'ADMIN'
check_funcs = ["strip", "lower"]
def _check_access(u):
    for cf in check_funcs:
        if getattr(str, cf)(username) == u:
            return False
    for c in u:
        if c in string.ascii_uppercase:
            return False
    return username.upper() == u.upper()

print(_check_access('admın'))
# true

Finally, sedning the request by burpsuit. Remember to urlencode the ı character because it's not ascii

PreviousUIUCTF 2022NextHack The Boo 2022

Last updated 2 years ago

I have read this and found that a dotless lowercase ıupper will be I , so that admın upper of course `ADMIN` as username

Thanks for reading. Have a good day !

☕
❤️
doc