hacktricks/reversing-and-exploiting/reversing-tools-basic-methods/README.md
2024-04-06 18:36:04 +00:00

25 KiB
Raw Blame History

Reversing Tools & Basic Methods

htARTEHackTricks AWS Red Team Expert でAWSハッキングをゼロからヒーローまで学ぶ

HackTricks をサポートする他の方法:

Try Hard Security Group

{% embed url="https://discord.gg/tryhardsecurity" %}


ImGuiベースのリバースエンジニアリングツール

ソフトウェア:

Wasmデコンパイラ / Watコンパイラ

オンライン:

ソフトウェア:

.NETデコンパイラ

dotPeek

dotPeekは、ライブラリ.dllWindowsメタデータファイル.winmd、および実行可能ファイル.exeを含む複数の形式を逆コンパイルおよび調査します。逆コンパイルされたアセンブリは、Visual Studioプロジェクト.csprojとして保存できます。

ここでのメリットは、失われたソースコードを復元する場合、このアクションが時間を節約できることです。さらに、dotPeekは逆コンパイルされたコード全体を便利にナビゲートできるため、Xamarinアルゴリズム分析に最適なツールの1つです。

.NET Reflector

包括的なアドインモデルと、ツールを拡張して正確なニーズに合わせるAPIを備えた.NET Reflectorは、時間を節約し、開発を簡素化します。このツールが提供する逆コンパイルサービスの多様性を見てみましょう:

  • データがライブラリやコンポーネントを通過する方法に洞察を提供します
  • .NET言語やフレームワークの実装と使用方法に洞察を提供します
  • 使用されるAPIや技術からより多くの情報を取得するために未記載および非公開の機能を見つけます
  • 依存関係と異なるアセンブリを見つけます
  • コード、サードパーティのコンポーネント、およびライブラリのエラーの正確な場所を特定します
  • 作業するすべての.NETコードのソースにデバッグします

ILSpy & dnSpy

Visual Studio Code用ILSpyプラグイン: 任意のOSで使用できますVSCodeから直接インストールでき、gitをダウンロードする必要はありません。Extensions をクリックして ILSpy を検索します)。
逆コンパイル変更、そして再コンパイルする場合は、dnSpy またはそれをアクティブにメンテナンスされたフォーク、dnSpyEx を使用できます(関数内の何かを変更するには、右クリック -> メソッドの変更)。

DNSpy ロギング

DNSpy が情報をファイルに記録するようにするには、次のスニペットを使用できます:

using System.IO;
path = "C:\\inetpub\\temp\\MyTest2.txt";
File.AppendAllText(path, "Password: " + password + "\n");

DNSpy デバッグ

DNSpyを使用してコードをデバッグするには、次の手順を実行する必要があります

まず、デバッグに関連する アセンブリ属性を変更します:

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]

リバースエンジニアリングツールと基本的な手法

このセクションでは、リバースエンジニアリングに使用される一般的なツールと基本的な手法について説明します。リバースエンジニアリングは、プログラムやファイルを解析して、その動作や構造を理解するプロセスです。以下は、リバースエンジニアリングに役立ついくつかのツールと手法です。

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default |
DebuggableAttribute.DebuggingModes.DisableOptimizations |
DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints |
DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]

そして、コンパイルをクリックしてください:

次に、新しいファイルを ファイル >> モジュールを保存... で保存してください:

これは必要です。なぜなら、これを行わないと、実行時にコードにいくつかの最適化が適用され、デバッグ中にブレークポイントがヒットしないか、一部の変数が存在しない可能性があるからです。

その後、.NETアプリケーションがIIS実行されている場合は、次のように再起動できます:

iisreset /noforce

その後、デバッグを開始するためには、すべての開いているファイルを閉じ、デバッグタブ内でプロセスにアタッチを選択します:

次に、w3wp.exeを選択してIISサーバーにアタッチし、アタッチをクリックします:

プロセスのデバッグが開始されたので、プロセスを停止してすべてのモジュールをロードする時間です。まず、_Debug >> Break All_をクリックし、次に_Debug >> Windows >> Modules_をクリックします

モジュール内の任意のモジュールをクリックし、Open All Modulesを選択します:

