Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SecHack365 Returns 2019 修了生プレゼンテーション

SecHack365 Returns 2019 修了生プレゼンテーション

2019/1/13 に開催されたSecHack365修了生向けのイベントSecHack365 Returnsで行ったプレゼンテーションです。
奨励賞をいただきました。
TODO:開催レポートへのリンク

友利奈緒(@K_atc)

January 13, 2019
Tweet

More Decks by 友利奈緒(@K_atc)

Other Decks in Science

Transcript

  1. Symbolic Backward Execution Security Engineer Interested in vulnerability detection (especially

    symbolic execution), illustration. Doing for 6 years. Person same with author. https://www.pixiv.net/member.php?id=4440209 Profile
  2. Symbolic Backward Execution Symbolic execution is a execution symbolizes any

    inputs. Symbol is similar to mathematical variables, and is NOT fixed values. In symbolic execution, execution environment such as registers, stack, memory, and files are symbolized. What is symbolic execution? Concept of Forward Symbolic Execution (FSE) (FSE is a method often adopted to implement symbolic execution) void testme(int a, int b) { int c = 0; if (a * b == 6) { c = 1; if (a == 1) c = 3; } assert(a * b * c == 6); } a ✕ b = 6 ∧ c ≠ 0 a ✕ b ≠ 6 ∧ c = 0 Φ a ✕ b = 6 ∧ a = 1 ∧ c = 1 a ✕ b = 6 ∧ a ≠ 1 ∧ c = 1 ✔ Assertion pass ✔ Assertion pass ✔ Assertion fail … path constraint
  3. 2 • [2016/10] SECCON 2016 • [2017/9 - 2017/10] •

    [2017/5 - 2018/2] Triton SecHack365 • [2016/? - 2018/1] 2017 Symbolic Backward Execution
  4. Symbolic Backward Execution Forward Symbolic Execution FSE • Path Explosion

    → • m O( 2|m| ) → *Forward Symbolic Execution
  5. Symbolic Backward Execution Toward automation of exploit, is there any

    good solutions mitigates weakness of symbolic execution? Black box that fulfills her wish ? Exploit Code Something Good Symbolic Execution ((o( ∀ )o)) What... what is it?
  6. Symbolic Backward Execution A security test that generates unexpected input

    and checks the presence of abnormal behavior [Supplement] What is Fuzzing? Fuzzer Program Spectacle of idyllical fuzzing
  7. Symbolic Backward Execution notes: original Linux CUI application which manages

    notes Pointer can be overwritten by buffer over flow bug Deploys shellcode to known address to make things simple About demo application to be exploited Futaba% ./notes ---- [menu] ---- n: new note u: update note s: show notes q: quit input command: n ==== [note #0] ==== title: Futaki Futaba content: I’m a high school student. ---- [menu] ---- ... snipped ... input command: s note #0:Futaki Futaba I’m a high school student. typedef struct { char* content; char title[16]; } note; note notes[8]; void update_note(unsigned int note_id) { ... snipped ... _printf(“title: "); _fgets(notes[note_id].title, 1024, stdin); } Buffer overflow bug section Definition of notes struct Pointer can be overwritten BOF
  8. Symbolic Backward Execution Let’s Fuzzing (>ω<)/ afl-fuzz -i inputs/notes -o

    result ./notes n title content s n title 2 content! s u 3 n title 3 content!! s q Number of crashes
  9. Symbolic Backward Execution Verify fuzzing result wasabi% xxd result-notes/crashes/id:000004,sig:07, src:000000,op:havoc,rep:32

    00000000: 6ef8 5d69 74e9 6d0d 320a 730a 750a 330a 00000010: 6e6c 65ff 68ff ff6f 8121 212e 7a81 2121 00000020: 20d5 0a63 6e6e 2120 d50a 636e 6e66 adad 00000030: adad 66ad adad adad adad ad22 adad adad 00000040: adad ad9d adad adad 0d51 0a73 0a75 0a33 00000050: 0a6e 6c65 ff28 ffff 6f81 2121 20d5 0a63 00000060: 6e6e 6e6e 6e81 e16e 6e6e 6e6e 7e6e 6e6f 00000070: 6e21 ff00 730a 71 Crashed due to illegal memory access! It’s exploitable crash!! Let’s pass this input to Futaba Crash input Inspection on gdb ③ rbp can be arbitrary value ② Terminated by illegal memory access ① Definitively the crash was reproduced
  10. Symbolic Backward Execution Futaba adopted Triton at this time •

    Tracer: can symbolically execute paths follows given input • libc: can symbolically fast execute libc Futaba <| Which symbolic execution engine should I use? | Triton angr KLEE S2E Published in 2015 2016 2008 2011 Usability Medium Easy Easy Medium Hard User Script Python Python command line, C/C++ Lua, C++ Tracer Available Not Works N/A N/A libc Fully Symbolically Executed Replaced with Symbolic Procedure 1) Engine is written in C++ Python C++ C++ Essential requirements when crash occurs in libc Comparison of symbolic execution engine Crashable execution path is known 1) libc can be symbolically executed, but slow
  11. Symbolic Backward Execution How to make an exploit code from

    a crash input? mov byte ptr [rbp], al Invalid Memory Access Native execution Symbolic Execution following traced path • Path constraint • Memory access constraint mov byte ptr [symvar_rbp], symvar_al Theorem on arbitrary memory overwrite: Be able to write value a on memory address A when executing this instruction ⇔constraint symvar_rbp == A, symvar_al == a is satisfiable • Crash Generate crash input Arbitrary Memory Overwrite PC Hijack Trigger shellcode Tracer executes according input of . Outputs instructions trace. NOTE: Described in AFL verification phase Crash input from AFL
  12. Symbolic Backward Execution How to make an exploit code from

    a crash input? GOT (Global Offset Table) holds libc function address. Using GOT Overwrite, libc function address are overwritten with X (*A = X). fputs() fputs@libc() Index Real Addr fputs fputs@libc GOT lookup call func fputs() X() Index Real Addr fputs X GOT (Overwritten) lookup call func This time, there is a function to invoke shell and this address is known. Let X be shellcode address. (In case of GOT Overwrite) Generate crash input Arbitrary Memory Overwrite PC Hijack Trigger shellcode
  13. Symbolic Backward Execution Futaba (I) encountered the following problem and

    it is fixed by her (my) pull request*. Triton can handle signals caused by Tracers, but Tracer ignores SIGBUS and terminates Triton. Fixed to handle SIGBUS in Tracer z3** throws (exception z3::exception) when constraint is wrong. Triton passes on this exception and exits with no messages. Fixed to catch this exception (thanks Jonathan for helping! Run-time error of Triton * This pullreq #695 is merged to dev-v0.6 branch. dev-v0.6 was merged with master branch in Jun 29, 2018. ** z3 is a constraint solver. Triton leverages z3 in back-end.
  14. Symbolic Backward Execution ※SMT * z3py *SMT Satisfiability Modulo Theories

    ∀∃ from z3 import * x, y = Ints('x y') wp = True wp = And(y > 3, wp) wp = substitute(wp, (y, x + 2)) simplify(wp) print(wp) Not(x <= 1) { ? } y := x + 2; assert y > 3; {true} x > 1 ⇄ x > 1
  15. Python Weakest Precondition SBE Python • • • If ※

    • ※ Symbolic Backward Execution by @K_atc Translate GCL & Gen Symbol Vars wp(S, Q) GCL S Q Python Code Models Solve (Concretize) Symbolic Backward Execution Engine
  16. Symbolic Backward Execution GCL Python GCL class GCL(): op =

    "" def __init__(self): pass class Substitute(GCL): op = op.Substitute def __init__(self, x, e): self.x = x # self.e = e # def __repr__(self): return "{}({}, {})".format(self.op, self.x, self.e) x, e
  17. Symbolic Backward Execution 1. Python ast AST 2. AST GCL

    Python →Python AST→GCL import ast code = "if (x > 0): y = 1" p = ast.parse(code) S = seq_node(p.body) if isinstance(node, ast.Assign): target = expr_node(node.targets[0], depth + 1, function_name) value = expr_node(node.value, depth + 1, function_name) assign_returned_values = __assign_returned_values(node.value) return assign_returned_values + gcl.Substitute(target, value) Assign →GCL GCL If(x > 0, Substitute(y, 1), Skip()) S Module(body=[If(test=Compare(left=Name(id=‘x’, ctx=Load()), ops=[Gt()], comparators=[Num(n=0)]), body=[Assign(targets=[Name(id='y', ctx=Store())], value=Num(n=1))], orelse=[])]) p Python AST GCL
  18. Symbolic Backward Execution wp(S, Q) def wp(S, Q): …. snipped

    … if S.op is node.op.Substitute: … snipped … if z3.is_expr(Q): return z3.substitute(Q, (S.x, S.e)) else: # Q is Bool return Q … snipped … if S.op is node.op.Seq: return wp(S.S1, wp(S.S2, Q)) … snipped … Weakest Precondition Python wp(S, Q)
  19. { ??? } y = (x + 1) * 2

    if y >= 6: z = 1 else: z = 0 assert(z == 1) { True } presen-demo.py Symbolic Backward Execution x
  20. Symbolic Backward Execution if expr = """ y = (x

    + 1) * 2 if y >= 6: z = 1 else: z = 0 assert(z == 1) """ p = ast.parse(expr) S = seq_node(p.body) Q = True print("S = {}".format(S)) print("Q = {}".format(Q)) P = wp(S, Q) P = simplify(P) print("wp(S, Q) = {}".format(P)) S = Seq(Substitute(y, (x + 1)*2), Seq(If(y >= 6, Substitute(z, 1), Substitute(z, 0)), Assert(z == 1))) Q = True wp(S, Q) = x >= 2
  21. Symbolic Backward Execution Futaba and Aoi (I) worked on automated

    exploit generation with the following approach. 1. Generate input causes crash using fuzzing 2. Execute the path may triggers crash symbolically 3. Solve constraints and generate exploit code Futaba&Aoi’s (my) AEG is available on GitHub: https://github.com/macaron-et/wasabi-aeg Apply this tool to other vulnerable application. Find exploitable crash using fuzzing. (Sadly, pwn binaries of CTF may have meaningless DoS vulnerabilities) Conclusion: Automated Exploit Generation Try it!
  22. • Weakest Precondition SBE Python • SBE Weakest Precondition •

    ✌(‘ω’✌ ) ✌(‘ω’)✌ ( ✌‘ω’)✌ • • ※ • While CFG Symbolic Backward Execution Symbolic Backward Execution