awdp
因为本章纯新手向,所以只讲讲防御应该怎么防御
awdp介绍
一般会给你一个附件让修复里面的漏洞,然后提交修复好的附件进行check,并且提交次数是有限制的,假如是5次,你提交5次都没check过,那你就不允许继续提交了,所以要谨慎修复
php
seay & d盾
下载后直接扫描,会给出漏洞结果,但是该工具是基于正则表达式,所以可能存在很多误报
d盾也可以扫描,但是扫描结果不全,但是准确率高点,推荐先用d盾进行扫描
seay无法扫描到一些较新的漏洞函数,还有反序列化的函数也无法扫描
watchbird
https://github.com/leohearts/awd-watchbird
根据教程直接安装
常见漏洞代码
下面只是给出漏洞代码,如果watchbird不能解决的问题,那也不是给小白解决的,所以只给出简单漏洞代码,和修复建议
sql
1 |
|
一般修复就是对 $password
进行过滤,过滤掉引号那些
文件上传
1 |
|
未限制后缀名,直接上传,修复方法直接白名单后缀
文件包含
1 |
|
最简单的方法就是直接删掉 include
当然还有以下几个可以文件包含的函数1
2require_once
require
rce
给出最常见的命令执行函数,遇见直接删掉就行1
2
3
4
5eval
system
`` // 反引号
exec
shell_exec
反序列化
1 | unserialize |
直接删除即可
java
springboot jar
- jar包解压
python class2java.py BOOT-INF/classes/com #根据具体路径
- IDEA打开BOOT-INF/classes,导入BOOT-INF/lib,开始调试
- 加入防御代码,编译运行后,将target里面编译后新的class文件粘贴到原本的jar包中
反序列化
我这里只讲java的原生反序列化,不涉及hessian,kryo等其他序列化器1
2
3
4
5
6
7
8
9
10
11
12
13
14
public DataObject deserializeBase64( { String base64Data)
try {
// 解码 Base64 数据
byte[] data = Base64.getDecoder().decode(base64Data);
// 反序列化数据
try (ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(data))) {
return (DataObject) ois.readObject();
}
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException("Failed to deserialize object", e);
}
}
大概漏洞原理就是反序列化的时候,会执行需要反序列化的类的readObject,而该类的readObject含有高危代码,或者可以构造出高危漏洞的代码
修复
重写 ObjectInputStream#readClassDescriptor (重新该类是为了防止utf8-overlong绕过)
添加黑名单(白名单最好)
MyObjectInputStream.java(记得加package)
1 | import java.io.IOException; |
springboot代码也要改成如下(记得import上面的类)1
2
3
4
5
6
7
8
9
10
11
12
13
14
public DataObject deserializeBase64( { String base64Data)
try {
// 解码 Base64 数据
byte[] data = Base64.getDecoder().decode(base64Data);
// 反序列化数据,修改序列化器
try (ObjectInputStream ois = new MyObjectInputStream(new ByteArrayInputStream(data))) {
return (DataObject) ois.readObject();
}
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException("Failed to deserialize object", e);
}
}
rce
1 | Runtime.getRuntime().exec(var); |
特殊(反射)1
2clazz.getDeclaredMethod
method.invoke
修复
直接删除
通用漏洞修复
java总结
不嫌麻烦可以用codeql进行扫描
https://github.com/webraybtl/CodeQLpy
根据教程即可,但是需要安装codeql,有点麻烦
CodeQL的数据库中本质上保存的是与代码相关的AST语法树
python
ssti
漏洞代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
def index():
ip, port = re.findall(pattern,request.host).pop()
if request.method == 'POST' and request.form.get("word"):
word = request.form.get("word")
if not waf(word):
word = "Hacker!"
else:
word = ""
result = render_template_string(content % (str(ip), str(port), str(word)))
if 'flag{' in result:
result = "Hacker"
return result
该代码从post请求中获取传入的值,最后带入到了 render_template_string(content % (str(ip), str(port), str(word)))
看到最后有个render之类的函数,并且传入的参数可控,就很可能是ssti的漏洞点
修复
1 | # 修复代码 |
一般来说过滤掉 {{` , `}}
, {%` , `%}
,就可以很大程度防止该漏洞。如果遇到可以编码绕过的形式,那也不是小白能做的了。
反序列化
参考文章:https://goodapple.top/archives/1069
1 | from flask import Flask, request, jsonify |
漏洞点是 pickle.loads(data_bytes)
,data_bytes同样是从post数据中获取,并且进行了base64解码,最后反序列化(pickle.loads)
反序列化原理可以参考网上文章或者我给出的文章链接
修复
与java的反序列化修复类似,重写pickle1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49from flask import Flask, request, jsonify
import base64
import builtins
import io
import pickle
app = Flask(__name__)
safe_builtins = {
'range',
'complex',
'set',
'frozenset',
'slice',
}
class RestrictedUnpickler(pickle.Unpickler):
#重写了find_class方法
def find_class(self, module, name):
# Only allow safe classes from builtins.
if module == "builtins" and name in safe_builtins:
return getattr(builtins, name)
# Forbid everything else.
raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name))
def restricted_loads(s):
"""Helper function analogous to pickle.loads()."""
return RestrictedUnpickler(io.BytesIO(s)).load()
def deserialize():
# 获取 POST 请求中的 Base64 编码数据
data_base64 = request.get_json().get('data')
if not data_base64:
return jsonify({'error': 'No data provided'}), 400
try:
# 解码 Base64 数据
data_bytes = base64.b64decode(data_base64)
# 反序列化数据
data = restricted_loads(data_bytes)
return jsonify({'data': data}), 200
except Exception as e:
return jsonify({'error': str(e)}), 400
if __name__ == '__main__':
app.run(debug=True)
rce
危险函数,看到直接删了就行了1
2
3os.system
eval
os.subprocess
同样有flask举例1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23from flask import Flask, request, jsonify
import os
app = Flask(__name__)
def execute_command():
# 从请求中获取参数
command = request.get_json().get('command')
if not command:
return jsonify({'error': 'No command provided'}), 400
try:
# 执行命令
result = os.system(command)
return jsonify({'result': result}), 200
except Exception as e:
return jsonify({'error': str(e)}), 500
if __name__ == '__main__':
app.run(debug=True)
修复
直接删除即可
nodejs
原型链污染
1 | const merge = (a, b) => { |
修复
对传入的参数做一层过滤1
2
3
4
5
6
7
8function containsPrototypePollution(obj) {
for (let key in obj) {
if (key === '__proto__' || key === 'constructor' || key === 'prototype') {
return true;
}
}
return false;
}
总结
上面总结的漏洞只是该语言的冰山一角,只是挑了部分常见简单的来说
还有golang,c#的漏洞,但是上面那些语言更常见,就挑这些来说了,实在不知道怎么修复,但是能找到漏洞点,那就删掉