Python之汉诺塔问题及python安全

一曲冷凌霜 提交于 2020-01-07 12:08:32

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函数。否则就会造成一些不必要的损失。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!