USAGE = """PwnCalc -- a simple calculator $ a=4 >>> a = 4 $ a = 4 >>> a = 4 $ b = 3 >>> b = 3 $ c = sqrt(a*a+b*b) >>> c = 5.0 $ d = sin(pi/4) >>> d = 0.7071067811865475 Have fun! """
defcheck_expression(s): """Allow only digits, decimal point, lowecase letters and math symbols.""" SYMBOLS = ".+*-/()" for c in s: ifnot c.islower() andnot c.isdigit() and c notin SYMBOLS: returnFalse returnTrue
defloop(): """Main calculator loop.""" vars = { c : 0for c in ascii_lowercase } whileTrue: line = input("$ ") ifnot line: print("Bye!") return items = line.split("=") iflen(items) != 2: print("Invalid syntax!") continue varname, expression = items varname = varname.strip() expression = expression.strip() iflen(varname) != 1ornot varname.islower(): print("Invalid variable name!") continue ifnot check_expression(expression): print("Invalid character in expression!") continue result = eval(expression, vars, {'sin': sin, 'cos': cos, 'sqrt': sqrt, 'exp': exp, 'log': log, 'pi': pi}) vars[varname] = result print(">>> {} = {}".format(varname, result))
if __name__ == "__main__": print(USAGE) loop()
result = eval(expression, vars, {'sin': sin, 'cos': cos, 'sqrt': sqrt, 'exp': exp, 'log': log, 'pi': pi}) 에서 eval 함수를 사용해서 취약점이 발생할 수 있다.
__import__('os').system('sh') 을 실행시키고 싶다. 이를 위해 eval(__import__('os').system('sh'))을 서버에서 실행시키고 싶었다. 이때 문제는 .+*-/()만 허용해서 '을 사용할 수가 없다. 이를 위해 eval과 chr을 사용했고 이걸 로컬이 아닌 서버에서 실행시키도록 노력했다. payload를 로컬에서 실행시킬 때 에러 없이 원하는 행위를 실행시킬 수 있어야 한다. 이게 그대로 서버에서 실행된다고 생각하면 된다.