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函数。否则就会造成一些不必要的损失。
来源:CSDN
作者:A1andNS
链接:https://blog.csdn.net/qq_26139045/article/details/103866813