8
\$\begingroup\$

This is the robbers' challenge. To post a cop, go here.

In this challenge, cops will invent a (likely simple) programming language, and write an interpreter, transpiler, or compiler that allows you to run it. Robbers will write a program in this language that manages to inject arbitrary code into the interpreter, transpiler, or compiler.

Cops

Cops should design a language. This language should be "pure"; its programs can take input and/or produce output, but cannot affect files, make network requests, behave non-deterministically (based on something like randomness or the system time), or otherwise impact or be impacted by the outside world (within reason).

Cops must then implement this language, with one of:

  • An interpreter: This will take the code and input as arguments/input, and produce the programs's output as output.
  • A transpiler: This will take the code and input, and produce code in some other language which does the same task. When run using that language's interpreter/compiler with input, the correct output is produced.
  • A compiler: Similar to a transpiler, but with machine code instead of another language.

There must be an intended "crack", or way to inject arbitrary code.

Robbers

Robbers should find a way to do one of the following:

  • Write a program that, when interpreted, transpiled, or compiled, can run arbitrary code as the interpreter/transpiler/compiler (e.g., if written in Python, you could run arbitrary Python, manipulate files, and so on)
  • Write a program that, when transpiled or compiled, injects arbitrary code into the resulting program/machine code (e.g., if your transpiler converts the language to Node.js, you could inject arbitrary JS into the transpiler output)

Robber Posts

Robbers should include code which can be given to the cop, which allows injecting arbitrary code. For example:

Cracks Print1Lang


eval("...") # arbitrary Python, with 1s replaced with \x31

This exploits the fact that . in regexes does not match newlines.

This exploit should allow injecting any code, in some language or situation that allows performing arbitrary computations and interacting with the computer's files, running shell commands, system calls, or anything like that. Simply printing a nondeterministic value does not count, as it does not give you unrestricted access to the environment the code or transpilation/compilation output is being run or transpiled/compiled in.

For an interpreter, this is likely going to be running code in the language the interpreter is written in. For a transpiler or compiler, the vulnerability can occur at either compile time or run time, and for the latter, the vulnerability would most likely consist of being able to inject arbitrary code or machine code into the compiled code.

Other

All the boring stuff. Nothing malicious, no crypto stuff.

Winner for cops is the user with the most safe cops, winner for robbers is the user who cracks the most cops.

\$\endgroup\$

5 Answers 5

5
\$\begingroup\$

Cracks Javastack

0);
<!-- place your code here 
console.log(`42`)
//
\$\endgroup\$
1
  • \$\begingroup\$ Nice job! my lexer's pretty bad. \$\endgroup\$
    – emanresu A
    Commented Jan 29, 2022 at 2:32
4
\$\begingroup\$

Cracks Vyxal 2.10

`f"{print(1)}"`∆i

Prints 1 then errors. Sadly does not work online, but does offline. Exploits the fact that ∆i uses sympy, similar to this. Injected code is everything between the { and }.

\$\endgroup\$
1
  • \$\begingroup\$ It’s not the same command I used, but it is the intended solution. Nice job! \$\endgroup\$ Commented Apr 19, 2022 at 2:44
3
\$\begingroup\$

Cracks Exceptionally

{exec
\"wrap"
}FUNCS
{"print(5)"
\0

Your code can go where the print(5) is.

So, all variables are accessible by the program, so we can load exec into the register, but we can't easily execute it. We'd have to load it into FUNCS, but FUNCS needs to be something that can be indexed into...

We can make it an array! By using the builtin \"wrap" on exec we can load that into FUNCS and execute it with \0. The line before that stores our code to the register so it gets run.

\$\endgroup\$
1
  • \$\begingroup\$ Brilliant! Also not what I had in mind, though I love that this is possible. X^D Expect a second version soon... \$\endgroup\$
    – DLosc
    Commented Jan 31, 2022 at 19:55
2
\$\begingroup\$

Cracks Jyxal

@=0,this["FUNC_"+arity]={},eval("console.log(\"pwned\")"),FUNC_x|;

This creates a function with the name...well, everything between @ and |;. Normally, if the function name was something reasonable and the code looked like @xyz|;, the transpiled output would look like this:

var arity = 'xyz';FUNC_xyz = (stack) => {return pop(stack)}; this['FUNC_' + arity.split(':')[0]].arity = arity;

So, with my crack, it looks like this:

var arity = '=0,this["FUNC_"+arity]={},eval("console.log(\"pwned\")"),FUNC_x';FUNC_=0,this["FUNC_"+arity]={},eval("console.log(\"pwned\")"),FUNC_x = (stack) => {return pop(stack)}; this['FUNC_' + arity.split(':')[0]].arity = arity;

As you can see, it sets FUNC_ to 0, sets this["FUNC_"+arity] to {} (to avoid a syntax error later, you could also just use // at the end), and then evals basically arbitrary code. You can't include some characters, but you can just use \x to insert them in the eval'd string.

\$\endgroup\$
1
  • \$\begingroup\$ Nice! My intended solution exited, but this works too. \$\endgroup\$
    – emanresu A
    Commented Jan 29, 2022 at 20:48
1
+250
\$\begingroup\$

Cracks Exceptionally v0.2

<"\"?\")) or exit('GET ACE LOL')#"

Attempt This Online!

Yeet your code where the exit('GET ACE LOL') is. Will print some junk first.

This gets transpiled into:

(print("\")) ? (reg := program.FUNCS[")) or exit('GET ACE LOL')#"](reg))

Exceptionally doesn't escape backslashes in strings, so it parses it as two seperate statements combined by the ? operator. However, the second " is escaped and the string won't end until reaching another ". We include some code to close the parentheses opened by the print and a comment at the end to throw away the rest, then whatever goes in the middle is arbitrary code.

\$\endgroup\$
3
  • \$\begingroup\$ Very good--this was an unintended exploit I realized was possible shortly before I posted the interpreter. Now I'll patch it out and see if you can find my intended crack... :) \$\endgroup\$
    – DLosc
    Commented Feb 3, 2022 at 0:07
  • \$\begingroup\$ (Nitpick: To be able to execute any code, you'd have to use exec, because the context where you're inserting stuff is an expression.) \$\endgroup\$
    – DLosc
    Commented Feb 3, 2022 at 0:08
  • \$\begingroup\$ @DLosc Yeah, I figured that. \$\endgroup\$
    – emanresu A
    Commented Feb 3, 2022 at 0:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.