Commit a6057e2c by Thomas Barabosch

Unified interface of check_cwe function. Improved loading of cwe

checks. Ready to implement partial analyses.
parent 4682feba
......@@ -28,7 +28,10 @@ let check_multiplication_before_symbol proj prog sub blk jmp tid_map symbols =
(Symbol_utils.get_symbol_name_from_jmp jmp symbols))
let check_cwe prog proj tid_map symbol_names =
let symbols = Symbol_utils.build_symbols symbol_names prog in
match symbol_names with
| hd::[] ->
let symbols = Symbol_utils.build_symbols hd prog in
let calls = call_finder#run prog [] in
let relevant_calls = filter_calls_to_symbols calls symbols in
check_calls relevant_calls prog proj tid_map symbols check_multiplication_before_symbol
| _ -> failwith "[CWE190] symbol_names not as expected"
......@@ -5,4 +5,4 @@ https://cwe.mitre.org/data/definitions/190.html
val name : string
val version : string
val check_cwe : Bap.Std.program Bap.Std.term -> Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> string list -> unit
val check_cwe : Bap.Std.program Bap.Std.term -> Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> string list list -> unit
......@@ -30,7 +30,7 @@ let read_lines in_chan =
List.rev !lines
(* TODO: check if program contains strings like "DEBUG"*)
let check_cwe project =
let check_cwe _ project _ _ =
match Project.get project filename with
| Some fname -> begin
let cmd = Format.sprintf "readelf --debug-dump=decodedline %s | grep CU" fname in
......@@ -41,5 +41,5 @@ let check_cwe project =
Unix.Unix_error (e,fm,argm) ->
Log_utils.error "[%s] {%s} %s %s %s" name version (Unix.error_message e) fm argm
end
| _ -> ()
| _ -> failwith "[CWE215] symbol_names not as expected"
......@@ -3,4 +3,4 @@
val name : string
val version : string
val check_cwe : Bap.Std.project -> unit
val check_cwe : Bap.Std.program Bap.Std.term -> Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> string list list -> unit
......@@ -87,3 +87,4 @@ let check_cwe prog proj tid_map pathes =
| Some _ ->
Seq.iter (Term.enum sub_t prog) ~f:(fun sub -> check_subfunction prog tid_map sub pathes)
| _ -> ()
......@@ -5,5 +5,4 @@ See https://cwe.mitre.org/data/definitions/243.html for detailed description. *)
val name : string
val version : string
val check_cwe : Bap.Std.program Bap.Std.term ->
Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> string list list -> unit
val check_cwe : Bap.Std.program Bap.Std.term -> Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> string list list -> unit
......@@ -7,9 +7,7 @@ open Symbol_utils
let name = "CWE332"
let version = "0.1"
(* ToDo: Implement more checks for other PRNGs.
See https://wiki.openssl.org/index.php/Random_Numbers *)
let check_cwe program proj tid_map =
let check_cwe program proj tid_map symbol_pairs =
match Option.both (find_symbol program "srand") (find_symbol program "rand") with
| None -> begin
match (find_symbol program "rand") with
......@@ -17,4 +15,4 @@ let check_cwe program proj tid_map =
| Some _ -> Log_utils.warn "[%s] {%s} (Insufficient Entropy in PRNG) program uses rand without calling srand before" name version
end
| Some (srand_tid, rand_tid) -> ()
......@@ -6,4 +6,4 @@ See https://cwe.mitre.org/data/definitions/332.html for detailed description. *)
val name : string
val version : string
val check_cwe : Bap.Std.program Bap.Std.term -> 'a -> 'b -> unit
val check_cwe : Bap.Std.program Bap.Std.term -> 'a -> 'b -> string list list -> unit
......@@ -57,7 +57,6 @@ let handle_sub sub program tid_map symbols source sink =
else
()
(* TODO: access -> open is just one example of a TOCTOU *)
let check_cwe program proj tid_map =
let check_cwe program proj tid_map symbol_pairs =
let symbols = Symbol_utils.build_symbols ["access"; "open";] in
Seq.iter (Term.enum sub_t program) ~f:(fun s -> handle_sub s program tid_map symbols "access" "open")
......@@ -5,4 +5,4 @@ https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use
val name : string
val version : string
val check_cwe : Bap.Std.program Bap.Std.term -> Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> unit
val check_cwe : Bap.Std.program Bap.Std.term -> Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> string list list -> unit
......@@ -22,4 +22,7 @@ let handle_sub sub program tid_map symbols =
else ()
let check_cwe program proj tid_map symbols =
Seq.iter (Term.enum sub_t program) ~f:(fun s -> handle_sub s program tid_map symbols)
match symbols with
| hd::[] ->
Seq.iter (Term.enum sub_t program) ~f:(fun s -> handle_sub s program tid_map hd)
| _ -> failwith "[CWE426] symbol_names not as expected"
......@@ -11,4 +11,4 @@ drops privileges on startup. (Debian uses a modified bash which does not do thi
val name : string
val version : string
val check_cwe : Bap.Std.program Bap.Std.term -> Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> string list -> unit
val check_cwe : Bap.Std.program Bap.Std.term -> Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> string list list -> unit
......@@ -92,6 +92,5 @@ let check_subfunction prog proj tid_map sub =
end
end)
let check_cwe prog proj tid_map =
let check_cwe prog proj tid_map symbol_names =
Seq.iter (Term.enum sub_t prog) ~f:(fun sub -> check_subfunction prog proj tid_map sub)
......@@ -4,5 +4,4 @@ See https://cwe.mitre.org/data/definitions/457.html for detailed description. *)
val name: string
val version : string
val check_cwe : Bap.Std.program Bap.Std.term ->
Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> unit
val check_cwe : Bap.Std.program Bap.Std.term -> Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> string list list -> unit
......@@ -25,8 +25,10 @@ let check_input_is_pointer_size proj prog sub blk jmp tid_map symbols =
let check_cwe prog proj tid_map symbol_names =
let symbols = Symbol_utils.build_symbols symbol_names prog in
let calls = call_finder#run prog [] in
let relevant_calls = filter_calls_to_symbols calls symbols in
check_calls relevant_calls prog proj tid_map symbols check_input_is_pointer_size
match symbol_names with
| hd::[] ->
let symbols = Symbol_utils.build_symbols hd prog in
let calls = call_finder#run prog [] in
let relevant_calls = filter_calls_to_symbols calls symbols in
check_calls relevant_calls prog proj tid_map symbols check_input_is_pointer_size
| _ -> failwith "[CWE467] symbol_names not as expected"
......@@ -9,5 +9,4 @@ See https://cwe.mitre.org/data/definitions/467.html for detailed description. *)
val name : string
val version : string
val check_cwe : Bap.Std.program Bap.Std.term ->
Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> string list -> unit
val check_cwe : Bap.Std.program Bap.Std.term -> Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> string list list -> unit
......@@ -38,7 +38,10 @@ let check_null_pointer proj prog sub blk jmp tid_map symbols =
| _ -> assert(false))
let check_cwe prog proj tid_map symbol_names =
let symbols = Symbol_utils.build_symbols symbol_names prog in
let calls = call_finder#run prog [] in
let relevant_calls = filter_calls_to_symbols calls symbols in
check_calls relevant_calls prog proj tid_map symbols check_null_pointer
match symbol_names with
| hd::[] ->
let symbols = Symbol_utils.build_symbols hd prog in
let calls = call_finder#run prog [] in
let relevant_calls = filter_calls_to_symbols calls symbols in
check_calls relevant_calls prog proj tid_map symbols check_null_pointer
| _ -> failwith "[CWE476] symbol_names not as expected"
......@@ -5,5 +5,4 @@ See https://cwe.mitre.org/data/definitions/476.html for detailed description. *)
val name: string
val version : string
val check_cwe : Bap.Std.program Bap.Std.term ->
Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> string list -> unit
val check_cwe : Bap.Std.program Bap.Std.term -> Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> string list list -> unit
......@@ -35,9 +35,12 @@ let resolve_symbols prog symbols =
Seq.filter ~f:(fun s -> List.exists ~f:(fun x -> x = Sub.name s) symbols)
let check_cwe prog tid_map symbols =
let subfunctions = Term.enum sub_t prog in
let cg = Program.to_graph prog in
get_calls_to_symbols cg subfunctions (resolve_symbols prog symbols)
|> print_calls ~tid_map:tid_map
let check_cwe prog proj tid_map symbol_names =
match symbol_names with
| hd::[] ->
let subfunctions = Term.enum sub_t prog in
let cg = Program.to_graph prog in
get_calls_to_symbols cg subfunctions (resolve_symbols prog hd)
|> print_calls ~tid_map:tid_map
| _ -> failwith "[CWE676] symbol_names not as expected"
......@@ -5,4 +5,4 @@ See https://cwe.mitre.org/data/definitions/676.html for detailed description. *)
val name : string
val version : string
val check_cwe : Bap.Std.program Bap.Std.term -> Bap.Std.word Bap.Std.Tid.Map.t -> string list -> unit
val check_cwe : Bap.Std.program Bap.Std.term -> Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> string list list -> unit
......@@ -4,4 +4,4 @@ https://cwe.mitre.org/data/definitions/782.html *)
val name : string
val version : string
val check_cwe : Bap.Std.program Bap.Std.term -> Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> string list -> unit
val check_cwe : Bap.Std.program Bap.Std.term -> Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> string list list -> unit
......@@ -2,13 +2,26 @@
"CWE190": {
"symbols": ["xmalloc", "malloc", "realloc"]
},
"CWE215": {
"symbols": []
},
"CWE243": {
"chroot_pathes": [["chroot", "chdir"], ["chdir", "chroot", "setresuid"], ["chdir", "chroot", "seteuid"],
"pairs": [["chroot", "chdir"], ["chdir", "chroot", "setresuid"], ["chdir", "chroot", "seteuid"],
["chdir", "chroot", "setreuid"], ["chdir", "chroot", "setuid"]],
"_comment": "valid chroot pathes according to http://www.unixwiz.net/techtips/chroot-practices.html"
},
"CWE332": {
"init_rand_pairs": [["srand", "rand"]]
"pairs": [["srand", "rand"]]
},
"CWE367": {
"pairs": [["access", "open"]]
},
"CWE426": {
"symbols": ["setresgid", "setresuid", "setuid", "setgid", "seteuid", "setegid"],
"_comment": "functions that change/drop privileges"
},
"CWE457": {
"symbols": []
},
"CWE467": {
"symbols": ["strncmp", "malloc",
......@@ -34,6 +47,9 @@
"memcpy", "wmemcpy", "memmove", "wmemmove", "memcmp", "wmemcmp", "me​mset", "wmemset",
"gets", "sprintf​", "vsprintf", "swprintf", "vswprintf", "snprintf", "vsnprintf",
"realpath", "getwd", "wctomb", "wcrtomb", "wcstombs", "wcsrtombs", "wcsnrtombs"]
},
"CWE782": {
"symbols": []
}
}
......@@ -6,20 +6,27 @@ open Yojson.Basic.Util
include Self()
let known_modules = [(Cwe_190.name, Cwe_190.version);
(Cwe_215.name, Cwe_215.version);
(Cwe_243.name, Cwe_243.version);
(Cwe_332.name, Cwe_332.version);
(Cwe_367.name, Cwe_367.version);
(Cwe_426.name, Cwe_426.version);
(Cwe_467.name, Cwe_467.version);
(Cwe_476.name, Cwe_476.version);
(Cwe_457.name, Cwe_457.version);
(Cwe_676.name, Cwe_676.version);
(Cwe_782.name, Cwe_782.version)]
type cwe_module = {
cwe_func : Bap.Std.program Bap.Std.term -> Bap.Std.project -> Bap.Std.word Bap.Std.Tid.Map.t -> string list list -> unit;
name : string;
version : string;
requires_pairs : bool;
}
let known_modules = [{cwe_func = Cwe_190.check_cwe; name = Cwe_190.name; version = Cwe_190.version; requires_pairs = false};
{cwe_func = Cwe_215.check_cwe; name = Cwe_215.name; version = Cwe_215.version; requires_pairs = false};
{cwe_func = Cwe_243.check_cwe; name = Cwe_243.name; version = Cwe_243.version; requires_pairs = true};
{cwe_func = Cwe_332.check_cwe; name = Cwe_332.name; version = Cwe_332.version; requires_pairs = true};
{cwe_func = Cwe_367.check_cwe; name = Cwe_367.name; version = Cwe_367.version; requires_pairs = true};
{cwe_func = Cwe_426.check_cwe; name = Cwe_426.name; version = Cwe_426.version; requires_pairs = false};
{cwe_func = Cwe_457.check_cwe; name = Cwe_457.name; version = Cwe_457.version; requires_pairs = false};
{cwe_func = Cwe_467.check_cwe; name = Cwe_467.name; version = Cwe_467.version; requires_pairs = false};
{cwe_func = Cwe_476.check_cwe; name = Cwe_476.name; version = Cwe_476.version; requires_pairs = false};
{cwe_func = Cwe_676.check_cwe; name = Cwe_676.name; version = Cwe_676.version; requires_pairs = false};
{cwe_func = Cwe_782.check_cwe; name = Cwe_782.name; version = Cwe_782.version; requires_pairs = false}]
let build_version_sexp () =
List.map known_modules ~f:(fun (name, version) -> Format.sprintf "(\"%s\" \"%s\")" name version)
List.map known_modules ~f:(fun cwe -> Format.sprintf "(\"%s\" \"%s\")" cwe.name cwe.version)
|> String.concat ~sep:" "
let print_module_versions () =
......@@ -43,56 +50,14 @@ let get_symbols_from_json json cwe =
|> flatten
|> List.map ~f:to_string
let init_cwe_190 json project program tid_address_map =
let symbols = get_symbols_from_json json "CWE190" in
Cwe_190.check_cwe program project tid_address_map symbols
let init_cwe_215 json project program tid_address_map =
Cwe_215.check_cwe project
let init_cwe_243 json project program tid_address_map =
let get_symbol_lists_from_json json cwe =
[json]
|> filter_member "CWE243"
|> filter_member "chroot_pathes"
|> filter_member cwe
|> filter_member "pairs"
|> flatten
|> List.map ~f:(fun l -> List.map (to_list l) ~f:to_string)
|> Cwe_243.check_cwe program project tid_address_map
let init_cwe_332 json project program tid_address_map =
(* TODO: read config. *)
Cwe_332.check_cwe program project tid_address_map
let init_cwe_367 json project program tid_address_map =
(* TODO: read config. *)
Cwe_367.check_cwe program project tid_address_map
let init_cwe_426 json project program tid_address_map =
(* TODO: read config. *)
let symbols = ["setresgid"; "setresuid"; "setuid"; "setgid"; "seteuid"; "setegid"] in
Cwe_426.check_cwe program project tid_address_map symbols
let init_cwe_457 json project program tid_address_map =
Cwe_457.check_cwe program project tid_address_map
let init_cwe_467 json project program tid_address_map =
let symbols = get_symbols_from_json json "CWE467" in
Cwe_467.check_cwe program project tid_address_map symbols
let init_cwe_476 json project program tid_address_map =
let symbols = get_symbols_from_json json "CWE476" in
Cwe_476.check_cwe program project tid_address_map symbols
let init_cwe_676 json project program tid_address_map =
let symbols = get_symbols_from_json json "CWE676" in
Cwe_676.check_cwe program tid_address_map symbols
let init_cwe_782 json project program tid_address_map =
(* TODO: read config and hand over symbols from man ioctl *)
let symbols = [] in
Cwe_782.check_cwe program project tid_address_map symbols
let partial_run project config modules =
(* IMPLEMENT ME: checkout how to dispatch ocaml modules dynamically *)
let program = Project.program project in
let tid_address_map = Address_translation.generate_tid_map program in
let json = Yojson.Basic.from_file config in
......@@ -103,17 +68,16 @@ let full_run project config =
let tid_address_map = Address_translation.generate_tid_map program in
let json = Yojson.Basic.from_file config in
begin
init_cwe_190 json project program tid_address_map;
init_cwe_215 json project program tid_address_map;
init_cwe_243 json project program tid_address_map;
init_cwe_332 json project program tid_address_map;
init_cwe_367 json project program tid_address_map;
init_cwe_426 json project program tid_address_map;
init_cwe_457 json project program tid_address_map;
init_cwe_467 json project program tid_address_map;
init_cwe_476 json project program tid_address_map;
init_cwe_676 json project program tid_address_map;
init_cwe_782 json project program tid_address_map
List.iter known_modules ~f:(fun cwe -> if cwe.requires_pairs = true then
begin
let symbol_pairs = get_symbol_lists_from_json json cwe.name in
cwe.cwe_func program project tid_address_map symbol_pairs
end
else
begin
let symbols = get_symbols_from_json json cwe.name in
cwe.cwe_func program project tid_address_map [symbols]
end)
end
let main config module_versions partial_update project =
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment