diff --git a/pyjail-1/solve.md b/pyjail-1/solve.md index 399365c..f96c77b 100644 --- a/pyjail-1/solve.md +++ b/pyjail-1/solve.md @@ -8,4 +8,6 @@ To get around this, we can raise an error with a custom error message. ```py raise OSError(locals()[chr(102)+chr(108)+chr(97)+chr(103)]) -``` \ No newline at end of file +``` + +Note: There is an unintended solution to both original JailBreak challenges, which is by abusing Python normalization and submitting a payload such as `𝘱𝘳𝘪𝘯𝘵(𝘧𝘭𝘢𝘨)`. Other unintended solutions to JailBreak 1 involve `help()`. \ No newline at end of file diff --git a/pyjail-2/solve.md b/pyjail-2/solve.md index 99f52a8..0544a41 100644 --- a/pyjail-2/solve.md +++ b/pyjail-2/solve.md @@ -4,4 +4,6 @@ Unlike the first JailBreak, this time the security measures banned numbers. Howe ``` locals()[chr(((bool("a")+bool("a")+bool("a")+bool("a")+bool("a"))*(bool("a")+bool("a")))**(bool("a")+bool("a"))+bool("a")+bool("a"))+chr(((bool("a")+bool("a")+bool("a")+bool("a")+bool("a"))*(bool("a")+bool("a")))**(bool("a")+bool("a"))+(bool("a")+bool("a")+bool("a")+bool("a"))*(bool("a")+bool("a")))+chr(((bool("a")+bool("a")+bool("a")+bool("a")+bool("a"))*(bool("a")+bool("a")))**(bool("a")+bool("a"))-bool("a")-bool("a")-bool("a"))+chr(((bool("a")+bool("a")+bool("a")+bool("a")+bool("a"))*(bool("a")+bool("a")))**(bool("a")+bool("a"))+bool("a")+bool("a")+bool("a"))] -``` \ No newline at end of file +``` + +Note: There is an unintended solution to both original JailBreak challenges, which is by abusing Python normalization and submitting a payload such as `𝘱𝘳𝘪𝘯𝘵(𝘧𝘭𝘢𝘨)`. \ No newline at end of file diff --git a/pyjail-revenge/Dockerfile b/pyjail-revenge/Dockerfile new file mode 100644 index 0000000..d492894 --- /dev/null +++ b/pyjail-revenge/Dockerfile @@ -0,0 +1,18 @@ +FROM gcc:14-bookworm AS builder + +RUN apt-get update && apt-get install -y wget && rm -rf /var/lib/apt/lists/* \ + && wget -O ynetd.c https://raw.githubusercontent.com/johnsonjh/ynetd/master/ynetd.c \ + && gcc -o ynetd ynetd.c && rm ynetd.c && chmod +x ./ynetd + +FROM python:3.12-slim-bookworm AS runtime + +WORKDIR /app + +COPY --from=builder /ynetd /app/ynetd + +COPY flag.txt /app/flag.txt +COPY main.py /app/main.py + +EXPOSE 9031 + +ENTRYPOINT [ "./ynetd", "-p", "9031", "python3 main.py" ] \ No newline at end of file diff --git a/pyjail-revenge/chall.yaml b/pyjail-revenge/chall.yaml new file mode 100644 index 0000000..625e467 --- /dev/null +++ b/pyjail-revenge/chall.yaml @@ -0,0 +1,21 @@ +name: JailBreak Revenge +categories: + - misc +value: 125 +flag: + file: flag.txt +description: |- + Some of y'all cheesed the previous two jailbreaks, + so it looks like they've put even more band-aids on + the system... +hints: + - What in python is evaluated to a number? +files: + - src: ./main.py +authors: + - Jack Crowley +visible: false +deploy: + nc: + build: . + expose: 9031/tcp \ No newline at end of file diff --git a/pyjail-revenge/flag.txt b/pyjail-revenge/flag.txt new file mode 100644 index 0000000..2cbe13d --- /dev/null +++ b/pyjail-revenge/flag.txt @@ -0,0 +1 @@ +bcactf{Wr1tING_pyJaiL5_iS_hArD_f56450aadefcc} \ No newline at end of file diff --git a/pyjail-revenge/main.py b/pyjail-revenge/main.py new file mode 100644 index 0000000..1c50d36 --- /dev/null +++ b/pyjail-revenge/main.py @@ -0,0 +1,27 @@ +def sanitize(letter): + print("Checking for contraband...") + return any([(i in letter.lower()) for i in BANNED_CHARS]) or any([ord(l)>120 for l in letter]) + +def end(): + print("Contraband letters found!\nMessages Deleted!") + exit() + +BANNED_CHARS = "gdvxfiyundmpnetkb/\\'\"~`!@#$%^&*.{},:;=0123456789#-_|? \t\n\r\x0b\x0c" +flag = open('flag.txt').read().strip() + +print("Welcome to the prison's mail center") + +msg = input("\nPlease enter your message: ") + +while msg != "": + if sanitize(msg): + end() + + try: + x = eval(msg) + if len(x) != len(flag): end() + print(x) + except Exception as e: + print(f'Error.') + + msg = input("\nPlease enter your message: ") \ No newline at end of file diff --git a/pyjail-revenge/solve.md b/pyjail-revenge/solve.md new file mode 100644 index 0000000..a738024 --- /dev/null +++ b/pyjail-revenge/solve.md @@ -0,0 +1,14 @@ +# JailBreak 2 + +Unlike the first JailBreak, this time the security measures banned numbers. However, this does not factor into the fact the both `True` and `False` are counted as 1 and 0 respectedly. Using the `bool` function, which when presented with a not empty argument evaluates to true, we can then do math to get the the needed ascii values, counting `all(())` as 1. + +```py +locals()[chr(all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(()))+chr(all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(()))+chr(all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(()))+chr(all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(())+all(()))] +``` + +Note that replacing `all(())` here with e.g. `bool(chr)` does not work, as the shell accepts a maximum of 4096 characters. + +Generate this string with +```py +f"locals()[chr({('all(())+'*ord('f'))[:-1]})+chr({('all(())+'*ord('l'))[:-1]})+chr({('all(())+'*ord('a'))[:-1]})+chr({('all(())+'*ord('g'))[:-1]})]" +``` \ No newline at end of file