前の連載をすべて無視してリバーシング

この記事は約5分で読めます。

どうもお久しぶりです

のどかはです

前pwnを解説するとか言いましたが全てが面倒になったので、投げ出してリバーシングを説明します

よっしゃやろう

という訳ですべてを置いていくように解説をしていきます

ソースコードは以下で

#include <stdio.h>
#include <sys/ptrace.h>
#include <unistd.h>

int main(void){
  char s[30][7] = {
    " AA    ",
    "A  A   ",
    "A  A   ",
    "AAAA   ",
    "A  A   ",
    "A  A   ",
    "       ",
    "L      ",
    "L      ",
    "L      ",
    "L      ",
    "LLLLL  ",
    "       ",
    "L      ",
    "L      ",
    "L      ",
    "L      ",
    "LLLLL  ",
  };
  if (ptrace(PTRACE_TRACEME, 0, 1, 0) == -1)
    return -1;
  void *b = malloc(100);
  void test(){
  #ifndef _A_
  #define _A_
  #include "a.c"
  #endif
  }
  char n[]="hp`ls)w|Bl`";
  int a;
  int colaz(int n){
    if( n % 2 == 1 )
      return 3*n+1;
    else
      return n/2;
  }
  printf("hello\ninput :> ");
  scanf("%d", &a);
  extern char **environ;
  if(environ){
    return 0;
  }
  for(char s=getchar(); a != 1; a==0 ? test() : 1, s=getchar())
    (a = colaz(a), n[a % sizeof(n)] ^= a, printf("%d", a));
  printf("%s", n);
  for(char s=getchar(); s != 'q'; s=getchar()){
    switch(s){
      case 'm': void *b = malloc(100); break;
      case 'f': free(b); break;
      default: printf("%x", b); break;
    }
  }
  return 0;
}

WSLなりなんなりを用いて試してみましょう
バイナリは普通にコンパイルしてバイナリを用意しましょう

解説
まずは stringsしてみましょう
そうするとALLというアスキーアートが見つかります
実際のリバーシングでもstringsするだけでフラグが見つかることがあります
大抵の場合そんな甘くはないですが、テキスト情報は大事なことが多いので、積極的にstringsしましょう
つぎにltrace ./vlunとstrace ./vulnとしてみましょう
なければapt install ltrace straceとして導入してください(Ubuntuであればこのコマンド)
ltraceの方は失敗します
これはデバッガーを検知して失敗させる、アンチデバッグ技術というものが仕組まれているからです
straceの方は成功します
こっちはptraceのようなステップ実行ではなくシミュレーションするために、関数をみることができます
この問題でどんな関数を読んでるのかをフィルタリングできるのでltraceとstraceは積極的に使っていきましょう
ptraceのバイパスの仕方はgdbによる動的デバッグです
こちらもなければgdbをインストールしましょう

gdb ./vuln

としてデバッガーを起動したあとrunしても強制終了させられます
ですので以下のコマンドによってptraceをバイパスします

break ptrace
fin
set $rax=0

これはptraceが検知されるとraxレジスターという場所に-1が入っているので、それを動的デバッグによって0へと書き換える処理です
これでcontinueとコマンドを打てば継続されます
文字列入力画面となったらctrl+cを押してシグナルを送り込みましょう
プログラムが停止します
finコマンドを活用しながらステップ実行していき、文字列を入力します
文字列は数字である必要があります
ステップ実行していき
SHELL=/bin/bashという表示があるとこまで進みます
環境変数をチェックして、test rax,raxという命令によって分岐していますので、set $rax=0とすることでバイパスします
continueすると数字が出力されて文字列入力となります
エンターキーを押していくと数字が変わりながら進みます
1となって文字列が表示されます
今回はネタバレしますが、100と入力していればhello worldという文字列が復号化されます
そのあと自由にmallocとfreeができるようになっていますが、これは作者の努力不足で何にも意味がないので無視しましょう

最後

という訳で、リバーシングを紹介しました

全てを置いて行って解説しましたが、リバーシングの楽しさがちょっとでも伝われば幸いです。

コメント

タイトルとURLをコピーしました