2011-12-05 4 views
1

사용자가 시스템에서 코드를 실행할 수있는 시스템에서 작업하고 있습니다. 코드가 샌드 박스 처리되는 동안, 나는 여전히 코드가 특정 문장, 특히 수입 코드를 사용하는지 알고 싶다. 이것은 플랫폼에 대한 지침에 위배되는 악의적 인 코드 나 코드를 빠르게 확인하는 데 사용됩니다. 코드는 나중에 사람이 검사하기 때문에 유일한 검사는 아니지만 최악의 경우를 자동으로 필터링하는 것이 좋습니다. .특정 문에 대한 파이썬 코드 확인

그래서 코드를 실행하지 않고 코드가 예를 들어 sys (또는 sys 부분)을 가져 오는지 확인하는 것이 가장 좋은 방법일까요? 나는 그 코드를 검색하는 정규 표현식보다 나은/좋은 방법이 있기를 희망한다.

보너스 질문 : 더 복잡한 진술은 어떻습니까? 예를 들어 bar 모듈에서 foo을 호출 하시겠습니까?

편집 : 이것은 보안에 관한 질문이 아닙니다. 코드 내에서 특정 문장을 찾는 것입니다. 내 의견보기. 이 사용자 코드는 사용자 샌드 박스 내에서만 실행되므로 자신의 샌드 박스를 망칠 수 있습니다. 그러나 코드가 '인증'되면 다른 사용자의 샌드 박스에서 실행될 수 있습니다. 인증되기 전에 확인해야합니다. 그리고 자동화 된 수표가 최악의 범죄를 발견 할 수 있다면 도움이 될 것입니다.

+0

인간은 매우 포괄적 인 검사를해야합니다. 예를 들어'exec' 명령을 사용하여 여기에 구현 한 간단한 시스템을 찾을 수 있습니다. – Oliver

+0

내가 틀릴 수도 있지만, 소스 파일을 텍스트 파일로 스캔하는 것 외에는 다른 방법을 생각할 수 없다 : 파이썬 인터프리터가 그들을 실행할 수있게하면, import 문과 모듈을 사용하기 전에 코드를 인트로 로그 할 수 없다. 레벨 함수가 실행되었습니다 ...하지만 문제의 일부가 누락 되었습니까? – mac

+0

@Oliver ... 여전히 ... 심지어 코드가 난독 화되면 (예 : 절인/압축/rot13 등) – mac

답변

0

ast 파이썬 모듈을 사용하여 파이썬 코드를 분석 할 수 있습니다.

여기 https://stackoverflow.com/a/8255293/589206

가 가져 오기 문 문제에 대한 해결책 : 여기에 매우 비슷한 질문에 대한 내 대답을 참조하십시오 물론

import ast 
import sys 

class FunctionNameFinder(ast.NodeVisitor): 
     def visit_Import(self, node): 
       print "Importing on line", node.lineno, ":", 
       for i in node.names: print i.name, 
       print 

with open(sys.argv[1], 'rU') as f: 
     FunctionNameFinder().visit(ast.parse("".join(f.readlines()))) 

, 악의적 인 사용자이고이 경우에 도움이되지 않습니다 코드를 모호하게 만들려고 많은 노력을 기울 였지만, 갈 수있는 유일한 방법은 실제 샌드 박스를 사용하는 것입니다. 그러나 그것은 처음에는 당신의 질문이 아니 었습니다.

+0

솔직히 말해서 이것이 정규 표현식을 사용하는 것보다 어떻게 나아 져야하는지 보지 못했습니다 ... 최고로 느린 순서이고 여전히 동일한 제한이 있습니다 .... 아니면 나는 무엇이든지 놓치고 있습니까? – mac

+0

이 방법을 사용하면 보너스 질문을 해결할 수 있습니다. 정규식을 사용하는 것은 어려울 것입니다. – hochl

+0

위의 Liquid Fire 코드와 같은 간단한 트릭에서는 작동하지 않습니다. – Voo

3

정말

1024 ** 1024 ** 1024 

여전히 통역을 씹어 때문에 인공 샌드 박스의 이런 종류의 일을하려고 귀찮게하지 않을 것입니다.

또는이

eval("__vzcbeg__('gvzr').nfpgvzr()") 

당신이 pypy의 sandbox의를 신뢰할 수없는 파이썬 코드를 실행하는 가장 안전한 방법에 대한에 몇 가지 보안보기를 원하는 경우

. pysandbox과 같은 몇 가지 파이썬 전용 모듈이 있지만 개인적으로 pypy 샌드 박스를 제안합니다.