アセンブリエクスプローラ内の任意のモジュールを右クリックし、アセンブリをソートをクリックします:

Java decompiler

https://github.com/skylot/jadx
https://github.com/java-decompiler/jd-gui/releases

Debugging DLLs

IDAを使用する

  • rundll32をロード64ビットはC:\Windows\System32\rundll32.exe、32ビットはC:\Windows\SysWOW64\rundll32.exe
  • Windbgデバッガーを選択
  • "ライブラリの読み込み/アンロード時に中断"を選択

  • 実行のパラメータを構成し、DLLへのパスと呼び出したい関数を入力します:

その後、デバッグを開始すると、各DLLがロードされるたびに実行が停止されます。その後、rundll32がDLLをロードすると実行が停止します。

しかし、ロードされたDLLのコードにどのようにアクセスできますかこの方法を使用すると、その方法がわかりません。

x64dbg/x32dbgを使用する

  • rundll32をロード64ビットはC:\Windows\System32\rundll32.exe、32ビットはC:\Windows\SysWOW64\rundll32.exe
  • コマンドラインを変更File --> Change Command Lineし、dllのパスと呼び出したい関数を設定します。例"C:\Windows\SysWOW64\rundll32.exe" "Z:\shared\Cybercamp\rev2\\14.ridii_2.dll",DLLMain
  • _Options --> Settings_を変更し、「DLL Entry」を選択します。
  • その後、実行を開始し、デバッガーは各dllメインで停止します。いずれかの時点で、dllのエントリに停止します。そこから、ブレークポイントを設定したいポイントを検索します。

実行がwin64dbgで何らかの理由で停止されると、win64dbgウィンドウの上部にいるコードが表示されます:

その後、デバッグが停止されたdll内のコードを確認できます。

GUIアプリ/ビデオゲーム

Cheat Engineは、実行中のゲームのメモリ内に重要な値が保存されている場所を見つけ、それらを変更するための便利なプログラムです。詳細は以下を参照してください:

{% content-ref url="cheat-engine.md" %} cheat-engine.md {% endcontent-ref %}

ARM & MIPS

{% embed url="https://github.com/nongiach/arm_now" %}

シェルコード

Blobrunnerを使用してシェルコードをデバッグする

Blobrunnerは、メモリ空間内にシェルコード割り当てし、シェルコードが割り当てられたメモリアドレスを示し、実行を停止します。
その後、プロセスにデバッガーIdaまたはx64dbgアタッチし、指定されたメモリアドレスにブレークポイントを設定し、実行を再開します。これにより、シェルコードのデバッグが行われます。

リリースのGitHubページには、コンパイルされたリリースが含まれるzipファイルがありますhttps://github.com/OALabs/BlobRunner/releases/tag/v0.0.5
以下のリンクにBlobrunnerのわずかに変更されたバージョンがあります。コンパイルするには、Visual Studio CodeでC/C++プロジェクトを作成し、コードをコピーして貼り付け、ビルドします。

{% content-ref url="blobrunner.md" %} blobrunner.md {% endcontent-ref %}

jmp2itを使用してシェルコードをデバッグする

jmp2itはBlobrunnerに非常に似ています。シェルコードメモリ空間内に割り当てし、永遠のループを開始します。その後、プロセスにデバッガーをアタッチし、開始を再生して2〜5秒待って停止を押すと、永遠のループ内にいます。永遠のループの次の命令にジャンプしてシェルコードを呼び出し、最終的にシェルコードを実行します。

リリースページ内でjmp2itのコンパイル済みバージョンをダウンロードできます

Cutterを使用してシェルコードをデバッグする

CutterはradareのGUIです。Cutterを使用すると、シェルコードをエミュレートして動的に検査できます。

Cutterを使用すると、「ファイルを開く」と「シェルコードを開く」が可能です。私の場合、シェルコードをファイルとして開いたときは正しく逆コンパイルされましたが、シェルコードとして開いたときは逆コンパイルされませんでした

特定の場所でエミュレーションを開始するには、そこにブレークポイントを設定し、Cutterは自動的にそこからエミュレーションを開始します

例えば、ヘックスダンプ内でスタックを表示できます:

