st98

@st98

https://st98.github.io https://twitter.com/st98_

Joined on Nov 14, 2015

  • Overview This is a service that you can create, read, and delete files including symbolic links. Filename should not contain characters except for 0-9A-Za-z. When you create a symbolic link, the link target should not start with / or contain ... Solution Paths of link targets will be only checked when files are created. Looking through the source code, you will notice that the order of checking a target path is, calling symlink, then checking the target path with readlink. Why does it checks the target path after a symbolic link is created? /* Create a symbolic link */
     Like  Bookmark
  • Overview The flag is in templates/index.html as below. To obtain the flag, you need to be logged in as admin, or read the content of the template file. {% if name == 'admin' %} <p>zer0pts{*****CENSORED*****}</p> {% else %} User input will be embedded in SQL statement, however, SQL Injection in /login seems to be prevented by escaping it.
     Like  Bookmark
  • Overview User input and the flag will be inserted into 'use strict'; (function () { return ${code}; /* ${FLAG} */ })(), and the server executes the code in sandbox. const result = vm.runInNewContext(`'use strict'; (function () { return ${code}; /* ${FLAG} */ })()`, {}, { timeout: 100 }); As you can see in the code, the flag is inserted as a comment in a function, after user input. So, what you need to do is somehow exfiltrating the comment by, for example, converting the function to String and outputting it. Since the server sets the maximum length of user input to 29 characters, you need to do code-golf with some features available in recent ECMAScript. const code = req.query.code + '';
     Like 1 Bookmark
  • Overview This application fetches api.php and renders the contents by JSONP. The length of the name of a callback function is up to 20 characters. <?php header('Content-Type: application/javascript'); $callback = $_GET['callback'] ?? 'render'; if (strlen($callback) > 20) { die('throw new Error("callback name is too long")'); }
     Like  Bookmark
  • Solution We're given source codes for database, app, and crawler. The location of flag can easily be found in worker/worker.js. // (snipped) const flag = 'zer0pts{<censored>}'; // (snipped) const crawl = async (url) => {
     Like  Bookmark
  • Solution As you can see from app.py, there is a Server-Side Template Injection (SSTI) vulnerability via Referer header in 404 page. @app.errorhandler(404) def page_not_found(error): """ Automatically go back when page is not found """ referrer = flask.request.headers.get("Referer") if referrer is None: referrer = '/' if not valid_url(referrer): referrer = '/'
     Like  Bookmark
  • Solution We're given the source codes (index.php, util.php) and Dockerfile. As you can see from index.php, the flag is stored in every created database as a table with unknown table name and unknown column name, but you can't see it. $pdo->query('CREATE TABLE `' . FLAG_TABLE . '` (`' . FLAG_COLUMN . '` TEXT);'); $pdo->query('INSERT INTO `' . FLAG_TABLE . '` VALUES ("' . FLAG . '");'); $pdo->query($sql); Obviously there are SQL injection with table name, column name, and column type when creating tables in index.php.
     Like  Bookmark
  • Solution We're given the source code (index.php) and Dockerfile. As you can see from index.php, you can get the flag if you can guess bin2hex(random_bytes(64)) or get config.php. <?php include 'config.php'; // FLAG is defined in config.php if (preg_match('/config\.php\/*$/i', $_SERVER['PHP_SELF'])) { exit("I don't know what you are thinking, but I won't let you read it :)"); }
     Like  Bookmark