Skip to content

Commit ac69313

Browse files
committed
finally add corCTF2022 challenges
1 parent 23003fe commit ac69313

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+12649
-1
lines changed

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,16 @@ This was a CTF I wrote challenges for, hosted by Intigriti. I forgot to record s
5454

5555
| Name | Category | Solves | Difficulty | Keywords |
5656
| --------------------------------------------------- | --------- | ---------- | ---------- | ------------------------------------------------------------ |
57-
| [payment-pal](DiceCTF-at-HOPE-2022/payment-pal) | web | 3 | ★★★☆☆ | prototype pollution, caching, xss, history, aes |
57+
| [payment-pal](DiceCTF-at-HOPE-2022/payment-pal) | web | 3 | ★★★☆☆ | prototype pollution, caching, xss, history, aes |
58+
59+
## corCTF 2022
60+
61+
| Name | Category | Solves | Difficulty | Keywords |
62+
| --------------------------------------------------- | --------- | ---------- | ---------- | ------------------------------------------------------------ |
63+
| [jsonquiz](corCTF-2022/web/jsonquiz) | web | 573 | ★☆☆☆☆ | baby, POST request |
64+
| [simplewaf](corCTF-2022/web/simplewaf) | web | 28 | ★★☆☆☆ | WAF bypass, NodeJS source reading |
65+
| [rustshop](corCTF-2022/web/simplewaf) | web | 13 | ★★★☆☆ | Rust, Axum library, deserialization |
66+
| [modernblog](corCTF-2022/web/modernblog) | web | 1 | ★★★★★ | React, CSS injection, novel DOM clobbering |
67+
| [babypwn](corCTF-2022/pwn/babypwn) | pwn | 114 | ★☆☆☆☆ | Rust, unsafe, printf, ret2libc |
68+
| [solidarity](corCTF-2022/pwn/solidarity) | pwn | 6 | ★★☆☆☆ | baby solana, account confusion, missing checks |
69+
| [sbxcalc](corCTF-2022/pwn/solidarity) | pwn | 11 | ★★★☆☆ | vm2, js calculator, proxy, golf |

corCTF-2022/misc/sbxcalc/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Solves: 11
2+
3+
Author: strellic
4+
5+
Description:
6+
7+
Yet another sandboxed JavaScript calculator... have fun :)
8+
9+
Flag: `corctf{d0nt_you_just_l0ve_j4vascript?}`
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FROM node:18.1.0-bullseye-slim
2+
WORKDIR /app
3+
COPY package.json ./
4+
COPY views ./views
5+
RUN npm i
6+
COPY app.js .
7+
CMD ["node", "app.js"]

