Reversing Tools & Basic Methods

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

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

Try Hard Security Group


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

ソフトウェア:

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

オンライン:

ソフトウェア:

.NETデコンパイラ

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

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

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

  • データがライブラリやコンポーネントを通過する方法についての洞察を提供

  • .NET言語やフレームワークの実装と使用に関する洞察を提供

  • APIや使用されているテクノロジーからより多くの情報を取得するための未公開の機能を見つける

  • 依存関係や異なるアセンブリを見つける

  • コード、サードパーティのコンポーネント、およびライブラリのエラーの正確な場所を特定する

  • 作業しているすべての .NET コードのソースにデバッグする

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

DNSpy ロギング

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

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

DNSpy デバッグ

DNSpyを使用してコードをデバッグするには、次の手順が必要です:

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

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

To:

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

このセクションでは、リバースエンジニアリングに使用される一般的なツールと基本的な手法について説明します。

[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_をクリックします:

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

Assembly Explorerで任意のモジュールを右クリックし、Sort Assembliesをクリックします:

Java decompiler

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

DLLのデバッグ

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 Entryに停止します。そこから、ブレークポイントを設定したいポイントを検索します。

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

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

GUIアプリ/ビデオゲーム

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

pageCheat Engine

PiNCEは、GNU Project Debugger(GDB)向けのフロントエンド/リバースエンジニアリングツールで、ゲームに焦点を当てていますが、リバースエンジニアリング関連の任意の用途に使用できます。

Decompiler Explorerは、複数のデコンパイラのためのWebフロントエンドです。このWebサービスを使用すると、小さな実行可能ファイルの出力を比較できます。

ARM & MIPS

シェルコード

blobrunnerを使用したシェルコードのデバッグ

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

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

pageBlobrunner

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)

この難読化ツールは、すべての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+f7(IDAでPythonプラグインをインポート)を押し、Pythonプラグインを選択します。

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

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

Golang

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

単にATL+f7(IDAでPythonプラグインをインポート)を押し、Pythonプラグインを選択します。

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

コンパイルされたPython

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

pageDecompile compiled python binaries (exe, elf) - Retreive from .pyc

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

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

  • no$gba(デバッグバージョンをダウンロード) - インターフェース付きのデバッガを含む

  • mgba - CLIデバッガを含む

  • gba-ghidra-loader - Ghidraプラグイン

  • GhidraGBA - Ghidraプラグイン

no$gbaでは、_Options --> Emulation Setup --> Controls_でゲームボーイアドバンスのボタンを押す方法がわかります

押されると、各キーには値があり、それを識別するために使用されます:

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と比較され、値が同じ場合はいくつかのコードが実行されます。

  • それ以外の場合、一部のcont(DAT_030000d4)がチェックされます。これはcontであり、コードに入るとすぐに1が追加されます。 8未満の場合、DAT_030000d8に値を追加するものが行われます(基本的には、contが8未満の間、この変数に押されたキーの値を追加しています)。

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

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

ゲームボーイ

コース

Try Hard Security Group

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

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

Last updated