Socat 比如某场比赛的文件目录如下
run.py
1 2 3 4 5 6 7 8 9 10 11 12 import  osimport  sysif  len (sys.argv) != 2 :    print ("Usage: %s [port]"  % sys.argv[0 ])     sys.exit(1 ) port = sys.argv[1 ] command = 'socat -d -d tcp-l:'  + port + ',reuseaddr,fork EXEC:"python -u server.py" '  os.system(command) 
 
前面加个nohup可以在端口一直运行
1 $  nohup socat -d -d tcp-l:[port],reuseaddr,fork EXEC:"python -u server.py"  
 
Docker Docker命令 创建镜像
1 $  docker build . -t [images_name] 
 
查看创建的镜像
 
创建容器
1 $  docker run --name [container_name] -d [-idt] -p [host_port]:[container_port] [images_name] 
 
-d表示不进入容器内部 
-p表示将容器内部的port_inner端口映射到port_outer端口 
-idt表示创建守护进程(没有这个容器创建完程序就退出了,不太清楚 
 
查看正在运行的容器
 
停止容器
1 $  docker stop [container_id] 
 
删除容器
1 $  docker rm [container_id] 
 
删除镜像
 
进入容器
1 2 $  docker attach [container_id] $  docker exec  -it [container_id] bash 
 
常用Dockerfile语法  
 
这里以一道极其简单nc拿flag的题目为例
server.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 from  hashlib import  sha256import  socketserverfrom  secret import  flagimport  signalimport  stringimport  randomimport  osclass  Task (socketserver.BaseRequestHandler ):    def  _recvall (self ):         BUFF_SIZE = 2048          data = b''          while  True :             part = self.request.recv(BUFF_SIZE)             data += part             if  len (part) < BUFF_SIZE:                 break          return  data.strip()     def  send (self, msg, newline=True  ):         try :             if  newline:                 msg += b'\n'              self.request.sendall(msg)         except :             pass      def  recv (self, prompt=b'[-] '  ):         self.send(prompt, newline=False )         return  self._recvall()     def  proof_of_work (self ):         random.seed(os.urandom(8 ))         proof = '' .join(             [random.choice(string.ascii_letters+string.digits) for  _ in  range (20 )])         _hexdigest = sha256(proof.encode()).hexdigest()         self.send(f"[+] sha256(XXXX+{proof[4 :]} ) == {_hexdigest} " .encode())         x = self.recv(prompt=b'[+] Plz tell me XXXX: ' )         if  len (x) != 4  or  sha256(x+proof[4 :].encode()).hexdigest() != _hexdigest:             return  False          return  True      def  handle (self ):         signal.alarm(60 )         if  not  self.proof_of_work():             self.send(b'[!] Wrong!' )             return          self.send(b'here is your flag' )         self.send(flag) class  ThreadedServer (socketserver.ThreadingMixIn, socketserver.TCPServer ):    pass  class  ForkedServer (socketserver.ForkingMixIn, socketserver.TCPServer ):    pass  if  __name__ == "__main__" :    HOST, PORT = '0.0.0.0' , 10001      server = ForkedServer((HOST, PORT), Task)     server.allow_reuse_address = True      print (HOST, PORT)     server.serve_forever() 
 
DockerFile
1 2 3 4 5 6 7 8 9 10 11 FROM  python:3.8 LABEL  Description="baby_try"  VERSION='1.0'  COPY  server.py . COPY  secret.py . RUN  chmod +x server.py EXPOSE  12345 	CMD  ["python" , "server.py" ] 
 
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 import  hashlibfrom  string import  ascii_letters, digitsfrom  pwn import  *from  itertools import  producttable = ascii_letters + digits class  Solve ():    def  __init__ (self ):         self.sh = remote('127.0.0.1' , 12345 )              def  proof_of_work (self ):                           proof = self.sh.recvuntil(b'[+] Plz tell me XXXX:' )         tail = proof[16 :32 ].decode()         _hash  = proof[37 :101 ].decode()         for  i in  product(table, repeat=4 ):             head = '' .join(i)             t = hashlib.sha256((head + tail).encode()).hexdigest()             if  t == _hash :                 self.sh.sendline(head.encode())                 break      def  solve (self ):         self.proof_of_work()         self.sh.recvline()         flag = self.sh.recvline()[:-1 ].decode()         print (flag)         self.sh.close() if  __name__ == '__main__' :    solution = Solve()     solution.solve() 
 
Step1 创建镜像 1 $  docker build . -t baby_try 
 
Step2 启动容器 1 $  docker run --name trytry -d -idt -p 12345:10001 baby_try 
 
将端口映射到本地12345端口
Step3 尝试exp打本地 没什么问题
Step4 挂载服务器 本地没问题后,就要部署到服务器上
使用Docker Compose 在过载服务器的时候还可以编写docker-compose.yml简化创建镜像和启动容器的步骤,如下
1 2 3 4 5 6 7 8 version:  '3' services:   checkin:      image:  signin      build:  .      ports:       -  "9999:10001"      restart:  always  
 
然后输入命令一键搭建
 
遇到的一些问题 
镜像搭建太慢 
容器创建完程序就退出了 
题目本身有问题 
 
此外,pwn题的部署有现成工具:https://github.com/giantbranch/pwn_deploy_chroot 
Reference 
Soreat_u-How to Setup for Interactive Crypto Problems?