目录
1.2安装过程中勾选下面的add Python 3.9 to PATH
1.5如果提示命令不存在没有运行的话,找到安装路径即python.exe所在目录,复制地址
1.6右击此电脑打开属性找到高级系统设置>打开环境变量Windows10系统
1.7path>编辑>新建>将复制的路径粘贴进去>确定>确定>再次打开命令提示符运行python
1.dict中通过调用什么函数将key与value循环匹配出来?
2.1.1解压master时可能会遇到解压失败的情况,这里分享一下我的解压过程
前言
Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆于1990年代初设计,作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python还为我们提供了非常完善的基础代码库,覆盖了网络、文件、GUI、数据库、文本等大量内容,被形象地称作“内置电池(batteries included)”。用Python开发,许多功能不必从零编写,直接使用现成的即可。当然除了这些优点外,python的第一个缺点就是运行速度慢,和C程序相比非常慢,因为Python是解释型语言,你的代码在执行时会一行一行地翻译成CPU能理解的机器码,这个翻译过程非常耗时,所以很慢。而C程序是运行前直接编译成CPU能执行的机器码,所以非常快。
1.下载安装
1.1选择你需要选择的版本
1.2安装过程中勾选下面的add Python 3.9 to PATH
1.3接着Win+R键输入cmd打开命令提示符
1.4输入python查看是否运行
1.5如果提示命令不存在没有运行的话,找到安装路径即python.exe所在目录,复制地址
1.6右击此电脑打开属性找到高级系统设置>打开环境变量Windows10系统
1.7path>编辑>新建>将复制的路径粘贴进去>确定>确定>再次打开命令提示符运行python
1.8pycharm的使用准备
链接:https://pan.xunlei.com/s/VN7cUEGEZ-9PWhqCX9jMAXpTA1
提取码:gymw
2.数据类型
2.1整数
- python可以处理任何整数包括负整数,例如:0,-22,1000...
- 计算机中由于使用二进制,故用十六进制来表达整数更加方便,通常以0x,0-9,a-f表示,例如:0x3a,0xa3b5...
2.2浮点数
- 浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时,一个浮点数的小数点位置是可变的,对于很大或很小的浮点数,就必须用科学计数法表示,把10用e替代,;例如:1.23,12.34,2.56X10^8=2.56e8,0.0034=3.4e-3
2.3字符串
- 字符串就是'和“括起来的内容,其本身不是字符串的一部分,如果想要将'表示成字符串的内容可以使用”括起来,如果需要'和“都在字符串内则需要转义符\进行转义,当然转义符如果需要也可以对转义符转义,当需要出现'\\a\\\'中的\不用转义时可以使用r'\\a\\\'来进行编写例如:' I\'m \"OK\"! ' ,'\\','I\'m\n\"OK\"!'
2.4布尔值
- 布尔值只有两种True,False,可以通过与或非来进行编写,例如True and True,True or False,True not False,与运算为全真(全部为True),或运算为存真(一个True)
2.5空值
- 用None来表示,特殊的值,并不代表为0
3.变量
- 在计算机程序中,变量不仅可以是数字,还可以是任意数据类型,例如:a=1,a='sh12',a=True...
3.1类变量
- 类变量是所有对象共有,其中一个对象将它值改变,其他对象得到的就是改变后的结果
3.2实例变量
- 实例变量属于对象私有,某一个对象将其值改变,不影响其他对象
3.3实例
class student(): # 定义一个类
age = 18 # 定义一个类变量
name = 'student' # 定义一个类变量
def __init__(self,age,name): # 定义一个构造函数
self.age = age # 定义一个实例变量
self.name = name # 定义一个实例变量
student_1= student(21,'夏天') # 实例化一个类
print(student_1.name) # 输出实例变量
print(student.name) # 输出类变量
结果:
夏天
student
4.list和tuple、dict和set
4.1list列表
4.1.1含义
- Python中内置的数据列表,list是有序的集合,可以随时添加和删除元素
- 查找和插入的时间随着元素的增加而增加
- 占用空间小,浪费内存很少
4.1.2示例
classhumans = ['春天','夏天','秋天']//这就是一个列表通常用[]来包括
classhumans.append('Adam')//在列表尾部添加元素
classhumans.pop()//删除添加的元素,也可以按照索引值来进行删除
classhumans.insert(3,'hello')//在索引值为3的位置插入元素
classhumans[1]='job'//按照索引位置进行替换元素
print(classhumans)
print(len(classhumans))//打印出这个列表中的元素个数
print(classhumans[0])//打印出这个列表中的第一个元素
4.2 tuple元组
4.2.1含义
- 和list一样元组是有序的,但是tuple一旦初始化就不能修改
4.2.2示例
a=(1,2)//定义元组时,最开始的元素不会再变
a=(1)//定义的不是tuple,是1这个数!这是因为括号()既可以表示tuple,又可以表示数学公式中的小括号,这就产生了歧义,Python规定,这种情况下,按小括号进行计算,计算结果自然是1,除非加一个逗号
a=(1,2,['x','y'])//可变的tuple,因为这个元组是由两个列表组成,[]中的是list列表,所以可以对其元素进行修改
a[2][0]='z'
a[2][1]='q'//在这个元组中['x','y']的索引为2,在列表['x','y']中'x','y'的索引分别为0,1
4.3 dict字典
4.3.1含义
- 使用键-值(key-value)存储,具有极快的查找速度
- 查找和插入的速度极快,不会随着key的增加而变慢;
- 需要占用大量的内存,内存浪费多
- dict是用空间来换取时间的一种方法
4.3.2示例
d = {'春': 15, '夏': 35, '秋': 25}//这就是一个字典,使用{}包括
print(d['春'])//查找春的值
d['春'] = 15//key和value方式
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
d.pop('Bob')//删除key
print(d.get('haha',0))//查看haha是否存在,不在返回0
4.4 set
4.4.1含义
- set和dict类似,也是一组key的集合,但不存储value
- set可以看成数学意义上的无序和无重复元素的集合
- 两个set可以做数学意义上的交集、并集等操作
4.4.2示例
a=set([1,2,3,2,4,5,3])//一个含重复值的简单集合
a.remove(2)//删除元素2,指定删除因为不存在重复项
a.add(6)//添加元素,可以添加重复值但是不会显示,因为输出时自动会去除
print(a)//输出会自动去除重复值
b=set([1,3,5])
c=set([2,4,6])
print(b.union(c))//合并
print(b.intersection(c))//交集
print(b.difference(c))//差集
5.参数
5.1形式参数
- 形式参数是定义函数时的变量
def stuentInfo(name,age):
print('姓名:',name,'年龄:',age)//name,age就是形参
5.1.1默认参数
- 当函数有多个参数时,把变化大的参数放前面,变化小的参数放后面。变化小的参数就可以作为默认参数,例如计算X的平方时,def power(x,n=2),n=2就是设置的默认参数
def studentInfo(name,age=21,sex='男')//这里的name没有默认值属于非默认参数即必选参数,而age和sex都默认值属于默认参数,规定默认参数在必选参数的后面,否则python解释器会报错
5.1.2可变参数
- 可变参数就是传入的参数个数是可变的
- 可变参数允许你传入0个或任意个参数,这些可变参数在函数调用时自动组装为一个tuple元组
def calc(*numbers)://可变参数
sum = 0
for n in numbers:
sum = sum + n
return sum
print(calc(1,2,3,4,5))
5.1.3关键字参数
- 关键字参数为了方便,可读性,关键字参数会允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict字典
5.1.4位置参数
- 当在调用函数时形参和实参须保持一致,按位置传参,如果位置不对应就指定说明
def studentInfo(name,age):
print('姓名:',name,'年龄:',age)
studentInfo(21,'夏天')//这里调用时就出现了形参和实参位置不对应
studentInfo(age=21,name='夏天')//通过声明来实现位置的函数调用
5.2实际参数
- 实参是在调用函数时的真实数据
studentInfo('夏天',18)//调用函数时输入的实际值即实参
6.生成器、迭代器、可迭代对象
6.1生成器
6.1.1定义
- 把一个列表生成式的[]改成()
- 能返回迭代器函数
- 正常函数变为生成器函数
- 生成器只支持顺序访问, 每个元素只能访问一次
6.1.2示例
#创建一个生成器,将[]改为()
list=[x * x for x in range(10)]
print(list)
#结果会直接打印出来
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
generator=(x * x for x in range(10))
print(generator)
输出显示生成器创建了
<generator object <genexpr> at 0x000001811E114990>
显示结果
1.通过next函数调用,调用一次计算一次结果,直到调用超出范围报错
print(next(generator))
print(next(generator))
print(next(generator))
结果:
0
1
4
2.通过for循环去输出
for x in generator:
print(x)
结果:
1
4
16
25
36
49
64
81
#正常函数变为生成器函数:
#正常
def fib(max):
n, a, b = 0, 0, 1
while n < max:
a, b = b, a + b
n += 1
print(a)//正常函数换为yield
return 'done'
f = fib(8)
print(f)
结果:
1
1
2
3
5
8
13
21
#生成器函数
def fib(max):
a, b = 0, 1
for i in range(max):
a, b = b, a+b
yield a
return 'done'
f = fib(8)
print(next(f))//生成器只支持顺序访问, 每个元素只能访问一次
print(next(f))
print(next(f))
print(next(f))
print(next(f))
print(next(f))
print(next(f))
print(next(f))
结果:
1
1
2
3
5
8
13
21
6.1.3下划线区别
- 单下划线私有属性,其要求只有类本身和子类自己能访问到这些变量,外部调用方式:类._
- 双下划线私有属性,其要求只有类本身能访问、子类不能访问
6.2迭代器
6.2.1定义
- 可以被next调用并不断返回下一个值的对象
6.2.2示例
#生成器函数
def createIterator():
yield 1
yield 2
yield 3
#返回生成器对象,调用next方法,返回值是一个包含value和done属性的对象,这就是一个通过自定义的迭代方式的迭代器
iterator = createIterator()
print(iterator.__next__())
print(iterator.__next__())
print(iterator.__next__())
6.3可迭代对象
6.3.1定义
- 可迭代对象,可以被for循环输出的,都是可迭代对象
- 生成器、迭代器都是可迭代对象
- 可以for循环的数据list,dict,tuple,set,string
6.3.2示例
from collections.abc import Iterable, Iterator
class Array:
def __iter__(self)://使用iter()函数将迭代对象变为迭代器
pass
def __next__(self):
pass
arr = Array()
print(isinstance(arr, Iterator))
print(isinstance([].__iter__(), Iterator))
7.闭包
7.1含义
- 可以保存一个环境,也就是说保存了当时的一个现场情况
- 返回函数不要引用任何循环变量,或者后续会发生变化的变量
- 可以保护你的变量不受侵害
7.2示例
def ls():
a="好啊好啊"//保存在内存
def ll():
print(a)
return ll
bb = ls()
bb() # 好啊好啊
print(bb.__closure__) # 打印出一个tuple
print(bb.__closure__[0].cell_contents) #查看tuple中的value ‘好啊好啊’
#实际应用
爬楼梯
#全局
total = 0 //可以记住上一次的total
def climb_total(step)://step=1时
global total //全局应用
new_total = total + step //0+1阶
total = new_total //total=0+1,爬一次+一阶
return total //当下次爬楼时返回给全局total,下次爬了6阶,就成了1+6然后再返回给total
print(climb_total(1))//爬了一阶
print(climb_total(6))
结果:
1
7
#闭包
def climb_total(): # 定义一个函数
total = 0 # 定义一个变量,常驻内存中
def climb(step): # 定义一个函数
nonlocal total # 声明total是一个局部变量
total += step # 变量total加上step的值,也可以写为new_total=total+step,total=new_total
return total # 返回total的值
return climb # 返回climb函数
dd = climb_total() # 实例化一个函数,dd实例化定义的climb_total函数
print(dd.__closure__) # 打印函数的闭包
print(dd(1)) # 调用函数
print(dd(2))
print(dd(3))
结果:
(<cell at 0x000002074DDAD4F8: int object at 0x000000005ABC6BF0>,)
1
3
6
思考
1.dict中通过调用什么函数将key与value循环匹配出来?
enemerate、items函数
- enemerate将可迭代序列中元素所在的下标和具体元素数据组合在一块,变成元组
- items() 函数以列表返回可遍历的(键, 值) 元组
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
for j in enumerate(d): #将索引和key输出
print(j)
for i in d.items(): # 可以遍历key和value
print(i)
2.复现assert和eval成功失败原因
2.1下载工具
- 这里特别注意在GitHub上下载中国蚁剑时会出现速度慢,系统防火墙提示等情况,这时我们手动去防火墙允许操作就可以恢复下载了安装需要下载一个loader和master两部分,一个是加载器一个是源码
GitHub - AntSwordProject/antSword: 中国蚁剑是一款跨平台的开源网站管理工具。AntSword is a cross-platform website management toolkit.中国蚁剑是一款跨平台的开源网站管理工具。AntSword is a cross-platform website management toolkit. - GitHub - AntSwordProject/antSword: 中国蚁剑是一款跨平台的开源网站管理工具。AntSword is a cross-platform website management toolkit.https://github.com/AntSwordProject/antSwordBurpsuite2021.10安装详细教程_青果@的博客-CSDN博客_burpsuite安装百度网盘链接:链接:https://pan.baidu.com/s/1AKS54jtyN6Ohkt1VDZ0Jiw提取码:v73p下载之后解压,解压之后会有两个文件点击jdk-18_windows-x64_bin.exe进行安装然后对应的安装目录查看是否有jdk的文件打开该文件夹,看是否有jre文件夹,我这里就没有没有jre文件参考大佬的方案:https://blog.csdn.net/qq_41219157/article/details/109667631可以看到jre文件https://blog.csdn.net/weixin_45632448/article/details/125071440
2.1.1解压master时可能会遇到解压失败的情况,这里分享一下我的解压过程
- 解压工具:bandizip
- 解压过程:
(1)首先在master压缩包文件右击打开解压软件,自定义解压到目录建议在loader同目录下
(2)解压过程出现重复文件直接选择覆盖或者跳过都可以,然后再去loader下找到AntSword.exe双击打开就搞定了
2.2复现过程
2.2.1通过小皮搭建一个测试网站
2.2.2写入内容进行测试
2.2.3查看网站是否显示测试内容显示即搭建成功
2.2.4eval成功、失败原因
- eval是PHP自身的语言结构,不能被可变函数调用
- PHP 支持可变函数的概念。意味着如果一个变量名后有圆括号,PHP 将寻找与变量的值同名的函数,并且尝试执行它
- eval除非通过自己再去构造一个函数来进行木马传递
- 下面演示如何通过eval()来实现一句话木马
- 我们通过eval来执行post输入,通过post提交的数据来执行我们需要执行的命令,下面是通过post提交一个phpinfo()的命令来让eval去执行这条命令,可以看出命令生效了,还可以通过一句话木马使用工具去进行连接获取位置的根目录文件,进行修改、备份
- 我们再来看下面这条一句话木马的原理,这句话满足一句话木马的特点,通过前面post['1']提交请求数据为eval时让eval去执行post['2']请求命令,这样就形成了和上述相同的效果,但是这里会报错,回到前面所说,因为eval是PHP的自身结构,所以无法通过可变函数来进行调用,这里的可变函数举个例子就是,’1‘请求的eval和后面括号中的post['2']称为可变函数,于是乎出现了下面的情况,我们再使用工具来验证一下,可以看出连接失败,请求数据显示为空
2.2.5assert成功、失败原因
- 与eval不同,因为assert在php中被认为是一个函数
- eval函数中参数是字符,assert函数中参数为表达式 (或者为函数)
- 下面将通过assert()来实现一句话木马,原理和前面类似,这里我们使用burp进行抓包查看
- 从上面可以看出,我们通过assert(eval($_POST['haha'])来进行测试连接,由于eval函数中参数是字符,assert函数中参数为表达式 (或者为函数),所以我们使用了eval(),但是即使放入函数还是不可以,这里开始换个方法,我直接提交1=assert&2,这里我提前进行了代理抓包,这里居然没有连接上
- 不慌,开始寻找问题,首先排除工具问题,因为我在这里再次测试了eval($POST_['2']),结果可以连接上去,所以去查了一下,好家伙终于让我找到了原因,原来是我的PHP版本太高,于是乎换了5.6.9,惊喜来的如此之快,它居然成了,最后经过验证如果使用assert执行,PHP版本需要在7.0以下的才行
- 开始抓包看一下,设置代理,使用burp进行抓包
- 上面是使用了base64进行了编码,如果不进行编码assert('') 里面的eval会是字符串就不会被执行,进行编码后assert中就有了eval(base64)函数,接下来我们不进行编码,来尝试使用下面的方式进行连接,原理,和上面讲的相同,就相当于assert(eval(haha)),通过自定义的post请求命令haha来让assert执行eval(),因为assert在PHP中是一个函数,来进行抓包看看,eval函数中参数haha是字符,assert函数中参数为函数,就成功验证了这个