2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

picoCTF Investigative Reversing 1 Writeup Using Ghidra

Last updated at Posted at 2021-03-18

Ghidraのデコンパイル誤りを訂正する訓練になるので記録に残しておく。

問題の入手先

問題としては,ELFバイナリ「mystery」と PNG画像「mystery.png」「mystery2.png」「mystery3.png」が渡される。
image.png
PNGを確認すると,フッターの後にフラグらしきものが見える。

Ghidraでデコンパイルしてみる

mystery
void main(void)
{
  FILE *__stream;
  FILE *__stream_00;
  FILE *__stream_01;
  FILE *__stream_02;
  long in_FS_OFFSET;
  char local_6b;
  int local_68;
  int local_64;
  int local_60;
  char local_38 [4];
  char local_34;
  char local_33;
  long local_10;
  
  local_10 = *(long *)(in_FS_OFFSET + 0x28);
  __stream = fopen("flag.txt","r");
  __stream_00 = fopen("mystery.png","a");
  __stream_01 = fopen("mystery2.png","a");
  __stream_02 = fopen("mystery3.png","a");
  if (__stream == (FILE *)0x0) {
    puts("No flag found, please make sure this is run on the server");
  }
  if (__stream_00 == (FILE *)0x0) {
    puts("mystery.png is missing, please run this on the server");
  }
  fread(local_38,0x1a,1,__stream);
  fputc((int)local_38[1],__stream_02);
  fputc((int)(char)(local_38[0] + '\x15'),__stream_01);
  fputc((int)local_38[2],__stream_02);
  local_6b = local_38[3];
  fputc((int)local_33,__stream_02);
  fputc((int)local_34,__stream_00);
  local_68 = 6;
  while (local_68 < 10) {
    local_6b = local_6b + '\x01';
    fputc((int)local_38[local_68],__stream_00);
    local_68 = local_68 + 1;
  }
  fputc((int)local_6b,__stream_01);
  local_64 = 10;
  while (local_64 < 0xf) {
    fputc((int)local_38[local_64],__stream_02);
    local_64 = local_64 + 1;
  }
  local_60 = 0xf;
  while (local_60 < 0x1a) {
    fputc((int)local_38[local_60],__stream_00);
    local_60 = local_60 + 1;
  }
  fclose(__stream_00);
  fclose(__stream);
  if (local_10 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return;
}

真っ先に気になる点

  char local_38 [4];
  fread(local_38,0x1a,1,__stream);

0x1a を読み込むのに char[4]はないよね

local_38 の型を char[26] に

変数名については
local_38 を flag に
__stream_00 を __stream_p1 に
__stream_01 を __stream_p2 に
__stream_02 を __stream_p3 に
local_68 を i に
local_64 を j に
local_60 を k に
local_6b を temp に

mystery
void main(void)
{
  long lVar1;
  FILE *__stream;
  FILE *__stream_p1;
  FILE *__stream_p2;
  FILE *__stream_p3;
  long in_FS_OFFSET;
  char temp;
  int i;
  int j;
  int k;
  char flag [26];
  
  lVar1 = *(long *)(in_FS_OFFSET + 0x28);
  __stream = fopen("flag.txt","r");
  __stream_p1 = fopen("mystery.png","a");
  __stream_p2 = fopen("mystery2.png","a");
  __stream_p3 = fopen("mystery3.png","a");
  if (__stream == (FILE *)0x0) {
    puts("No flag found, please make sure this is run on the server");
  }
  if (__stream_p1 == (FILE *)0x0) {
    puts("mystery.png is missing, please run this on the server");
  }
  fread(flag,0x1a,1,__stream);
  fputc((int)flag[1],__stream_p3);
  fputc((int)(char)(flag[0] + '\x15'),__stream_p2);
  fputc((int)flag[2],__stream_p3);
  temp = flag[3];
  fputc((int)flag[5],__stream_p3);
  fputc((int)flag[4],__stream_p1);
  i = 6;
  while (i < 10) {
    temp = temp + '\x01';
    fputc((int)flag[i],__stream_p1);
    i = i + 1;
  }
  fputc((int)temp,__stream_p2);
  j = 10;
  while (j < 0xf) {
    fputc((int)flag[j],__stream_p3);
    j = j + 1;
  }
  k = 0xf;
  while (k < 0x1a) {
    fputc((int)flag[k],__stream_p1);
    k = k + 1;
  }
  fclose(__stream_p1);
  fclose(__stream);
  if (lVar1 != *(long *)(in_FS_OFFSET + 0x28)) {
                    /* WARNING: Subroutine does not return */
    __stack_chk_fail();
  }
  return;
}

デコンパイル結果がソースコードに近くなったところでソルバー作成

png1 = list("CF{An1_e2630725}")
png2 = list("\x85s")
png3 = list("icT0tha_")
    
ans = [0] * 0x1a

# png3
ans[1] = png3[0]
ans[2] = png3[1]
ans[5] = png3[2]
j = 10
while j < 0xf:
    ans[j] = png3[j-7]
    j = j + 1

# png2
ans[0] = chr(ord(png2[0]) - 0x15)
temp = png2[1]

# png1
ans[4] = png1[0]
i = 6
while i < 10:
    temp = chr(ord(temp) - 0x1)
    ans[i] = png1[i-5]
    i = i + 1

k = 0xf
while k < 0x1a:
    ans[k] = png1[k-10]
    k = k + 1

ans[3] = temp

# print(ans)
print(''.join(ans))

※ソルバーに全角文字が混じっていました。(2021/4/20訂正)

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?