항상 까다로운 일을 할 수 있기 때문에 당신은 단지 코드의 정적 분석하여이 작업을 수행 할 수 없습니다
+0

OP가 보안을 위해 이것을 원하지 않는다고 생각합니다. 샌드 박스. 이러한 종류의 수표는 샌드 박스를 깨고 시도를 인정하고 금지를 시행 할 수 있습니다. – mac

1

, 예를 들면 :

>>> getattr(__builtins__, "__" + chr(105) + "mport__")("sys") 
<module 'sys' (built-in)> 

당신이 볼 수 있듯이, 분해, 코드 또는 AST 원을보고 ' "수입"이라는 문자열이 포함되어 있지 않은 경우도 있습니다.

>>> import dis 
>>> dis.dis(lambda: getattr(__builtins__, "__" + chr(105) + "mport__")("sys")) 
    1   0 LOAD_GLOBAL    0 (getattr) 
       3 LOAD_GLOBAL    1 (__builtins__) 
       6 LOAD_CONST    1 ('__') 
       9 LOAD_GLOBAL    2 (chr) 
      12 LOAD_CONST    2 (105) 
      15 CALL_FUNCTION   1 
      18 BINARY_ADD 
      19 LOAD_CONST    3 ('mport__') 
      22 BINARY_ADD 
      23 CALL_FUNCTION   2 
      26 LOAD_CONST    4 ('sys') 
      29 CALL_FUNCTION   1 
      32 RETURN_VALUE 
+0

나는 chr (73)이 실수 였기 때문에 나는 그것을위한 ascii이고 "Import"가 나를 위해 오류를 던 졌기 때문에. 소문자 i의 경우 105로 작동하지만 괜찮습니다. – Voo

+0

정말로 감사합니다. –

1

나는 그런 종류의 것을 전혀 안정적으로 감지 할 수 있다고 생각하지 않습니다. 다음 고려 :

>>> f = None 
>>> b = vars()[[f for f in vars() if 'ti' in f][0]] 
>>> m = getattr(b, [f for f in dir(b) if 't_' in f][0]) 
>>> m('x\x9c+\xae,\x06\x00\x02\xc1\x01`'.decode('zip')) 
<module 'sys' (built-in)> 
0

은 무엇 당신이하려고하는 것은 일반적인 시나리오입니다 : 당신은 이미 샌드 박스에서 실행하여 코드의 동적 해석을하고있다.다른 도구를 사용하여 정적 분석을하고 싶으면 프로그램을 읽어보십시오.

두 가지 방법 모두 고유 한 단점이 있으며 계산의 특성으로 인해 모든 종류의 잠재적 인 시나리오가 잘못 전달 될 수 있습니다. 그러나 여전히 두 가지를 조합하면 더 높은 신뢰 수준에서 많은 유용한 정보를 얻을 수 있습니다.

예를 들어 C/C++와 같이 널리 사용되는 언어에서는 코드를 깊이 분석하고 보안과 관련된 문제를 비롯하여 많은 문제를보고 할 수있는 강력한 도구 (예 : Lint)가 있습니다.

불행히도 파이썬에는 견고성 수준이 높은 도구가 없습니다. 그렇게 말하면서, 당신은 아직도 많이 할 수 있습니다. 최선의 선택은 PyLint를 사용하는 것이라고 생각합니다.

PyLint에는 코드 분석에 대한 몇 가지 표준 규칙이 있지만 코드 냄새를 사용자 정의하기 위해 PyLint를 재정의 할 수 있습니다.

예를 들어, 사용중인 모듈 종류를보고 싶다면 imports checker을 사용할 수 있습니다. 보다 복잡한 시나리오를 처리하기 위해 기능을 사용자 정의하고 확장 할 수 있습니다. 그들의 documentation for enhancing PyLint을보십시오.

tutorial 한 번 봐 시작하려면 : 사실 모래 복싱은 참으로 매우 어렵습니다

1

있지만, 그것은 당신이 잡을하려고 수입 문이있는 경우,이 사항을 고려하십시오

>>> org_imp = __builtins__.__import__ 
>>> def imp_hook(*args, **kw): 
    if args[0] == 'sys': 
     print 'Gotcha!!' 
     return None 
    return org_imp 

>>> __builtins__.__import__ = imp_hook 
>>> import sys 
Gotcha!! 
>>> sys 
>>> print sys 
None 

이 작업은 import 문 자체의 복잡성에 관계없이 수행됩니다.

참고 : & 반품 없음을 인쇄하면 의미있는 예외가 발생하지만 아이디어를 얻으실 수 있습니다!