シェルコードの逆難読化と実行される関数の取得

scdbgを試してみるべきです。
このツールは、シェルコードが使用している関数や、シェルコードがメモリ内でデコードされているかどうかなどを教えてくれます。

scdbg.exe -f shellcode # Get info
scdbg.exe -f shellcode -r #show analysis report at end of run
scdbg.exe -f shellcode -i -r #enable interactive hooks (file and network) and show analysis report at end of run
scdbg.exe -f shellcode -d #Dump decoded shellcode
scdbg.exe -f shellcode /findsc #Find offset where starts
scdbg.exe -f shellcode /foff 0x0000004D #Start the executing in that offset

scDbgには、グラフィカルなランチャーも備わっており、希望するオプションを選択してシェルコードを実行することができます。

Create Dump オプションは、メモリ内でシェルコードが動的に変更された場合に最終的なシェルコードをダンプします(デコードされたシェルコードをダウンロードするのに便利です)。start offset は特定のオフセットでシェルコードを開始するのに役立ちます。Debug Shell オプションは、scDbgターミナルを使用してシェルコードをデバッグするのに役立ちますただし、前述のいずれかのオプションの方がこの問題にはより適していると考えます。Idaやx64dbgを使用できるため

CyberChefを使用した逆アセンブル

シェルコードファイルを入力としてアップロードし、次のレシピを使用して逆コンパイルします:https://gchq.github.io/CyberChef/#recipe=To_Hex('Space',0)Disassemble_x86('32','Full%20x86%20architecture',16,0,true,true)

Movfuscator

この難読化ツールは、すべてのmov命令を変更します(本当にクールです)。また、実行フローを変更するために割り込みを使用します。動作方法の詳細については以下を参照してください:

幸運な場合、demovfuscatorがバイナリを復号化します。いくつかの依存関係があります。

apt-get install libcapstone-dev
apt-get install libz3-dev

