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