just read memory

그냥 읽으라고 한다

설명에 script 쓰라고 하는데.. 안 써봐서 약간의 노가다를 각오하고 풀고 라업 참고해서 배워보려한다(변명하자면 script 예시가 잘 안 보여서 어떻게 쓰는지 숙지가 안됐다)

Image

어떤 연쇄적인 리스트에 대해 malloc 해주고 append_list하는 코드이다.

append_list 함수를 읽어보자.

__int64 unknown_func1()
{
  return (unsigned int)cnt;
}

cnt를 return한다

__int64 unknown_func2()
{
  int v1; // [rsp+0h] [rbp-4h]

  return (unsigned int)(9 * (3 * (v1 + 5) - 7));
}

v1에 대한 계산값을 출력한다.

__int64 generate_flag()
{
  unsigned int v1; // [rsp+0h] [rbp-4h]

  cnt = v1;
  return v1 % 0x4A + 48;
}

v1에 대한 계산값을 출력한다.

QWORD *append_list()
{
  _QWORD *result; // rax
  _QWORD *v1; // [rsp+10h] [rbp-10h]
  char flag; // [rsp+1Fh] [rbp-1h]

  unknown_func1();
  unknown_func2();
  flag = generate_flag();
  v1 = malloc(0x10uLL);
  *(_BYTE *)v1 = flag;
  v1[1] = 0LL;
  if ( tail_node )
    *(_QWORD *)(tail_node + 8) = v1;
  result = v1;
  tail_node = (__int64)v1;
  return result;
}

위에서 봤던 generate_flag는 v1에 저장된다. malloc으로 할당되는 v1을 동적분석하며 관찰해봐야 한다.

v1으로 받는 값들을 64번.. 관찰해보면 된다.

Image

함수 BP 걸고 내부로 들어가보자

Image

+72에 mov rax, QW rbp-0x10로 flag를 v1(rax)으로 옮기는 거 같다. 그 다음 줄은 76에 bp를 걸어보자

b *main+76

Image

rax값은 0x4d이다. 하나씩 모아보자..

한 16번쯤 하면 공부 열심히 해야겠다는 생각이 든다.

Image

라업 코드를 보니 아래와 같았다. 주석은 내가 추가하면서 코드 이해했다.

# gdb -q -x script1.py
# gdb 라이브러리 
import gdb

ge = gdb.execute
gp = gdb.parse_and_eval

# gdb 실행 
ge("file ./main")

# gdb.Breakpoint로 중단점 설정 
class check_generated_flag(gdb.Breakpoint):
    def __init__(self, address):
        super(check_generated_flag, self).__init__(spec=f"*{address}", type=gdb.BP_BREAKPOINT)
        #cnt가 카운트 개수인 거 같다. ida 분석하면서도 있었던 변수 
        self.hit_cnt = 0
        self.flag = ""

    def stop(self):
    	#rax값을 읽는다. 0xff를 해서 ax만 남기는 거 같다. 
        ax = int(gp("$rax")) & 0xFF
        #flag에 ascii값 추가 
        self.flag += chr(ax)

        self.hit_cnt += 1
        #count 64개 채웠으면 다 찾은 거니까 stop 
        if self.hit_cnt >= 64:
            print("input:", self.flag)
        return False

# 여기 주소 뭐지 -> 아래서 후술 
pie_base = 0x555555554000
check_generated_flag(pie_base + 0x149F)

ge("run <<< asdf")
exit()

pie_base에 +0x149f(오프셋이다)는 아래 주소이다.

Image

Image

generate_flag 바로 이후 명령이다.

gdb로 코드영역 pie base 주소는 code라고 적어주면 된다.