{"id":26784726,"url":"https://github.com/theflash2k/pwn-chal","last_synced_at":"2025-06-14T14:04:27.645Z","repository":{"id":240208895,"uuid":"777740420","full_name":"TheFlash2k/pwn-chal","owner":"TheFlash2k","description":"A simple image to help you get your PWN/remote challenges up and running in no time","archived":false,"fork":false,"pushed_at":"2025-04-24T07:11:11.000Z","size":22777,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-24T08:24:37.919Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TheFlash2k.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-03-26T12:26:33.000Z","updated_at":"2025-04-24T07:11:15.000Z","dependencies_parsed_at":"2024-05-17T10:42:34.774Z","dependency_job_id":"8cec21d4-1542-4bcb-a09b-1acb3e6f133c","html_url":"https://github.com/TheFlash2k/pwn-chal","commit_stats":null,"previous_names":["theflash2k/pwn-chal"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/TheFlash2k/pwn-chal","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheFlash2k%2Fpwn-chal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheFlash2k%2Fpwn-chal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheFlash2k%2Fpwn-chal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheFlash2k%2Fpwn-chal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TheFlash2k","download_url":"https://codeload.github.com/TheFlash2k/pwn-chal/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TheFlash2k%2Fpwn-chal/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259827505,"owners_count":22917709,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-03-29T10:29:27.165Z","updated_at":"2025-06-14T14:04:27.631Z","avatar_url":"https://github.com/TheFlash2k.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"## PWN-CHAL - Easy remote PWN challenges deployment\n\n[Dockerhub](https://hub.docker.com/repository/docker/theflash2k/pwn-chal/)\n\n[Github](https://github.com/TheFlash2k/pwn-chal)\n\nYou can use this image to easily deploy your challenges without having to setup anything.\n\nUnder the hood, pwn-chal utilizes [`ynetd`](https://github.com/johnsonjh/ynetd) to serve the challenge to host. `socat` can be utilized as well by setting `BASE` environment variable.\n\nA sample Dockerfile is as follows:\n\n```dockerfile\nFROM theflash2k/pwn-chal:latest\n\nENV CHAL_NAME=baby-pwn\nCOPY ${CHAL_NAME} ${CHAL_NAME}\nCOPY flag.txt flag.txt\n```\n\n| **NOTE**: Challenge binary **MUST** be placed inside the `/app` directory. Default WORKDIR is set to `/app`\n\nThe binaries will run in the context of user `ctf-player` rather than root.\n\n| This CAN be overriden with the use of **OVERRIDE_USER** environment variable\n\nFollowing environment variables can be changed to your own likings:\n```bash\nCHAL_NAME\nPORT\nBASE\nSTART_DIR\nFLAG_FILE\nOVERRIDE_USER\nSETUID_USER\nREDIRECT_STDERR\nNO_FLAG\nADD_READFLAG\nROOT_ONLY_FLAG\nOUTBOUND_BLOCK\nPOW\n```\n\nThere are other image-specific environment variables as well:\n\n- [Kernel](#kernel)\n- [Windows](#windows)\n- [ARM/ARM64](#arm--arm64)\n\n\n### CHAL_NAME\nThis is the name of the challenge binary. (I know, should've been `CHAL_BIN` or something, but ;-;).\n\n### PORT\nThe port that the challenge will listen on internally. The default port is `8000`\n\n### BASE\nThe BASE binary to use for listening. Can be one of the following:\n1. ynetd [Default]\n2. socat\n\n### START_DIR\nIn case the challenge gives a shell, this is the directory the user will land in. Default is `/app`.\n\n### FLAG_FILE\nUser can specify the path to the flag file. Needs to be an absolute value as the container will set `chattr +i` on this file. Default is `/app/flag.txt`. In case the flag_file is random, chattr won't work place but file will exist.\n\n| **NOTE**: There is a `FLAG_FILE_SYMLINK` environment variable, which isn't set by default, but if set, will generate a symlink for the flag in `/app/flag.txt` if `FLAG_FILE` is not `/app/flag.txt`.\n\n| **NOTE**: When using `theflash2k/pwn-chal:windows`, make sure to put flag in `/app/flag.txt` or set the `FLAG_FILE` accordingly. Randomly generated flag files may not work as the flag will be copied from `/app/flag.txt` or `$FLAG_FILE` to `C:\\flag.txt`\n\n### OVERRIDE_USER\nBy default, the binaries will run in the context of `ctf-player` user. This can be overriden by `OVERRIDE_USER` variable. It can be a valid user. But, if the user doesn't exist, it will default to `root`.\n\n### SETUID_USER\nThis environment variable will change owner and group of `CHAL_NAME` to `SETUID_USER` and then give it `suid` permissions. And will run as `OVERRIDE_USER`. Permission set is `4755`. if `SETUID_USER` doesn't exist, it will default to `root`.\n\n| **NOTE**: When the `SETUID_USER` is set, `FLAG_FILE` will automatically be set to `400`, i.e. `READ-ONLY` to `$SETUID_USER`. This can be overriden with the `FORCE_FLAG_RO` parameter. Just set that to any value except `y` and the flag will be `440`.\n\n### REDIRECT_STDERR\nThis environment variable will simply allow redirection of stderr through the socket. By default it is set to `y`, meaning that stderr will also be redirected.\n\n### NO_FLAG\nThis environment variable will simply remove the `$FLAG_FILE`. (Made this specifically for Showdown-based challenges where there's a submitter binary.)\n\n### ADD_READFLAG\nThis environment variable will set the \n\n### ROOT_ONLY_FLAG\nThis will set the flag to be read only by root user and no one else. The use-case for this particular flag is when we're trying to use a SUID `readflag` binary. Default `n`\n\n### OUTBOUND_BLOCK\nThis blocks all the outbound connection. This is done using `iptables` so `CAP_NET_ADMIN` is required for the running container. If it is not provided, it doesn't SOFT-EXIT, but rather continues anyways. (Default=`y`)\n\n### POW\nProof of Work. The value can be between 0-256. Default is `0`. 256 means HAAARD. Usually, you go for `25-32`.\n\u003e The POW was originally implemented by HXPCTF team. You can see in [pow](utilities/pow/pow) script\n\n---\n\nEnvironment variables may also be specified with the docker run command:\n```bash\ndocker run -it --rm -e PORT=5012 -p 54251:5012 -e BASE=socat theflash2k/pwn-chal:latest\n```\n\n| **NOTE**: If no `CHAL_NAME` is provided, the default binary will run on the specified port and upon connecting, you'll get the following message:\n\n```\npwn-chal container successfully deployed. Please setup your challenge by specifying the CHAL_NAME environment variable and placing your binary in /app.\nRegards,\nTheFlash2k\n```\n\n## Image-specific details\n\n## Kernel:\n\nFor the kernel image, I decided to use QEMU under-the-hood. You can modify the following variables\n\n### KASLR:\nBy default, KASLR (Kernel Address Space Layout Randomization) is set to `1`, i.e. it will be enabled. You can modify it by setting either `0` or `1` .\n\n### KPTI:\nBy default, KPTI (Kernel Page Table Isolation) is set to `1`, i.e. it will be enabled. You can modify it by setting either `0` or `1` .\n\n### SMEP:\nBy default, SMEP (Supervisor Mode Execution Prevention) is set to `1`, i.e. it will be enabled. You can modify it by setting either `0` or `1` .\n\n### SMAP:\nBy default, SMAP (Supervisor Mode Access Prevention) is set to `1`, i.e. it will be enabled. You can modify it by setting either `0` or `1` .\n\n### PANIC_ON_OOPS:\nBy default, Panic on OOPS is set to `1`, i.e. it will be enabled. You can modify it by setting either `0` or `1` .\n\n### MODE:\n`MODE` specifies how your payload will be downloaded/placed inside the vm. There are two available options:\n\n- remote: This prompts the user to enter a URL from which the exploit will be downloaded. [DEFAULT]\n- stdin: This prompts the user to enter a base64 encoded payload and then decodes it and stores it inside the vm.\n\n### VM_MEMORY:\nThe amount of RAM that will be allocated to the virtual machine\n\n### INITRAMFS:\nThe INITRAMFS file name. This file MUST be stored at `/app`. \nDefault name is: `initramfs.cpio.gz`.\n\n### KERNEL:\nThe name of the KERNEL. This file MUST be stored at `/app`.\nDefault name is: `vmlinuz`\n\n### CPU:\nThe CPU that will be passed to the underlying qemu. There are two available options:\n- `qemu64` [DEFAULT]\n- `kvm64`\n\n### SMP:\nThe CPU threads/cores defined in SMP will be passed directly.\nBy default it is set to `1`.\n\n## Windows\n\nSince the `windows` machine uses `wine` under the hood to run the binaries and `xvfb` to emulate a virtual display, following variables can be modified:\n\n### WINEARCH:\n\nThis will let wine know whether the `CHAL_NAME` binary is a `x86` or `x64` binary.\n\n### WINEPREFIX:\n\nThis is the folder that contains the wine configurations, if the configurations do not already exist, they will take around 10-15 seconds to generate the entire configurations. By default, `$RUN_AS/.wine` is set as the WINEPREFIX and upon each container start, the configs are automatically generated.\n\n### WIN_DEBUG:\n\nThis is a custom variable, if set to any value, it will use `ynetd` to serve the `wine`-served binary and upon crash, it will show the debug logs to the user on the connection. If you want to see detailed logs, you can also set the `REDIRECT_STDERR=y` so that all the stderr logs are also passed through the socket. However, this should only be used when trying a challenge locally.\n\n| **NOTE**: Since ASLR is disabled by default in the wine configuration, all `ASLR` related challenges might not work as expected.\n\n## ARM \u0026 ARM64\n\nIn order to run the `arm` and `arm64` containers, you need to run the following command on the host first:\n\n```bash\n# Install the qemu packages\nsudo apt-get install qemu binfmt-support qemu-user-static\n\n# This step will execute the registering scripts\ndocker run --rm --privileged multiarch/qemu-user-static --reset -p yes\n```\n\nFor debugging, you can set the following environment variable:\n\n### QEMU_GDB_PORT\n\nThis port will be passed to the underlying `qemu-arm` command and will enable remote GDB debugging on the specified port.\n\n| **NOTE**: When debugging is enabled, the container will run, and run the GDB port on the specified port, and since the program will run in a `while [[ 1 ]]` loop, it will continue to do so. However, the `stdin`, `stdout` and `stderr` aren't redirected to GDB, and therefore, running the container with `-d` option will not work the way you'd expect it to.\n\nIf you know how to fix it, please contact me, or a simple Pull Request with the fix ;).\n\nA sample Dockerfile with debugging enabled:\n\n```dockerfile\nFROM theflash2k/pwn-chal:arm\n\nENV CHAL_NAME=baby-arm\nENV QEMU_GDB_PORT=7000\n\nCOPY ${CHAL_NAME} ${CHAL_NAME}\n```\n\n## Tags:\n\n| Tag | Version | Usage |\n| --- | --- | --- |\n| latest | Ubuntu 25.04@sha256:9a302811bba2ae9533ddae0b563af29c112f1262329e508f13c0c532d5ba7c19 | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/latest) |\n| 2504 | Ubuntu 25.04@sha256:9a302811bba2ae9533ddae0b563af29c112f1262329e508f13c0c532d5ba7c19 | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/2504) |\n| 2410 | Ubuntu 24.10@sha256:02b7410af4f33ca28aad0764e34bb7442ef739ff253ea6c28e008e20f8921c52 | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/2410) |\n| 2404 | Ubuntu 24.04@sha256:6e75a10070b0fcb0bead763c5118a369bc7cc30dfc1b0749c491bbb21f15c3c7 | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/2404) |\n| 2304 | Ubuntu 23.04@sha256:5a828e28de105c3d7821c4442f0f5d1c52dc16acf4999d5f31a3bc0f03f06edd | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/2304) |\n| 2204 | Ubuntu 22.04@sha256:3d1556a8a18cf5307b121e0a98e93f1ddf1f3f8e092f1fddfd941254785b95d7 | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/2204) |\n| 2004 | Ubuntu 20.04@sha256:e5a6aeef391a8a9bdaee3de6b28f393837c479d8217324a2340b64e45a81e0ef | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/2004) |\n| 1804 | Ubuntu 18.04@sha256:152dc042452c496007f07ca9127571cb9c29697f42acbfad72324b2bb2e43c98 | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/1804) |\n| 1604 | Ubuntu 16.04@sha256:1f1a2d56de1d604801a9671f301190704c25d604a416f59e03c04f5c6ffee0d6 | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/1604) |\n| kernel | Ubuntu 25.04@sha256:9a302811bba2ae9533ddae0b563af29c112f1262329e508f13c0c532d5ba7c19 with QEMU | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/kernel) |\n| x86 | theflash2k/pwn-chal:latest with gcc-multilib installed for 32-bit support | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/x86) |\n| x86-cpp | theflash2k/pwn-chal:latest with g++-multilib installed for 32-bit support | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/x86-cpp) |\n| seccomp | theflash2k/pwn-chal:latest with libseccomp-dev installed | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/seccomp) |\n| py38 | python:3.8-slim-buster with my magic | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/py38) |\n| py311 | python:3.11-slim-buster with my magic | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/py311) |\n| crypto | python:3.11-slim-buster with Pycryptodome and my magic | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/crypto) |\n| sagemath | Using sagemath/sagemath:latest Docker image | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/sagemath) |\n| cpp | theflash2k/pwn-chal:latest with libstdc++ for C++ support | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/cpp) |\n| arm | 25.04@sha256:9a302811bba2ae9533ddae0b563af29c112f1262329e508f13c0c532d5ba7c19 with QEMU [Also with GDB Remote Debugging] | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/arm) |\n| arm64 | 25.04@sha256:9a302811bba2ae9533ddae0b563af29c112f1262329e508f13c0c532d5ba7c19 with QEMU [Also with GDB Remote Debugging] | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/arm64) |\n| windows | Ubuntu 20.04@sha256:e5a6aeef391a8a9bdaee3de6b28f393837c479d8217324a2340b64e45a81e0ef with WINE and XVFB | [Github](https://github.com/TheFlash2k/pwn-chal/tree/master/samples/windows) |\n\n## Known Bugs:\n\n- Both ARM/ARM64 and Windows do not have `ASLR` and `PIE`, so the stack and library addresses are always constant.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheflash2k%2Fpwn-chal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftheflash2k%2Fpwn-chal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftheflash2k%2Fpwn-chal/lists"}