setodaNote CTF ELF Writeup Using Ghidra


setodaNote CTF Rev問題の2問目

stringsを確認したらダメだったので,functionから。
putsが気になったので,putsから追いかけてみた。


putsのcall元は?

putsのcall元は,FUN_00101135

FUN_00101135
undefined8 FUN_00101135(void)
{
  undefined8 local_28;
  undefined8 local_20;
  undefined local_18;
  int local_c;

  local_28 = 0x465d5a534f49444e;
  local_20 = 0x55494a4143494577;
  local_18 = 0;
  local_c = 0;
  while (local_c < 0x10) {
    *(byte *)((long)&local_28 + (long)local_c) = *(byte *)((long)&local_28 + (long)local_c) ^ 0x28;
    local_c = local_c + 1;
  }
  puts((char *)&local_28);
  return 0;
}

stack strings を 0x28 で xor してる
ビンゴみたい
Ghidra scriptでフラグを復元してみる

test_ELF.py
#
# solver for WaniCTF Reversing complex
#
def qword_parse(value):
    #return([(value & 0xff00000000000000) / 0x100000000000000,(value & 0x00ff000000000000) / 0x1000000000000,(value & 0x0000ff0000000000) / 0x10000000000,(value & 0x000000ff00000000) / 0x100000000,(value & 0x00000000ff000000) / 0x1000000,(value & 0x0000000000ff0000) / 0x10000,(value & 0x000000000000ff00) / 0x100,(value & 0x00000000000000ff) / 0x1])
    return([(value & 0x00000000000000ff) / 0x1,(value & 0x000000000000ff00) / 0x100,(value & 0x0000000000ff0000) / 0x10000,(value & 0x00000000ff000000) / 0x1000000,(value & 0x000000ff00000000) / 0x100000000,(value & 0x0000ff0000000000) / 0x10000000000,(value & 0x00ff000000000000) / 0x1000000000000,(value & 0xff00000000000000) / 0x100000000000000])

def dword_parse(value):
    #return([(value & 0xff000000) / 0x1000000,(value & 0x00ff0000) / 0x10000,(value & 0x0000ff00) / 0x100,(value & 0x000000ff) / 0x1])
    return([(value & 0x000000ff) / 0x1,(value & 0x0000ff00) / 0x100,(value & 0x00ff0000) / 0x10000,(value & 0xff000000) / 0x1000000])

def word_parse(value):
    #return([(value & 0xff00) / 0x100,(value & 0x00ff) / 0x1])
    return([(value & 0x00ff) / 0x1,(value & 0xff00) / 0x100])

local_28=[]

addr = toAddr(0x0010113d)
inst = getInstructionAt(addr)
local_28.extend(qword_parse(inst.getOpObjects(1)[0].getValue()))

addr = toAddr(0x00101147)
inst = getInstructionAt(addr)
local_28.extend(qword_parse(inst.getOpObjects(1)[0].getValue()))

print(local_28)
print(''.join(map(chr,local_28)))

ans = []

i = 0
while i < 0x10:
    ans.append(local_28[i] ^ 0x28)
    i = i + 1

print(ans)
print(''.join(map(chr,ans)))


ビンゴ!