`\");VY_print(chr(96)+code.split('\n')[3][15:-4])#
Vyxal doesn't have a way to read files, but in v2.4.0 and prior, there was an ACE exploit that allowed for arbitrary python to be executed.
The ACE:
Vyxal is a transpiled language, meaning that every command in a program is converted to some python code, and then all of the python code is combined together and executed.
When pushing a string, all that was done to the string in transpilation was changing "
to \\\"
, then appending it to the stack. This meant that a string \"); #
would become \\");#
. On its own, this means nothing, but when considered in the transpiled code, it is much more useful.
When viewing the transpiled code (which you can do for any Vyxal program using the c
flag), you can see that the snippet `\\"); #
is transpiled to the following python code:
stack.append("\\"); #\n")
Instead of pushing the string that we told it to, it simply pushed \
, followed by a comment. In theory, we could put any python code between the ;
and the #
, which is what we do in this program.
The program:
In this program, the payload (the python code that we actually care about) is the following:
VY_print(chr(96)+code.split('\n')[3][15:-4])
This has several parts to it, so lets pick it apart bit by bit.
VY_print
is the printing function that is defined internally in Vyxal. I used this function instead of print
because it disables the implicit output that Vyxal normally has. This prints the final string, which will hopefully be the same as the program.
When the program is transpiled, the transpiled code is saved in the code
variable. This variable is used in the program to read the source code, which makes this a cheating quine.
However, the code
variable also contains a header that initializes a few variables, such as the stack. To combat this, we split
the code on newlines and get only the fourth line, which is where our code is.
Unfortunately, this line also has the stack.append...
, and the comment at the end, neither of which are part of our quine. Because of this, we need to take only the 16th through 5th-to-last characters in the string, which we do with [15:-4]
.
Finally, our code has a backtick at the beginning to start the string, so we add one to the beginning of the output with chr(96)
, since the ASCII value of `
is 96.