corCTF-2022/misc/sbxcalc/task/app.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
const express = require("express");
2+
const vm2 = require("vm2");
3+
4+
const PORT = process.env.PORT || "4000";
5+
6+
const app = express();
7+
8+
app.set("view engine", "hbs");
9+
10+
// i guess you can have some Math functions...
11+
let sandbox = Object.create(null);
12+
["E", "PI", "sin", "cos", "tan", "log", "pow", "sqrt"].forEach(v => sandbox[v] = Math[v]);
13+
14+
// oh, and the flag too i guess...
15+
sandbox.flag = new Proxy({ FLAG: process.env.FLAG || "corctf{test_flag}" }, {
16+
get: () => "nope" // :')
17+
});
18+
19+
// no modifying the sandbox, please
20+
sandbox = Object.freeze(sandbox);
21+
22+
app.get("/", (req, res) => {
23+
let output = "";
24+
let calc = req.query.calc;
25+
26+
if (calc) {
27+
calc = `${calc}`;
28+
29+
if(calc.length > 75) {
30+
output = "Error: calculation too long";
31+
}
32+
33+
let whitelist = /^([\w+\-*/() ]|([0-9]+[.])+[0-9]+)+$/; // this is a calculator sir
34+
if(!whitelist.test(calc)) {
35+
output = "Error: bad characters in calculation";
36+
}
37+
38+
if(!output) {
39+
try {
40+
const vm = new vm2.VM({
41+
timeout: 100,
42+
eval: false,
43+
sandbox,
44+
});
45+
output = `${vm.run(calc)}`;
46+
if (output.includes("corctf")) {
47+
output = "Error: no.";
48+
}
49+
}
50+
catch (e) {
51+
console.log(e);
52+
output = "Error: error occurred";
53+
}
54+
}
55+
}
56+
57+
res.render("index", { output, calc });
58+
});
59+
60+
app.listen(PORT, () => console.log(`sbxcalc listening on ${PORT}`));
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "sbxcalc",
3+
"version": "1.0.0",
4+
"description": "",
5+
"main": "app.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"author": "strellic",
10+
"license": "ISC",
11+
"dependencies": {
12+
"express": "^4.18.1",
13+
"hbs": "^4.2.0",
14+
"vm2": "^3.9.10"
15+
}
16+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta name="viewport" content="width=device-width, initial-scale=1">
5+
<title>sbxcalc</title>
6+
<link rel="stylesheet" href="https://unpkg.com/[email protected]/build/pure-min.css" integrity="sha384-Uu6IeWbM+gzNVXJcM9XV3SohHtmWE+3VGi496jvgX1jyvDTXfdK+rfZc8C1Aehk5" crossorigin="anonymous">
7+
</head>
8+
<body>
9+
<div style="margin: 4rem">
10+
<h1>sbxcalc</h1>
11+
12+
{{#if output}}
13+
<h3>result: <output>{{output}}</output></h3>
14+
{{/if}}
15+
16+
<form method="GET" class="pure-form">
17+
<input type="text" name="calc" value="{{calc}}" placeholder="calculator" />
18+
<input type="submit" class="pure-button pure-button-primary" />
19+
</form>
20+
</div>
21+
</body>
22+
</html>

corCTF-2022/pwn/babypwn/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Solves: 114
2+
3+
Author: strellic
4+
5+
Description:
6+
7+
Just another one of those typical intro babypwn challs... wait, why is this in Rust?
8+
9+
Flag: `corctf{why_w4s_th4t_1n_rust???}`
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "babypwn"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
libc = "0.2.126"
10+
libc-stdhandle = "0.1.0"
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use libc;
2+
use libc_stdhandle;
3+
4+
fn main() {
5+
unsafe {
6+
libc::setvbuf(libc_stdhandle::stdout(), &mut 0, libc::_IONBF, 0);
7+
8+
libc::printf("Hello, world!\n\0".as_ptr() as *const libc::c_char);
9+
libc::printf("What is your name?\n\0".as_ptr() as *const libc::c_char);
10+
11+
let text = [0 as libc::c_char; 64].as_mut_ptr();
12+
libc::fgets(text, 64, libc_stdhandle::stdin());
13+
libc::printf("Hi, \0".as_ptr() as *const libc::c_char);
14+
libc::printf(text);
15+
16+
libc::printf("What's your favorite :msfrog: emote?\n\0".as_ptr() as *const libc::c_char);
17+
libc::fgets(text, 128, libc_stdhandle::stdin());
18+
19+
libc::printf(format!("{}\n\0", r#"
20+
....... ...----.
21+
.-+++++++&&&+++--.--++++&&&&&&++.
22+
+++++++++++++&&&&&&&&&&&&&&++-+++&+
23+
+---+&&&&&&&@&+&&&&&&&&&&&++-+&&&+&+-
24+
-+-+&&+-..--.-&++&&&&&&&&&++-+&&-. ....
25+
-+--+&+ .&&+&&&&&&&&&+--+&+... ..
26+
-++-.+&&&+----+&&-+&&&&&&&&&+--+&&&&&&+.
27+
.+++++---+&&&&&&&+-+&&&&&&&&&&&+---++++--
28+
.++++++++---------+&&&&&&&&&&&&@&&++--+++&+
29+
-+++&&&&&&&++++&&&&&&&&+++&&&+-+&&&&&&&&&&+-
30+
.++&&++&&&&&&&&&&&&&&&&&++&&&&++&&&&&&&&+++-
31+
-++&+&+++++&&&&&&&&&&&&&&&&&&&&&&&&+++++&&
32+
-+&&&@&&&++++++++++&&&&&&&&&&&++++++&@@&
33+
-+&&&@@@@@&&&+++++++++++++++++&&&@@@@+
34+
.+&&&@@@@@@@@@@@&&&&&&&@@@@@@@@@@@&-
35+
.+&&@@@@@@@@@@@@@@@@@@@@@@@@@@@+
36+
.+&&&@@@@@@@@@@@@@@@@@@@@@&+.
37+
.-&&&&@@@@@@@@@@@@@@@&&-
38+
.-+&&&&&&&&&&&&&+-.
39+
..--++++--."#).as_ptr() as *const libc::c_char);
40+
}
41+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
FROM pwn.red/jail:0.3.0
2+
COPY --from=ubuntu:20.04 / /srv
3+
COPY babypwn /srv/app/run
4+
COPY flag.txt /srv/app

corCTF-2022/pwn/babypwn/task/babypwn

3.41 MB
Binary file not shown.

corCTF-2022/pwn/babypwn/task/flag.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
corctf{why_w4s_th4t_1n_rust???}
1.94 MB
Binary file not shown.

corCTF-2022/pwn/solidarity/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Solves: 6
2+
3+
Author: strellic
4+
5+
Description:
6+
7+
The Crusaders of Rust CTF team stands in solidarity... with otters?
8+
9+
Flag: `corctf{solid4rity_for_the_ott3r_cause}`
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[package]
2+
name = "solidarity"
3+
version = "1.0.0"
4+
edition = "2021"
5+
6+
[features]
7+
no-entrypoint = []
8+
9+
[dependencies]
10+
borsh = "0.9.3"
11+
borsh-derive = "0.9.3"
12+
solana-program = "1.8.14"
13+
14+
[lib]
15+
crate-type = ["cdylib", "lib"]
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.PHONY: build
2+
build:
3+
cargo build-bpf
4+
cp ./target/deploy/solidarity.so ../challenge
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#![cfg(not(feature = "no-entrypoint"))]
2+
3+
use solana_program::{
4+
account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, pubkey::Pubkey,
5+
};
6+
7+
entrypoint!(process_instruction);
8+
fn process_instruction(
9+
program_id: &Pubkey,
10+
accounts: &[AccountInfo],
11+
instruction_data: &[u8],
12+
) -> ProgramResult {
13+
crate::processor::process_instruction(program_id, accounts, instruction_data)
14+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
mod entrypoint;
2+
pub mod processor;
3+
4+
use borsh::{
5+
BorshDeserialize,
6+
BorshSerialize,
7+
};
8+
9+
use solana_program::{
10+
instruction::{
11+
AccountMeta,
12+
Instruction,
13+
},
14+
pubkey::Pubkey,
15+
system_program,
16+
17+
};
18+
19+
use std::mem::size_of;
20+
21+
#[derive(BorshDeserialize, BorshSerialize)]
22+
pub enum SolInstruction {
23+
Initialize,
24+
Propose { proposal_id: u32 },
25+
Vote { proposal_id: u32, amount: u32 },
26+
Withdraw { amount: u64 }
27+
}
28+
29+
#[repr(C)]
30+
#[derive(BorshSerialize, BorshDeserialize)]
31+
pub struct Config {
32+
pub admin: Pubkey,
33+
pub total_balance: u64
34+
}
35+
36+
#[repr(C)]
37+
#[derive(BorshSerialize, BorshDeserialize)]
38+
pub struct Proposal {
39+
pub creator: Pubkey,
40+
pub balance: u32,
41+
pub proposal_id: u32
42+
}
43+
44+
pub const CONFIG_SIZE: usize = size_of::<Config>();
45+
pub const PROPOSAL_SIZE: usize = size_of::<Proposal>();
46+
47+
pub fn get_config(program: Pubkey) -> (Pubkey, u8) {
48+
Pubkey::find_program_address(&["CONFIG".as_bytes()], &program)
49+
}
50+
pub fn get_vault(program: Pubkey) -> (Pubkey, u8) {
51+
Pubkey::find_program_address(&["VAULT".as_bytes()], &program)
52+
}
53+
pub fn get_proposal(program: Pubkey, proposal_id: u32) -> (Pubkey, u8) {
54+
Pubkey::find_program_address(&["PROPOSAL".as_bytes(), &proposal_id.to_be_bytes()], &program)
55+
}
56+
57+
pub fn initialize(program: Pubkey, user: Pubkey) -> Instruction {
58+
let (config, _) = get_config(program);
59+
let (vault, _) = get_vault(program);
60+
Instruction {
61+
program_id: program,
62+
accounts: vec![
63+
AccountMeta::new(config, false),
64+
AccountMeta::new(vault, false),
65+
AccountMeta::new(user, true),
66+
AccountMeta::new_readonly(system_program::id(), false),
67+
],
68+
data: SolInstruction::Initialize.try_to_vec().unwrap(),
69+
}
70+
}
71+
72+
pub fn propose(program: Pubkey, user: Pubkey, creator: Pubkey, proposal_id: u32) -> Instruction {
73+
let (config, _) = get_config(program);
74+
let (proposal, _) = get_proposal(program, proposal_id);
75+
Instruction {
76+
program_id: program,
77+
accounts: vec![
78+
AccountMeta::new(config, false),
79+
AccountMeta::new(user, true),
80+
AccountMeta::new(creator, true),
81+
AccountMeta::new(proposal, false),
82+
AccountMeta::new_readonly(system_program::id(), false),
83+
],
84+
data: SolInstruction::Propose{ proposal_id }.try_to_vec().unwrap(),
85+
}
86+
}
87+
88+
pub fn vote(program: Pubkey, user: Pubkey, proposal_id: u32, amount: u32) -> Instruction {
89+
let (config, _) = get_config(program);
90+
let (vault, _) = get_vault(program);
91+
let (proposal, _) = get_proposal(program, proposal_id);
92+
Instruction {
93+
program_id: program,
94+
accounts: vec![
95+
AccountMeta::new(config, false),
96+
AccountMeta::new(vault, false),
97+
AccountMeta::new(user, true),
98+
AccountMeta::new(proposal, false),
99+
AccountMeta::new_readonly(system_program::id(), false),
100+
],
101+
data: SolInstruction::Vote{ proposal_id, amount }.try_to_vec().unwrap(),
102+
}
103+
}
104+
105+
pub fn withdraw(program: Pubkey, user: Pubkey, amount: u64) -> Instruction {
106+
let (config, _) = get_config(program);
107+
let (vault, _) = get_vault(program);
108+
Instruction {
109+
program_id: program,
110+
accounts: vec![
111+
AccountMeta::new(config, false),
112+
AccountMeta::new(vault, false),
113+
AccountMeta::new(user, true),
114+
AccountMeta::new_readonly(system_program::id(), false),
115+
],
116+
data: SolInstruction::Withdraw{ amount }.try_to_vec().unwrap(),
117+
}
118+
}

0 commit comments

Comments
 (0)