说明:所有库(除开os、time、sys标准库),按照案例实现的方式,对重要代码进行了总结,方便之后进行复习。
数据包制作/网络通信/扫描相关模块包含了socket、scapy、nmap库
应用程序服务相关模块包含了paramiko、ftplib、pymysql库
网络请求模块包含了urllib、urllib2、request库
进程/多线程/多进程/队列相关模块包含了subprocess、threading、multiprocessing、queue库
命令行解析有argparse库
编码解码包含了base64、hashlib库
常用标准库包含了time、random、re、sys、os库
服务端
# 0x01创建socket对象(AF_INET=IPv4,SOCK_STREAM=流式socket,for TCP) sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 0x02为socket绑定IP端口 sk.bind(('主机地址', 端口)) # 0x03设置监听 sk.listen(5) # 0x04设置堵塞(返回一个通信对象conn 和 一个连接地址 address) conn,address = sk.accept() # 0x05数据交互发送数据 conn.send() # 发送数据 返回值为发送数据字节数量 conn.sendall() # 完整发送数据,返回之前会尝试发送所有数据,成功返回None,失败则抛出异常 # 接收数据 conn.recv(bufsize) # bufsize为接收大小 # 0x06关闭连接 sk.close()
客户端
# 0x01 创建socket对象 sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 0x02连接 sk.connect(('主机地址', 端口)) # 0x03数据交互发送数据 conn.send() #发送数据 返回值为发送数据字节数量conn.sendall() #完整发送数据,返回之前会尝试发送所有数据,成功返回None,失败则抛出异常接收数据 conn.recv(bufsize) # bufsize为接收大小 # 0x04关闭 sk.close()
# 1. 构造arp数据包 arp = Ether(dst='ff:ff:ff:ff:ff:ff')/ARP(pdst='IP段') # 2. 发送数据包(res 保存探测结果 unres 保存未答复的)(srp 二层发包 具有接收功能) res,unres = srp(arp, timeout=2) # 3. 显示结果(res保存着存活主机的结果集,s是res中的一个头部 ,h也是res中的一个头部,只不过,很多信息保存在h头部里。 h.hwsc 代表目的MAC地址,h.psrc代表目的的IP地址。) for s,h in res: print("MAC:"+h.hwsrc+" "+"IP:"+h.psrc)
# 1. 构造tcp端口扫描数据包 tcp = IP(dst='目的IP')/TCP(dport=端口号, flags="S") # 2. 发送数据包(sr1 在三层发送数据包 有接收功能 只接收一个) res = sr1(tcp, timeout=2) # 3 . 判断 接收数据包的TCP头部的flags 含有 SA(端口打开) 或 RA(端口关闭) if res['TCP'].flags == 'SA' 或者 ifres['TCP'].flags =='RA' # 4 . 继续发送数据包 继续完成三次握手 (如果上一步为RA 则直接输出当前端口关闭) res = sr1(IP(dst='目的IP')/TCP(dport=端口号, flags="AR"), timeout=2)
# 1 . 构造icmp数据包 icmp = IP(dst='目的IP', id=100)/ICMP(seq=100, id=100)/b'hello' # 2 . 发送数据包 res = sr1(icmp, timeout=2) # 3 . 判断主机存活和输出结果判断 if res: # 输出结果 # 输出地址 res['IP'].src # 输出ttl值 res.['IP'].ttl
# 1. 构造syn端口扫描数据包 syn = IP(dst='目的IP')/TCP(dport=端口号, flags="S") # 2. 发送数据包(sr1 在三层发送数据包 有接收功能 只接收一个) res = sr1(syn, timeout=2) # 3 . 判断 接收数据包的TCP头部的flags 含有 SA(端口打开) 或 RA(端口关闭) if res['TCP'].flags == 'SA' 或者 ifres['TCP'].flags =='RA' # 4 . 继续发送数据包 完成完成三次握手 (如果上一步为RA 则直接输出当前端口关闭) res = sr1(IP(dst='目的IP')/TCP(dport=端口号, flags="R"), timeout=2)
nmap 扫描参数
主机发现
-sP -sn -sA
端口扫描
-sS -sT -sU
检测应用程序版本和操作系统信息
-sV(应用程序版本) -O(操作系统信息)
脚本使用
--script=vuln(扫描主机是否存在常见漏洞)
# 1 . 创建对象 nm = nmap.PortScanner() # 2 . 填写参数执行扫描(根据参数自定义) nm.scan(hosts='IP/IP段', arguments='-sV -p0-65535') # 3 . 显示结果(返回的对象可以用以下方法进行处理)
PortScanner()类方法
示例
nm.command_line()
1. command_line() 返回扫描方法 2. scaninfo() 返回nmap扫描信息 3. all_hosts() 返回nmap扫描的主机清单
PortScannerHostDict()类方法
示例
nm[‘ip’].hostname()
SSHClient() 类
# 1. 创建ssh对象 client = paramiko.SSHClient() # 2 . 设置远程服务器应对策略 client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 3 . 设置参数进行连接 client.connect(hostname='主机地址' , port='主机端口', username='主机用户名', password='主机密码') # 4 . 执行命令 stdin,stdout,stderr = clinet.exec_command('netstat -lnt')stdout 为正确输出 stderr 为错误输出 两者同时只有一个变量有值# 5 . 输出结果输出 # 正确结果 if stdout: print(stdout.read().decode('utf-8')) # 输出错误结果 if stderr: print(stderr.read().decode('utf-8'))
# 1 . 创建一个通道 transport = paramiko.Transport(('主机地址', 端口号))transport.connect(username='主机用户名', password='主机密码')# 2 . 创建SSHClient对象 ssh = paramiko.SSHClient()ssh._transport = transport # 3 . 执行命令 stdin,stdout,stderr = ssh.exec_command('netstat -lnt') # 4 . 输出结果 # 输出正确结果 if stdout: print(stdout.read().decode('utf-8')) # 输出错误结果 if stderr: print(stderr.read().decode('utf-8'))
# 1 . 创建通道 tran = paramiko.Transport(('主机地址', 端口号))tran.connect(username='主机名', password='主机密码') # 2 . 创建SFTP对象 sftp = paramiko.SFTPClient.from_transport(tran) # 3 . 设置路径 localpath = '本地文件路径'remotepath = '远程文件路径' # 4 . 执行上传 sftp.put(localpath, remotepath) # 5 . 执行下载 stfp.get(remorepath, localpath)
常用方法
mkdir() 在服务上创建目录
remove() 在服务器上删除目录
rename() 在服务器上重命名目录
stat() 查看服务器文件目录
listdir() 列出服务器目录下的文件
# 创建对象 ftp = ftplib.FTP() # 配置连接 # 设置调试级别,显示详细信息 ftp.set_debuglevel(2) # 连接ftp server ftp.connect('主机地址', '端口号') # 登录 ftp.login('ftp用户名', '密码') # 输出欢迎信息 print(ftp.getwelcome()) # 执行操作 # 设置缓冲区大小 bufsize = 1024 # 设置本地路径 localpath = '本地文件路径' # 设置远程文件路径 remotepath = '远程文件路径' # 打开本地路径文件 file = open(filename, 'rb') # 上传文件 ftp.storbinary("STOR"+remotepath, remotepath, bufsize) # 关闭调试信息 ftp.set_debuglevel(0) # 关闭文件 ftp.quit()
# 创建对象ftp = ftplib.FTP()# 配置连接 # 设置调试级别,显示详细信息 ftp.set_debuglevel(2) # 连接ftp server ftp.connect('主机地址', '端口号') # 登录 ftp.login('ftp用户名', '密码') # 输出欢迎信息 print(ftp.getwelcome())# 执行操作 # 设置缓冲区大小 bufsize = 1024 # 设置本地路径 localpath = '本地文件路径' # 设置远程文件路径 remopepath = '远程文件路径' # 打开本地文件路径 file = open(localpath, 'wb').write # 下载文件 ftp.retrbinary("RETR"+remopepathf, file, bufsize) # 关闭调试信息 ftp.set_debuflevel(0) # 关闭文件 ftp.quit()
相关方法
ftp.dir() 显示目录下所有目录信息
ftp.nlst() 获取目录下的文件
ftp.pwd() 返回当前所在位置
ftp.cwd(pathname) 设置FTP当前操作路径
ftp.mkd(pathname) 新建远程目录
ftp.rmd(dirname) 删除远程目录
ftp.delete(filename) 删除远程文件
ftp.rename(fromname, toname) 将fromname 修改名称为 toname
(查阅资料后 两个库基本方法均一致 用pymyql演示)
# 创建连接 conn = pymysql.connect('主机地址', 'mysql用户名', '密码', '数据库') # 创建游标 cur = conn.cursor() # 执行 sqlcur.execute(sql语句) # 输出结果 data = cur.fetchone() # 输出一条结果 data = cur.fetchall() # 输出所有结果 # 关闭游标 cur.close() # 关闭连接 conn.close()
# 创建连接 conn = pymysql.connect('主机地址', 'myql用户名', '密码', '数据库') # 创建游标 cur = conn.cursor() # 执行 sqlcur.execute("update 表名 set 字段名='新值' where 条件 ") # 关闭游标 cur.close() # 执行DML语句 保存方法 cur.commit() # 关闭连接 conn.close()
相关SQL语句:
增:
增加表
create table 表名 (字段名 字段类型 其他, 字段名 字段类型 其他, ...);
增加字段
alter table 表名 add 字段 类型 其他;
删:
删除表
drop table 表名
删除表中数据
delete from 表名 where 表达式
改:
改表名
rename table 原表名 to 新表名;
改字段
update 表名 set 字段=新值 where 条件
# 设置提交url url = 'http://127.0.0.1/DVWA/vulnerabilities/xss_s/' # 设置请求头部 headers = {'cookie': 'cookie值'} # POST提交data 参数 data = {'txtName': '标题', 'mtxMessage': '内容', 'btnSign': 'Sign Guestbook'} # data 进行url编码 data = urllib.urlencode(data) # 构建Request 对象 request = urllib2.Request(url, data, headers) # 请求urlopen() 只接收url, data, timeout 三个参数 resp = urllib2.urlopen(request) # 输出结果 print(resp.read())
# 设置爬取的url url = "http://127.0.0.1/DVWA/vulnerabilities/xss_s/" # 设置头部 headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36', 'Cookie': ' security=impossible; PHPSESSID=adcc9b21be4a5689bc5fa145a9f15a25'} # 构造Request对象 request = urllib2.Request(url=url, headers=headers) # 请求urlopen() resp = urllib2.urlopen(request) str1 = resp.read() # 正则匹配内容数据(绿色部分为正则表达式) result = re.findall('<div id="guestbook_comments">Name: ([a-z1-9A-Z]+)<br />Message: ([a-zA-Z0-9]+)<br /></div>', str1) # 输出 for item in result: print('Name:'+item[0]+'Content:'+item[1])
功能:python3下 urllib 进行POST提交数据(dvwa xss 提交数据为例)
(说明:python3下 urllib和urllib2 合并成了一个urllib 这个包分为四个模块 ) (分为:urllib.request urllib.error urllib.parse urllib.robotaparser)
# 设置提交链接 url = ' http://127.0.0.1/DVWA/vulnerabilities/xss_s/' # 设置headers头部 headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36','Cookie':'security=low; PHPSESSID=c53448691f29843f229d25fdc0b4871a'} # 构建data数据 data = {'txtName': 'python3', 'mtxMessage': 'connect', 'btnSign': ' Sign Guestbook'} # data进行url编码 data = urllib.parse.urlencode(data) # 构建request对象 request = urllib.request.Request(url, data.encode('utf-8'), headers) # urllib.request.urlopen()提交 resp = urllib.request.urlopen(request)
# 设置url url = 'http://127.0.0.1/DVWA/vulnerabilities/xss_s/ ' # 设置头部 headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36','Cookie': 'security=low; PHPSESSID=c53448691f29843f229d25fdc0b4871a'} # 构建request request = urllib.request.Request(url=url, headers=headers) # urlopen() 进行请求 resp = urllib.request.urlopen(request) # 用re正则 对返回结果进行处理(转为返回结果文本格式为gbk) str1 = resp.read().decode('gbk') res = re.findall('<div id="guestbook_comments">Name: ([a-z1-9A-Z]+)<br />Message: ([a-zA-Z0-9]+)<br /></div>', str1) # 输出结果 print('Tittle'+'\t'+'Connect')for item in res: print(item[0] + '\t\t' + item[1])
# 设置提交url地址 url = 'http://127.0.0.1/DVWA/vulnerabilities/xss_s/ ' # 构建headers头部 headers = {'User-Agent': ' Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36','Cookie': ' security=low; PHPSESSID=c53448691f29843f229d25fdc0b4871a'} # 构建需要提交的data数据 data = {'txtName': 'request', 'mtxMessage': '123456789', ' btnSign':' Sign Guestbook'} # 进行提交 resp = request.post(url=url, data=data, headers=headers)
# 设置url链接 url = ' http://127.0.0.1/DVWA/vulnerabilities/xss_s/' # 构建headers头部 headers = {'User-Agent': ' Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36','Cookie': ' security=low; PHPSESSID=c53448691f29843f229d25fdc0b4871a'} # 进行提交 resp = request.get(url=url, headers=headers)str1 = resp.text # 用re正则对返回结果进行处理 res = re.findall('<div id="guestbook_comments">Name: ([a-z1-9A-Z]+)<br />Message: ([a-zA-Z0-9]+)<br /></div>', str1) # 输出 print('Tittle'+'\t'+'Connect')for item in res: print(item[0] + '\t\t' + item[1])
功能:subprocess实现执行命令输出结果
(subprocess 有4个方法都可以实现创建子进程功能,四个方法都是对Popen()方法的封装)(分别为:call() check_call() check_output() 以及3.5之后代替前三个方法的run())
run()方法
# 调用子进程(返回CompletedProcess对象) s = subprocess.run(['ipconfig', '-all'], stdout=subprocess.PIPE, shell=True) # 输出结果 print(s.stdout.decode('GBK'))
Popen()方法(支持stdin和stdout)
# 调用子进程(返回subprocess.Popen对象) s = subprocess.Popen('python', stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) # 输入 s.stdin.write(b'import sys \n') s.stdin.write(b'print(sys.version) \n') s.stdin.close() # 输出 print(s.stdout.read().decode('GBK')) s.stdout.clode()
# 创建socket对象 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接到远程主机 s.connect(('主机地址', 端口号)) # 将socket对象的文件描述符复制到系统 0标准输入 1标准输出 2标准错误 #(os.dup2(fd, fd2) 将文件描述符fd复制到fd2 ) # (s.fileno() 获取socket对象的文件描述符) os.dup2(s.fileno(), 0) os.dup2(s.fileno(), 1) os.dup2(s.fileno(), 2) # 调用call() 执行指令 p = subprocess.call(['/bin/bash', '-i'])
功能:执行输出任务,创建十条线程,同步执行
# 创建一个需要用多线程完成的任务 def task(num): for _ in range(10): print('[+] this is %s'%(num)) print('[+] %s end'%(num)) # 创建线程池 threads = [] # 创建多线程并启动多线程 for i in range(11): thread = threading.Thread(target=task, args=(i,), name='线程名') threads.append(thread) thread.start() # 设置堵塞 for thread in threads: thread.join()
# 创建一个需要用多进程完成的任务 def worker(num): for _ in range(10): print("[+] This is %s"%(num)) print("[+] %s end"%(num)) # 创建进程池 courses = [] # 创建进程并启动多进程 for i in range(10): course = multiprocess.Process(target=worker, args=(i,), name='进程名') courses.append(course) courses.start() # 设置堵塞 for course in courses: course.join()
# 导包 from multiprocess.dummy import Pool as ThreadPool # 创建一个需要用多线程完成的任务 def worker(num): print('[+] This is %s'%(num)) time.sleep(1) # 开4个 worker, 没有参数时默认是cpu的核心数 pool = ThreadPool(4) # 设置任务所需参数(把列表遍历完,就会结束, 写爬虫的时候可以用来遍历url) nums = [1,2,3,4,5,6,7,8,9,0] # 执行任务(同时执行4个任务,相当于每次遍历4个,遍历完就结束) results = pool.map(worker, nums) # 关闭和阻塞 pool.close() pool.join()
功能:从文件中读取字符保存到队列(queue对象)中,再进行输出
# 设置读取文件路径 filePath = 'file.txt' # 创建队列 q = queue.Queue() # 打开文件并输出到队列 with open(filePath) as f: for line in f: password = line.strip('\n') q.put(password) # 输出队列 while True: if not q.empty(): print(q.get()) else: break
功能:实现创建命令行选项
# 创建对象 parse = argparse.ArgumentParser(description='在-h中显示的解析注释') # 添加参数 #(add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar] [, dest] )) parse.add_argument('-f', '--file', dest='filename', help='set filename path') parse.add_argument('-y', '--yes', action='store_false', help="action default false ") # 解析参数 args = parse.parse_args()
(说明:因编码只能是bytes 需要进行utf-8编码 输出的时候 需要str 进行转码输出)
# 定义字符串 str1 = "system('cat /flag.txt');" # 字符串utf-8编码 str1 = str1.encode(encoding='utf-8') # base64编码 en_str = base64.b64encode(str1) print("base64编码前:"+ str(str1)) print("base64编码后:" + str(en_str)) # base64解码 de_str = base64.b64decode(en_str) print("base解码前:"+str(en_str)) print("base解码后:"+str(de_str))
# 定义字符串 str1 = 'This is not md5' # 字符串编码 str1 = str1.encode(encoding='utf-8') # 创建md5对象 m = hashlib.md5() # 加密 m.update(str1) str1_md5 = m.hexdigest() # 输出 print("MD5加密前:"+str(str1)) print("MD5加密后:"+str1_md5)
(三种方式表示时间:1.timestamp(时间戳) 2. struct_time (格式化的时间字符串) 3. tuple(元组))
时间格式相互转化关系图
time()
localtime([secs])
asctime([t])
mktime(t)
sleep(secs)
gmtime([secs])
ctime([secs])
strftime(format[, t])
strptime(string[, format])
random.random() >>>0.2786970302306403
uniform(a, b)
random.uniform(1, 10) >>>2.431852539010123 random.uniform(20,100) >>>87.86159294411607
random.randint(1, 20) >>>18 random.randint(20, 50) >>>26
choice(squence)
x = [2,3,4,1,5,6,7,8,9]
random.choice(x)
3
x = [2,3,4,1,5,6,7,8,9]
random.choice(x)9
sample(sequence, k)
x = [1,2,3,4,5,6,7,8] random.sample(x, 2) >>>[8,4] x = [1,2,3,4,5,6,7,8] random.sample(x, 4) >>>[1,6,3,5]
x = [1,2,3,4,5,6,7,8] random.shuffle(x) >>>[3, 2, 7, 1, 6, 8, 4, 5]
修饰符
(对应flags)1. re.I 忽略大小写 2. re.L 做本地化识别(locale-aware)匹配 3. re.M 多行匹配,影响^和$ 4. re.S 即为.并且包括换行符在内的任意字符(.不包括换行符) 5. re.U 表示特殊字符集\w,\W,\b,\B,\d,\D,\s,\S 依赖于Unicode字符属性数据库 6. re.x 为了增加可读性,忽略空格和#后面的注释
正则表达式常用模式
模式 | 描述 |
---|---|
^ | 匹配字符串的开头 |
$ | 匹配字符串的末尾 |
[…] | 用来表示一组字符[0-9] [a-z] … |
[0-9] | 匹配任何数字 |
[a-z] | 匹配任何小写字母 |
[A-Z] | 匹配任何大写字母 |
re{n} | 精确匹配n个前面表达式 |
re{n,m} | 匹配n到m次由前面的正则表达式定义的片段 |
a|b | 匹配a或b |
(re) | 对正则表达式分组并记住匹配的文本 |
\w | 匹配字母数字及下划线 |
\W | 匹配非字母数字及下划线 |
\s | 匹配任意空白字符 |
\S | 匹配任意非空字符 |
\d | 匹配任意数字 |
\D | 匹配任意非数字 |
正则表达式常用方法
pattern = re.compile(r'\d+') res = pattern.match('one12twothree34four') >>>none res = pattern.search('one12twothree34four') >>> <_sre.SRE_Match object; span=(2, 4), match='12'> >>>m.group() >>>'12' res = pattern.findall('one12twothree34four') >>>['12', '34']
re.search(pattern, string[, flags])
res = re.search(r'\d+', 'abcdefghijkl123lnm345') res.group() >>>'123'
res = re.match(r'\d+', 'abcdef123lijklm345') >>>none res = re.match(r'\d+', '123abcdef456') >>>res.group() >>>'123'
res = re.findall(r'\d+', 'abc123def456lkj789') >>>['123', '456', '789']
sys模块负责程序与python解释器的交互,提供了一系列的函数和变量,用于操控python的运行时环境。
sys.argv[0]
sys.platform
sys.executable
sys.modules
sys.builtin_module_names
sys.path
sys.stdin
sys.stdout
sys.err
sys.getrecursionlimit()
sys.setrecursionlimit()
sys.getrefcount()
sys.getsizeof()
sys.ps1
sys.ps2
os模块负责程序与操作系统的交互,提供了访问操作系统底层的接口
(参考: https://docs.python.org/zh-cn/3.6/library/os.html,https://www.runoob.com/python/python-os-path.html , https://www.runoob.com/python/os-file-methods.html)
文件
和目录
、进程
、文件标识符
、路径
)os.access(path, mode)
os.chdir(path)
os.chflags(path, flags)
os.chmod(path, mode)
os.chown(path, uid, gid)
os.chroot(path)
os.fchdir(fd)
os.getcwd()
os.link(src, dst)
os.symlink(src, dst)
os.listdir(path)
os.mkdir(path[,mode])
os.makedirs(name[, mode])
os.mkfifo(path[, mode])
os.remove(path)
os.removedirs(name)
os.rmdir(path)
os.rename(src, dst)
os.renames(old, new)
os.replace(src, dst)
os.stat(path)
函数
对文件描述符
所引用的I/O 流
进行操作
。)os.closerange(fd_low, fd_high)
os.dup(fd)
os.dup2(fd, fd2)
os.fchdir(fd)
os.fchmod(fd, mode)
os.fchown(fd, uid, gid)
os.fdatasync(fd)
os.fdopen(fd)
os.fpathconf(fd, name)
os.fstat(fd)
os.fstatvfs(fd)
os.open(path, flags, mode=0o77)
os.write(fd, str)
os.read(fd, n)
操作当前进程
和用户的信息
。)os.getlogin()
os.uname()
os.setgid(gid)
os.setsid()
os.setuid(uid)
os.getgid()
os.getsid(pid)
os.getuid()
os.getpid()
os.setegid(egid)
os.seteuid(euid)
os.getegid()
os.geteuid()
os.setpgid(pid, pgrp)
os.getpgid(pid)
创建
和管理进程
)os._exit(n)
os.fork()
os.forkpty()
os.kill(pid, sid)
os.popen(command[, mode[, bufsize]])
os.system(command)
路径名
上实现了一些有用的功能
)