Python之漢諾塔問題及python安全

Python之漢諾塔問題

今天學習了一下漢諾塔問題,像了許久啊!!腦袋不太OK!記得上次看到漢諾塔是我在看電影的時候,電影場景裏給大猩猩測試智商的。。。。

這裏使用的是Python3編寫的代碼,畢竟大家都知道2020年的1月1日Python2已經正式退休了。下面是Python3的時代了。

發現規律後就會意識到這個就是一個遞歸函數,挺明顯的。

代碼如下:

'''
下面是漢諾塔問題不同的圓盤個數實現任務的次數規律:
n=1    a=1   f(x) = 1
n=2    a=3   f(2) = 2*f(1)+1
n=3    a=7   f(3) = 2*f(2)+1
n=4    a=15  f(4) = 2*f(3)+1
...    ...   f(n) = 2*f(n-1)+1
'''
def Move(n,a,b,c):
    if n == 1:
        print (a,'--->',c)    #如果只有一個圓盤就直接把它從A拿到C,並且結束程序。
        return 0
    else:           #不是一個圓盤那麼就要對n-1個圓盤從A移到B
        Move(n-1,a,c,b)
        print (a,'--->',c)   #把最底下的那個從A移動到C
        Move(n-1,b,a,c)       #最後把在B的n-1個圓盤移動到C
number = input('請輸入圓盤的個數(整數數字):')
Move(eval(number),'A','B','C')

運行效果如下:在這裏插入圖片描述

思考

說起Python,這也是一門解釋型語言所以它肯定會存在一些注入漏洞,之前在看SQL注入的時候就一直在想Python注入會是什麼樣的。今天就試一試,因爲剛好我在編寫代碼的時候使用到了eval()函數,這個函數可以把字符串轉換爲Python可以理解的語句,這樣就產生了了一個命令執行漏洞。就不具體講了,所以我發現它是可以被利用於注入的。
所以我就設置了一個flag進行簡單是實驗:

'''
下面是漢諾塔問題不同的圓盤個數實現任務的次數規律:
n=1    a=1   f(x) = 1
n=2    a=3   f(2) = 2*f(1)+1
n=3    a=7   f(3) = 2*f(2)+1
n=4    a=15  f(4) = 2*f(3)+1
...    ...   f(n) = 2*f(n-1)+1
'''
flag='A1andNS{sfji_341bghsdf_6ygsfuh}'
def Move(n,a,b,c):
    if n == 1:
        print (a,'--->',c)    #如果只有一個圓盤就直接把它從A拿到C,並且結束程序。
        return 0
    else:           #不是一個圓盤那麼就要對n-1個圓盤從A移到B
        Move(n-1,a,c,b)
        print (a,'--->',c)   #把最底下的那個從A移動到C
        Move(n-1,b,a,c)       #最後把在B的n-1個圓盤移動到C
number = input('請輸入圓盤的個數(整數數字):')
Move(eval(number),'A','B','C')

代碼如上,然後運行一下:

在這裏插入圖片描述

照常請求輸入數字,但是我會輸入print(flag)語句:

在這裏插入圖片描述

運行一下結果如下:

在這裏插入圖片描述

我要的Flag被直接顯示出來了,當然由於eval(‘print flag’)被執行,所以python報錯了,Move()函數就傳參異常了。

防範

那麼要怎麼樣來防止被惡意執行命令呢?

可以從eval()函數自身開始看,利用eval()的兩個設置 限制條件的位來設置白名單,從而避免被執行。

'''
n=1    a=1   f(x) = 1
n=2    a=3   f(2) = 2*f(1)+1
n=3    a=7   f(3) = 2*f(2)+1
n=4    a=15  f(4) = 2*f(3)+1
...    ...   f(n) = 2*f(n-1)+1
'''
flag='A1andNS{sfji_341bghsdf_6ygsfuh}'
def Move(n,a,b,c):
    if n == 1:
        print (a,'--->',c)
        return 0
    else:
        Move(n-1,a,c,b)
        print (a,'--->',c)
        Move(n-1,b,a,c)
number = input('請輸入圓盤的個數(整數數字):')
Move(eval(number,{'input':input},{'input':input}),'A','B','C')

比如我把eval函數加了限制後再去執行print(flag),就不起作用了。

在這裏插入圖片描述

當然這只是一個簡單的實驗,證實了eval函數在帶來便利的同時也會帶來一些風險,這些風險需要被重視,並且安全的使用eval函數。否則就會造成一些不必要的損失。

發佈了22 篇原創文章 · 獲贊 27 · 訪問量 5593
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章