そして、keystoneをインストールしてください(apt-get install cmake; mkdir build; cd build; ../make-share.sh; make install

CTFをプレイしている場合、このフラグを見つけるためのワークアラウンドは非常に役立ちます: https://dustri.org/b/defeating-the-recons-movfuscator-crackme.html

Rust

エントリーポイントを見つけるには、次のように::mainで関数を検索します:

この場合、バイナリの名前はauthenticatorでしたので、これが興味深いmain関数であることはかなり明らかです。
呼び出されている関数の名前を持っている場合は、それらをインターネットで検索して、それらの入力出力について学びます。

Delphi

Delphiでコンパイルされたバイナリを逆アセンブルする場合は、https://github.com/crypto2011/IDRを使用できます。

Delphiバイナリを逆アセンブルする必要がある場合は、IDAプラグインhttps://github.com/Coldzer0/IDA-For-Delphiを使用することをお勧めします。

単にATL+f7IDAでPythonプラグインをインポートを押して、Pythonプラグインを選択します。

このプラグインはバイナリを実行し、デバッグの開始時に関数名を動的に解決します。デバッグを開始した後は、再度Startボタン緑色のボタンまたはf9を押すと、実際のコードの最初にブレークポイントがヒットします。

また、グラフィックアプリケーションでボタンを押すと、そのボタンによって実行される関数でデバッガが停止します。

Golang

Golangバイナリを逆アセンブルする必要がある場合は、IDAプラグインhttps://github.com/sibears/IDAGolangHelperを使用することをお勧めします。

単にATL+f7IDAでPythonプラグインをインポートを押して、Pythonプラグインを選択します。

これにより、関数の名前が解決されます。

コンパイルされたPython

このページでは、ELF/EXE Pythonコンパイル済みバイナリからPythonコードを取得する方法が見つかります:

{% content-ref url="../../generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md" %} .pyc.md {% endcontent-ref %}

GBA - ゲームボーイアドバンス

GBAゲームのバイナリを取得した場合、それをエミュレートおよびデバッグするために異なるツールを使用できます:

  • no$gbaデバッグバージョンをダウンロード- インターフェース付きのデバッガを含む
  • mgba - CLIデバッガを含む
  • gba-ghidra-loader - Ghidraプラグイン
  • GhidraGBA - Ghidraプラグイン

no$gbaでは、_Options --> Emulation Setup --> Controls_でGame Boy Advanceのボタンを押す方法がわかります

押されると、各キーには識別値があります:

A = 1
B = 2
SELECT = 4
START = 8
RIGHT = 16
LEFT = 32
UP = 64
DOWN = 128
R = 256
L = 256

したがって、この種のプログラムでは、興味深いのはプログラムがユーザー入力をどのように処理するかです。アドレス0x4000130には、一般的に見られる関数KEYINPUTがあります。

前の画像では、その関数がFUN_080015a8(アドレス:0x080015fa_および_0x080017ac)から呼び出されていることがわかります。

その関数では、いくつかの初期化操作(重要ではない)の後に:

void FUN_080015a8(void)

{
ushort uVar1;
undefined4 uVar2;
undefined4 uVar3;
ushort uVar4;
int iVar5;
ushort *puVar6;
undefined *local_2c;

DISPCNT = 0x1140;
FUN_08000a74();
FUN_08000ce4(1);
DISPCNT = 0x404;
FUN_08000dd0(&DAT_02009584,0x6000000,&DAT_030000dc);
FUN_08000354(&DAT_030000dc,0x3c);
uVar4 = DAT_030004d8;

このコードが見つかりました:

do {
DAT_030004da = uVar4; //This is the last key pressed
DAT_030004d8 = KEYINPUT | 0xfc00;
puVar6 = &DAT_0200b03c;
uVar4 = DAT_030004d8;
do {
uVar2 = DAT_030004dc;
uVar1 = *puVar6;
if ((uVar1 & DAT_030004da & ~uVar4) != 0) {

最後のif文は、uVar4最後のキーにあるかどうかをチェックし、現在のキーではないことを確認しています(現在のキーは**uVar1**に保存されています)。

if (uVar1 == 4) {
DAT_030000d4 = 0;
uVar3 = FUN_08001c24(DAT_030004dc);
FUN_08001868(uVar2,0,uVar3);
DAT_05000000 = 0x1483;
FUN_08001844(&DAT_0200ba18);
FUN_08001844(&DAT_0200ba20,&DAT_0200ba40);
DAT_030000d8 = 0;
uVar4 = DAT_030004d8;
}
else {
if (uVar1 == 8) {
if (DAT_030000d8 == 0xf3) {
DISPCNT = 0x404;
FUN_08000dd0(&DAT_02008aac,0x6000000,&DAT_030000dc);
FUN_08000354(&DAT_030000dc,0x3c);
uVar4 = DAT_030004d8;
}
}
else {
if (DAT_030000d4 < 8) {
DAT_030000d4 = DAT_030000d4 + 1;
FUN_08000864();
if (uVar1 == 0x10) {
DAT_030000d8 = DAT_030000d8 + 0x3a;

前のコードでは、uVar1押されたボタンの値が格納される場所)をいくつかの値と比較しています:

  • まず、値4SELECTボタン)と比較されます:このボタンはチャレンジでは画面をクリアします
  • 次に、値8STARTボタン)と比較されます:このチャレンジでは、コードがフラグを取得するために有効かどうかをチェックします。
  • この場合、変数**DAT_030000d8**が0xf3と比較され、値が同じ場合はいくつかのコードが実行されます。
  • それ以外の場合、一部のcontDAT_030000d4がチェックされます。これはcontであり、コードに入るとすぐに1が追加されます。
    8未満の場合、DAT_030000d8に値を追加する何かが行われます基本的には、contが8未満の間、この変数に押されたキーの値を追加しています

したがって、このチャレンジでは、ボタンの値を知っていると、長さが8未満で、結果の加算が0xf3になる組み合わせを押す必要がありました。

このチュートリアルの参考資料: https://exp.codes/Nostalgia/

ゲームボーイ

{% embed url="https://www.youtube.com/watch?v=VVbRe7wr3G4" %}

コース

Try Hard Security Group

{% embed url="https://discord.gg/tryhardsecurity" %}

htARTEHackTricks AWS Red Team Expert AWSハッキングをゼロからヒーローまで学ぶ

HackTricksをサポートする他の方法