one_gadget 1.6.2 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +141 -94
- data/bin/one_gadget +4 -3
- data/lib/one_gadget/abi.rb +42 -22
- data/lib/one_gadget/builds/libc-2.19-397c84e78c14cbffba39a48184db482211df9fb3.rb +38 -0
- data/lib/one_gadget/builds/libc-2.19-4eda8ff01be3fba1c7bdd442a8690c3dc7397b6a.rb +44 -0
- data/lib/one_gadget/builds/libc-2.19-509ee0c9616c4c3ed81951501a8950e1f529bbff.rb +38 -0
- data/lib/one_gadget/builds/libc-2.19-6aff6d091954955fe931bb720a17708513aabda7.rb +41 -0
- data/lib/one_gadget/builds/libc-2.19-8d935a42f2f2a1149aa52d3098b32b1d5012cb67.rb +38 -0
- data/lib/one_gadget/builds/libc-2.19-a820f849dda0b99ed06dd59bb88404969b3a5f88.rb +41 -0
- data/lib/one_gadget/builds/libc-2.19-d9a10b8ef90300628dd0a3a535106967714d7328.rb +47 -0
- data/lib/one_gadget/builds/libc-2.21-169a143e9c40cfd9d09695333e45fd67743cd2d6.rb +37 -0
- data/lib/one_gadget/builds/libc-2.21-2e9718e58257bda1dc0d751665a3ee233bf606f2.rb +37 -0
- data/lib/one_gadget/builds/libc-2.23-29e38445a740bba5a77b86691e3c51a7e48dc79b.rb +46 -0
- data/lib/one_gadget/builds/libc-2.23-679ad41a6bc9e718a11a36cf9879cac97197e565.rb +37 -0
- data/lib/one_gadget/builds/libc-2.23-b5381a457906d279073822a5ceb24c4bfef94ddb.rb +37 -0
- data/lib/one_gadget/builds/libc-2.23-d10fbfd9328f5ffaca50aa93562cb3bfb618fbcc.rb +43 -0
- data/lib/one_gadget/builds/libc-2.23-dd5192a769e33ed6ca68a6ab5740ff9e8ec678a7.rb +46 -0
- data/lib/one_gadget/builds/libc-2.24-1f7bdfb9a24714835cee6e6597ea7aa782821371.rb +46 -0
- data/lib/one_gadget/builds/libc-2.24-206b2bb216b6cdb6b1be565a6fcd29f3862db060.rb +49 -0
- data/lib/one_gadget/builds/libc-2.24-26e84118fee5788eb5d8dda66b7e7f029d2c7800.rb +43 -0
- data/lib/one_gadget/builds/libc-2.24-43adbb1e7368c94fba1ba9020d8ef0808bff5bc4.rb +37 -0
- data/lib/one_gadget/builds/libc-2.24-497931f8d2346a6d0e300a65d8fc6106c6c88c15.rb +37 -0
- data/lib/one_gadget/builds/libc-2.24-4fa7401566d6b3e2c7ee5df3b4d85a01f85b595c.rb +37 -0
- data/lib/one_gadget/builds/libc-2.24-568d20b7e0d08bc282fb42ae405c7054e4209ede.rb +37 -0
- data/lib/one_gadget/builds/libc-2.24-5b72576ff331e93852355123afecdec70fd247b5.rb +49 -0
- data/lib/one_gadget/builds/libc-2.24-a4c01d397b6584f7040ef266b16a5d4da0b7a087.rb +43 -0
- data/lib/one_gadget/builds/libc-2.24-b81a06f0ac241c4aa8860602d9abcc903adbb675.rb +46 -0
- data/lib/one_gadget/builds/libc-2.24-be6d412ecc4816c46eb49e750b02f714a9131c4e.rb +46 -0
- data/lib/one_gadget/builds/libc-2.24-d2a8a8ac188a6c3bafa4813a3d2789240ee49489.rb +46 -0
- data/lib/one_gadget/builds/libc-2.24-dff06414a29b97b865ef938e06a7751fe8b1b2d0.rb +46 -0
- data/lib/one_gadget/builds/libc-2.24-e5dc6c0caa39828fa10ed37e642723a581acdb6d.rb +37 -0
- data/lib/one_gadget/builds/libc-2.24-fd0655c4d2073eda4235084e1d0e558f0251be8a.rb +37 -0
- data/lib/one_gadget/builds/libc-2.25-e5eb6347f0629b37bf698200022a683b7efb10ed.rb +37 -0
- data/lib/one_gadget/builds/libc-2.26-1c39b3b3faa2a2cbb0fa0b6845b29332562262d3.rb +37 -0
- data/lib/one_gadget/builds/libc-2.26-499b381aaf00ce85ee5d4a12770ea369b30d2a41.rb +52 -0
- data/lib/one_gadget/builds/libc-2.26-4cc84abfe1fd26a485fc2b1b954c281ce9d358fd.rb +52 -0
- data/lib/one_gadget/builds/libc-2.26-4ea852c9d6a5084b8b58509b3b3d37d3d8cddb90.rb +52 -0
- data/lib/one_gadget/builds/libc-2.26-6d2b609f0c8e7b338f767b08c5ac712fac809d31.rb +49 -0
- data/lib/one_gadget/builds/libc-2.26-fb587bc4429e7d1b0de31a3b9ee8ae78ee797eb0.rb +37 -0
- data/lib/one_gadget/builds/libc-2.27-0e188ec5f09c187a7a92784d4b97aa251b15a93c.rb +47 -0
- data/lib/one_gadget/builds/libc-2.27-53f40c1d2f3739ae017dcdcef1a17314786e3709.rb +38 -0
- data/lib/one_gadget/builds/libc-2.27-9dd0bb57f81671704475d1e5163405f7b4d4b454.rb +32 -0
- data/lib/one_gadget/builds/libc-2.28-44f5a3efb0e5733fa9d97e690cb36cd4c682bcdb.rb +41 -0
- data/lib/one_gadget/builds/libc-2.28-5784a31a1c26f6d2157e585205ebb63dd19ff90f.rb +41 -0
- data/lib/one_gadget/builds/libc-2.28-5b157f49586a3ca84d55837f97ff466767dd3445.rb +38 -0
- data/lib/one_gadget/builds/libc-2.28-6ee9454b96efa9e343f9e8105f2fa4529265ea05.rb +38 -0
- data/lib/one_gadget/emulators/aarch64.rb +176 -0
- data/lib/one_gadget/emulators/amd64.rb +1 -1
- data/lib/one_gadget/emulators/i386.rb +1 -1
- data/lib/one_gadget/emulators/instruction.rb +36 -7
- data/lib/one_gadget/emulators/lambda.rb +36 -25
- data/lib/one_gadget/emulators/processor.rb +94 -6
- data/lib/one_gadget/emulators/x86.rb +43 -95
- data/lib/one_gadget/error.rb +15 -3
- data/lib/one_gadget/fetcher.rb +3 -1
- data/lib/one_gadget/fetchers/aarch64.rb +41 -0
- data/lib/one_gadget/fetchers/amd64.rb +4 -2
- data/lib/one_gadget/fetchers/base.rb +35 -11
- data/lib/one_gadget/fetchers/i386.rb +2 -2
- data/lib/one_gadget/fetchers/x86.rb +23 -0
- data/lib/one_gadget/gadget.rb +63 -11
- data/lib/one_gadget/helper.rb +282 -203
- data/lib/one_gadget/one_gadget.rb +12 -4
- data/lib/one_gadget/version.rb +1 -1
- metadata +57 -6
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'one_gadget/gadget'
|
2
|
+
# https://gitlab.com/libcdb/libcdb/blob/master/libc/libc6_2.26-0ubuntu2_i386/lib/i386-linux-gnu/libc-2.26.so
|
3
|
+
#
|
4
|
+
# Intel 80386
|
5
|
+
#
|
6
|
+
# GNU C Library (Ubuntu GLIBC 2.26-0ubuntu2) stable release version 2.26, by Roland McGrath et al.
|
7
|
+
# Copyright (C) 2017 Free Software Foundation, Inc.
|
8
|
+
# This is free software; see the source for copying conditions.
|
9
|
+
# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
|
10
|
+
# PARTICULAR PURPOSE.
|
11
|
+
# Compiled by GNU CC version 6.4.0 20171010.
|
12
|
+
# Available extensions:
|
13
|
+
# crypt add-on version 2.1 by Michael Glad and others
|
14
|
+
# GNU Libidn by Simon Josefsson
|
15
|
+
# Native POSIX Threads Library by Ulrich Drepper et al
|
16
|
+
# BIND-8.2.3-T5B
|
17
|
+
# libc ABIs: UNIQUE IFUNC
|
18
|
+
# For bug reporting instructions, please see:
|
19
|
+
# <https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
|
20
|
+
|
21
|
+
build_id = File.basename(__FILE__, '.rb').split('-').last
|
22
|
+
OneGadget::Gadget.add(build_id, 250868,
|
23
|
+
constraints: ["esi is the GOT address of libc", "[esp+0x34] == NULL"],
|
24
|
+
effect: "execve(\"/bin/sh\", esp+0x34, environ)")
|
25
|
+
OneGadget::Gadget.add(build_id, 250870,
|
26
|
+
constraints: ["esi is the GOT address of libc", "[esp+0x38] == NULL"],
|
27
|
+
effect: "execve(\"/bin/sh\", esp+0x38, environ)")
|
28
|
+
OneGadget::Gadget.add(build_id, 250874,
|
29
|
+
constraints: ["esi is the GOT address of libc", "[esp+0x3c] == NULL"],
|
30
|
+
effect: "execve(\"/bin/sh\", esp+0x3c, environ)")
|
31
|
+
OneGadget::Gadget.add(build_id, 250881,
|
32
|
+
constraints: ["esi is the GOT address of libc", "[esp+0x40] == NULL"],
|
33
|
+
effect: "execve(\"/bin/sh\", esp+0x40, environ)")
|
34
|
+
OneGadget::Gadget.add(build_id, 250916,
|
35
|
+
constraints: ["esi is the GOT address of libc", "[eax] == NULL || eax == NULL", "[[esp]] == NULL || [esp] == NULL"],
|
36
|
+
effect: "execve(\"/bin/sh\", eax, [esp])")
|
37
|
+
OneGadget::Gadget.add(build_id, 250917,
|
38
|
+
constraints: ["esi is the GOT address of libc", "[[esp]] == NULL || [esp] == NULL", "[[esp+0x4]] == NULL || [esp+0x4] == NULL"],
|
39
|
+
effect: "execve(\"/bin/sh\", [esp], [esp+0x4])")
|
40
|
+
OneGadget::Gadget.add(build_id, 425551,
|
41
|
+
constraints: ["edi is the GOT address of libc", "eax == NULL"],
|
42
|
+
effect: "execl(\"/bin/sh\", eax)")
|
43
|
+
OneGadget::Gadget.add(build_id, 425552,
|
44
|
+
constraints: ["edi is the GOT address of libc", "[esp] == NULL"],
|
45
|
+
effect: "execl(\"/bin/sh\", [esp])")
|
46
|
+
OneGadget::Gadget.add(build_id, 1269749,
|
47
|
+
constraints: ["esi is the GOT address of libc", "eax == NULL"],
|
48
|
+
effect: "execl(\"/bin/sh\", eax)")
|
49
|
+
OneGadget::Gadget.add(build_id, 1269750,
|
50
|
+
constraints: ["esi is the GOT address of libc", "[esp] == NULL"],
|
51
|
+
effect: "execl(\"/bin/sh\", [esp])")
|
52
|
+
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'one_gadget/gadget'
|
2
|
+
# https://gitlab.com/libcdb/libcdb/blob/master/libc/libc6_2.26-0ubuntu2_amd64/lib/x86_64-linux-gnu/libc-2.26.so
|
3
|
+
#
|
4
|
+
# Advanced Micro Devices X86-64
|
5
|
+
#
|
6
|
+
# GNU C Library (Ubuntu GLIBC 2.26-0ubuntu2) stable release version 2.26, by Roland McGrath et al.
|
7
|
+
# Copyright (C) 2017 Free Software Foundation, Inc.
|
8
|
+
# This is free software; see the source for copying conditions.
|
9
|
+
# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
|
10
|
+
# PARTICULAR PURPOSE.
|
11
|
+
# Compiled by GNU CC version 6.4.0 20171010.
|
12
|
+
# Available extensions:
|
13
|
+
# crypt add-on version 2.1 by Michael Glad and others
|
14
|
+
# GNU Libidn by Simon Josefsson
|
15
|
+
# Native POSIX Threads Library by Ulrich Drepper et al
|
16
|
+
# BIND-8.2.3-T5B
|
17
|
+
# libc ABIs: UNIQUE IFUNC
|
18
|
+
# For bug reporting instructions, please see:
|
19
|
+
# <https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
|
20
|
+
|
21
|
+
build_id = File.basename(__FILE__, '.rb').split('-').last
|
22
|
+
OneGadget::Gadget.add(build_id, 293958,
|
23
|
+
constraints: ["rax == NULL"],
|
24
|
+
effect: "execve(\"/bin/sh\", rsp+0x30, environ)")
|
25
|
+
OneGadget::Gadget.add(build_id, 294042,
|
26
|
+
constraints: ["[rsp+0x30] == NULL"],
|
27
|
+
effect: "execve(\"/bin/sh\", rsp+0x30, environ)")
|
28
|
+
OneGadget::Gadget.add(build_id, 890627,
|
29
|
+
constraints: ["[r13] == NULL || r13 == NULL", "[rbx] == NULL || rbx == NULL"],
|
30
|
+
effect: "execve(\"/bin/sh\", r13, rbx)")
|
31
|
+
OneGadget::Gadget.add(build_id, 891345,
|
32
|
+
constraints: ["[[rbp-0xa0]] == NULL || [rbp-0xa0] == NULL", "[[rbp-0x70]] == NULL || [rbp-0x70] == NULL"],
|
33
|
+
effect: "execve(\"/bin/sh\", [rbp-0xa0], [rbp-0x70])")
|
34
|
+
OneGadget::Gadget.add(build_id, 891352,
|
35
|
+
constraints: ["[rcx] == NULL || rcx == NULL", "[[rbp-0x70]] == NULL || [rbp-0x70] == NULL"],
|
36
|
+
effect: "execve(\"/bin/sh\", rcx, [rbp-0x70])")
|
37
|
+
OneGadget::Gadget.add(build_id, 891356,
|
38
|
+
constraints: ["[rcx] == NULL || rcx == NULL", "[rdx] == NULL || rdx == NULL"],
|
39
|
+
effect: "execve(\"/bin/sh\", rcx, rdx)")
|
40
|
+
OneGadget::Gadget.add(build_id, 1035374,
|
41
|
+
constraints: ["[rsp+0x40] == NULL"],
|
42
|
+
effect: "execve(\"/bin/sh\", rsp+0x40, environ)")
|
43
|
+
OneGadget::Gadget.add(build_id, 1035386,
|
44
|
+
constraints: ["[rsi] == NULL || rsi == NULL", "[[rax]] == NULL || [rax] == NULL"],
|
45
|
+
effect: "execve(\"/bin/sh\", rsi, [rax])")
|
46
|
+
OneGadget::Gadget.add(build_id, 1039134,
|
47
|
+
constraints: ["[rsp+0x70] == NULL"],
|
48
|
+
effect: "execve(\"/bin/sh\", rsp+0x70, environ)")
|
49
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'one_gadget/gadget'
|
2
|
+
# https://gitlab.com/libcdb/libcdb/blob/master/libc/libc6-amd64_2.26-0ubuntu2.1_i386/lib64/libc-2.26.so
|
3
|
+
#
|
4
|
+
# Advanced Micro Devices X86-64
|
5
|
+
#
|
6
|
+
# GNU C Library (Ubuntu GLIBC 2.26-0ubuntu2.1) stable release version 2.26, by Roland McGrath et al.
|
7
|
+
# Copyright (C) 2017 Free Software Foundation, Inc.
|
8
|
+
# This is free software; see the source for copying conditions.
|
9
|
+
# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
|
10
|
+
# PARTICULAR PURPOSE.
|
11
|
+
# Compiled by GNU CC version 6.4.0 20171010.
|
12
|
+
# Available extensions:
|
13
|
+
# crypt add-on version 2.1 by Michael Glad and others
|
14
|
+
# GNU Libidn by Simon Josefsson
|
15
|
+
# Native POSIX Threads Library by Ulrich Drepper et al
|
16
|
+
# BIND-8.2.3-T5B
|
17
|
+
# libc ABIs: UNIQUE IFUNC
|
18
|
+
# For bug reporting instructions, please see:
|
19
|
+
# <https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
|
20
|
+
|
21
|
+
build_id = File.basename(__FILE__, '.rb').split('-').last
|
22
|
+
OneGadget::Gadget.add(build_id, 269098,
|
23
|
+
constraints: ["rax == NULL"],
|
24
|
+
effect: "execve(\"/bin/sh\", rsp+0x30, environ)")
|
25
|
+
OneGadget::Gadget.add(build_id, 269182,
|
26
|
+
constraints: ["[rsp+0x30] == NULL"],
|
27
|
+
effect: "execve(\"/bin/sh\", rsp+0x30, environ)")
|
28
|
+
OneGadget::Gadget.add(build_id, 799376,
|
29
|
+
constraints: ["[r12] == NULL || r12 == NULL", "[r13] == NULL || r13 == NULL"],
|
30
|
+
effect: "execve(\"/bin/sh\", r12, r13)")
|
31
|
+
OneGadget::Gadget.add(build_id, 921694,
|
32
|
+
constraints: ["[rsp+0x70] == NULL"],
|
33
|
+
effect: "execve(\"/bin/sh\", rsp+0x70, environ)")
|
34
|
+
OneGadget::Gadget.add(build_id, 921706,
|
35
|
+
constraints: ["[rsi] == NULL || rsi == NULL", "[[rax]] == NULL || [rax] == NULL"],
|
36
|
+
effect: "execve(\"/bin/sh\", rsi, [rax])")
|
37
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'one_gadget/gadget'
|
2
|
+
# https://gitlab.com/libcdb/libcdb/blob/master/libc/libc6_2.27-3ubuntu1_i386/lib/i386-linux-gnu/libc-2.27.so
|
3
|
+
#
|
4
|
+
# Intel 80386
|
5
|
+
#
|
6
|
+
# GNU C Library (Ubuntu GLIBC 2.27-3ubuntu1) stable release version 2.27.
|
7
|
+
# Copyright (C) 2018 Free Software Foundation, Inc.
|
8
|
+
# This is free software; see the source for copying conditions.
|
9
|
+
# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
|
10
|
+
# PARTICULAR PURPOSE.
|
11
|
+
# Compiled by GNU CC version 7.3.0.
|
12
|
+
# libc ABIs: UNIQUE IFUNC
|
13
|
+
# For bug reporting instructions, please see:
|
14
|
+
# <https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
|
15
|
+
|
16
|
+
build_id = File.basename(__FILE__, '.rb').split('-').last
|
17
|
+
OneGadget::Gadget.add(build_id, 250067,
|
18
|
+
constraints: ["esi is the GOT address of libc", "[esp+0x34] == NULL"],
|
19
|
+
effect: "execve(\"/bin/sh\", esp+0x34, environ)")
|
20
|
+
OneGadget::Gadget.add(build_id, 250069,
|
21
|
+
constraints: ["esi is the GOT address of libc", "[esp+0x38] == NULL"],
|
22
|
+
effect: "execve(\"/bin/sh\", esp+0x38, environ)")
|
23
|
+
OneGadget::Gadget.add(build_id, 250073,
|
24
|
+
constraints: ["esi is the GOT address of libc", "[esp+0x3c] == NULL"],
|
25
|
+
effect: "execve(\"/bin/sh\", esp+0x3c, environ)")
|
26
|
+
OneGadget::Gadget.add(build_id, 250080,
|
27
|
+
constraints: ["esi is the GOT address of libc", "[esp+0x40] == NULL"],
|
28
|
+
effect: "execve(\"/bin/sh\", esp+0x40, environ)")
|
29
|
+
OneGadget::Gadget.add(build_id, 250115,
|
30
|
+
constraints: ["esi is the GOT address of libc", "[eax] == NULL || eax == NULL", "[[esp]] == NULL || [esp] == NULL"],
|
31
|
+
effect: "execve(\"/bin/sh\", eax, [esp])")
|
32
|
+
OneGadget::Gadget.add(build_id, 250116,
|
33
|
+
constraints: ["esi is the GOT address of libc", "[[esp]] == NULL || [esp] == NULL", "[[esp+0x4]] == NULL || [esp+0x4] == NULL"],
|
34
|
+
effect: "execve(\"/bin/sh\", [esp], [esp+0x4])")
|
35
|
+
OneGadget::Gadget.add(build_id, 424575,
|
36
|
+
constraints: ["esi is the GOT address of libc", "eax == NULL"],
|
37
|
+
effect: "execl(\"/bin/sh\", eax)")
|
38
|
+
OneGadget::Gadget.add(build_id, 424576,
|
39
|
+
constraints: ["esi is the GOT address of libc", "[esp] == NULL"],
|
40
|
+
effect: "execl(\"/bin/sh\", [esp])")
|
41
|
+
OneGadget::Gadget.add(build_id, 1277534,
|
42
|
+
constraints: ["ebx is the GOT address of libc", "eax == NULL"],
|
43
|
+
effect: "execl(\"/bin/sh\", eax)")
|
44
|
+
OneGadget::Gadget.add(build_id, 1277535,
|
45
|
+
constraints: ["ebx is the GOT address of libc", "[esp] == NULL"],
|
46
|
+
effect: "execl(\"/bin/sh\", [esp])")
|
47
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'one_gadget/gadget'
|
2
|
+
# spec/data/aarch64-libc-2.27.so
|
3
|
+
#
|
4
|
+
# AArch64
|
5
|
+
#
|
6
|
+
# GNU C Library (Ubuntu GLIBC 2.27-3ubuntu1) stable release version 2.27.
|
7
|
+
# Copyright (C) 2018 Free Software Foundation, Inc.
|
8
|
+
# This is free software; see the source for copying conditions.
|
9
|
+
# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
|
10
|
+
# PARTICULAR PURPOSE.
|
11
|
+
# Compiled by GNU CC version 7.3.0.
|
12
|
+
# libc ABIs: UNIQUE
|
13
|
+
# For bug reporting instructions, please see:
|
14
|
+
# <https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
|
15
|
+
|
16
|
+
build_id = File.basename(__FILE__, '.rb').split('-').last
|
17
|
+
OneGadget::Gadget.add(build_id, 258396,
|
18
|
+
constraints: ["writable: x20+0x338", "x3+0x7c0 == NULL"],
|
19
|
+
effect: "execve(\"/bin/sh\", sp+0x70, environ)")
|
20
|
+
OneGadget::Gadget.add(build_id, 258400,
|
21
|
+
constraints: ["writable: x20+0x338", "x3 == NULL"],
|
22
|
+
effect: "execve(\"/bin/sh\", sp+0x70, environ)")
|
23
|
+
OneGadget::Gadget.add(build_id, 258436,
|
24
|
+
constraints: ["writable: x19+0x4", "writable: x20+0x338", "[sp+0x70] == NULL"],
|
25
|
+
effect: "execve(\"/bin/sh\", sp+0x70, environ)")
|
26
|
+
OneGadget::Gadget.add(build_id, 258472,
|
27
|
+
constraints: ["writable: x19+0x4", "writable: x20+0x338", "[x21] == NULL || x21 == NULL"],
|
28
|
+
effect: "execve(\"/bin/sh\", x21, environ)")
|
29
|
+
OneGadget::Gadget.add(build_id, 409212,
|
30
|
+
constraints: ["x2+0x7c8 == NULL"],
|
31
|
+
effect: "execl(\"/bin/sh\", \"sh\", x2+0x7c8)")
|
32
|
+
OneGadget::Gadget.add(build_id, 409224,
|
33
|
+
constraints: ["x1+0x7c0 == NULL"],
|
34
|
+
effect: "execl(\"/bin/sh\", x1+0x7c0)")
|
35
|
+
OneGadget::Gadget.add(build_id, 409232,
|
36
|
+
constraints: ["x1 == NULL"],
|
37
|
+
effect: "execl(\"/bin/sh\", x1)")
|
38
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'one_gadget/gadget'
|
2
|
+
# https://gitlab.com/libcdb/libcdb/blob/master/libc/libc6-amd64_2.27-3ubuntu1_i386/lib64/libc-2.27.so
|
3
|
+
#
|
4
|
+
# Advanced Micro Devices X86-64
|
5
|
+
#
|
6
|
+
# GNU C Library (Ubuntu GLIBC 2.27-3ubuntu1) stable release version 2.27.
|
7
|
+
# Copyright (C) 2018 Free Software Foundation, Inc.
|
8
|
+
# This is free software; see the source for copying conditions.
|
9
|
+
# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
|
10
|
+
# PARTICULAR PURPOSE.
|
11
|
+
# Compiled by GNU CC version 7.3.0.
|
12
|
+
# libc ABIs: UNIQUE IFUNC
|
13
|
+
# For bug reporting instructions, please see:
|
14
|
+
# <https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
|
15
|
+
|
16
|
+
build_id = File.basename(__FILE__, '.rb').split('-').last
|
17
|
+
OneGadget::Gadget.add(build_id, 271374,
|
18
|
+
constraints: ["rax == NULL"],
|
19
|
+
effect: "execve(\"/bin/sh\", rsp+0x30, environ)")
|
20
|
+
OneGadget::Gadget.add(build_id, 271458,
|
21
|
+
constraints: ["[rsp+0x30] == NULL"],
|
22
|
+
effect: "execve(\"/bin/sh\", rsp+0x30, environ)")
|
23
|
+
OneGadget::Gadget.add(build_id, 806783,
|
24
|
+
constraints: ["[r13] == NULL || r13 == NULL", "[r12] == NULL || r12 == NULL"],
|
25
|
+
effect: "execve(\"/bin/sh\", r13, r12)")
|
26
|
+
OneGadget::Gadget.add(build_id, 930286,
|
27
|
+
constraints: ["[rsp+0x60] == NULL"],
|
28
|
+
effect: "execve(\"/bin/sh\", rsp+0x60, environ)")
|
29
|
+
OneGadget::Gadget.add(build_id, 930298,
|
30
|
+
constraints: ["[rsi] == NULL || rsi == NULL", "[[rax]] == NULL || [rax] == NULL"],
|
31
|
+
effect: "execve(\"/bin/sh\", rsi, [rax])")
|
32
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'one_gadget/gadget'
|
2
|
+
# https://gitlab.com/libcdb/libcdb/blob/master/libc/libc6-i386_2.28-0ubuntu1_amd64/lib32/libc-2.28.so
|
3
|
+
#
|
4
|
+
# Intel 80386
|
5
|
+
#
|
6
|
+
# GNU C Library (Ubuntu GLIBC 2.28-0ubuntu1) stable release version 2.28.
|
7
|
+
# Copyright (C) 2018 Free Software Foundation, Inc.
|
8
|
+
# This is free software; see the source for copying conditions.
|
9
|
+
# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
|
10
|
+
# PARTICULAR PURPOSE.
|
11
|
+
# Compiled by GNU CC version 8.2.0.
|
12
|
+
# libc ABIs: UNIQUE IFUNC ABSOLUTE
|
13
|
+
# For bug reporting instructions, please see:
|
14
|
+
# <https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
|
15
|
+
|
16
|
+
build_id = File.basename(__FILE__, '.rb').split('-').last
|
17
|
+
OneGadget::Gadget.add(build_id, 256230,
|
18
|
+
constraints: ["esi is the GOT address of libc", "[esp+0x34] == NULL"],
|
19
|
+
effect: "execve(\"/bin/sh\", esp+0x34, environ)")
|
20
|
+
OneGadget::Gadget.add(build_id, 256232,
|
21
|
+
constraints: ["esi is the GOT address of libc", "[esp+0x38] == NULL"],
|
22
|
+
effect: "execve(\"/bin/sh\", esp+0x38, environ)")
|
23
|
+
OneGadget::Gadget.add(build_id, 256236,
|
24
|
+
constraints: ["esi is the GOT address of libc", "[esp+0x3c] == NULL"],
|
25
|
+
effect: "execve(\"/bin/sh\", esp+0x3c, environ)")
|
26
|
+
OneGadget::Gadget.add(build_id, 256243,
|
27
|
+
constraints: ["esi is the GOT address of libc", "[esp+0x40] == NULL"],
|
28
|
+
effect: "execve(\"/bin/sh\", esp+0x40, environ)")
|
29
|
+
OneGadget::Gadget.add(build_id, 256278,
|
30
|
+
constraints: ["esi is the GOT address of libc", "[eax] == NULL || eax == NULL", "[[esp]] == NULL || [esp] == NULL"],
|
31
|
+
effect: "execve(\"/bin/sh\", eax, [esp])")
|
32
|
+
OneGadget::Gadget.add(build_id, 256279,
|
33
|
+
constraints: ["esi is the GOT address of libc", "[[esp]] == NULL || [esp] == NULL", "[[esp+0x4]] == NULL || [esp+0x4] == NULL"],
|
34
|
+
effect: "execve(\"/bin/sh\", [esp], [esp+0x4])")
|
35
|
+
OneGadget::Gadget.add(build_id, 429851,
|
36
|
+
constraints: ["esi is the GOT address of libc", "eax == NULL"],
|
37
|
+
effect: "execl(\"/bin/sh\", eax)")
|
38
|
+
OneGadget::Gadget.add(build_id, 429852,
|
39
|
+
constraints: ["esi is the GOT address of libc", "[esp] == NULL"],
|
40
|
+
effect: "execl(\"/bin/sh\", [esp])")
|
41
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'one_gadget/gadget'
|
2
|
+
# https://gitlab.com/libcdb/libcdb/blob/master/libc/libc6_2.28-0ubuntu1_i386/lib/i386-linux-gnu/libc-2.28.so
|
3
|
+
#
|
4
|
+
# Intel 80386
|
5
|
+
#
|
6
|
+
# GNU C Library (Ubuntu GLIBC 2.28-0ubuntu1) stable release version 2.28.
|
7
|
+
# Copyright (C) 2018 Free Software Foundation, Inc.
|
8
|
+
# This is free software; see the source for copying conditions.
|
9
|
+
# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
|
10
|
+
# PARTICULAR PURPOSE.
|
11
|
+
# Compiled by GNU CC version 8.2.0.
|
12
|
+
# libc ABIs: UNIQUE IFUNC ABSOLUTE
|
13
|
+
# For bug reporting instructions, please see:
|
14
|
+
# <https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
|
15
|
+
|
16
|
+
build_id = File.basename(__FILE__, '.rb').split('-').last
|
17
|
+
OneGadget::Gadget.add(build_id, 257699,
|
18
|
+
constraints: ["esi is the GOT address of libc", "[esp+0x34] == NULL"],
|
19
|
+
effect: "execve(\"/bin/sh\", esp+0x34, environ)")
|
20
|
+
OneGadget::Gadget.add(build_id, 257701,
|
21
|
+
constraints: ["esi is the GOT address of libc", "[esp+0x38] == NULL"],
|
22
|
+
effect: "execve(\"/bin/sh\", esp+0x38, environ)")
|
23
|
+
OneGadget::Gadget.add(build_id, 257705,
|
24
|
+
constraints: ["esi is the GOT address of libc", "[esp+0x3c] == NULL"],
|
25
|
+
effect: "execve(\"/bin/sh\", esp+0x3c, environ)")
|
26
|
+
OneGadget::Gadget.add(build_id, 257712,
|
27
|
+
constraints: ["esi is the GOT address of libc", "[esp+0x40] == NULL"],
|
28
|
+
effect: "execve(\"/bin/sh\", esp+0x40, environ)")
|
29
|
+
OneGadget::Gadget.add(build_id, 257747,
|
30
|
+
constraints: ["esi is the GOT address of libc", "[eax] == NULL || eax == NULL", "[[esp]] == NULL || [esp] == NULL"],
|
31
|
+
effect: "execve(\"/bin/sh\", eax, [esp])")
|
32
|
+
OneGadget::Gadget.add(build_id, 257748,
|
33
|
+
constraints: ["esi is the GOT address of libc", "[[esp]] == NULL || [esp] == NULL", "[[esp+0x4]] == NULL || [esp+0x4] == NULL"],
|
34
|
+
effect: "execve(\"/bin/sh\", [esp], [esp+0x4])")
|
35
|
+
OneGadget::Gadget.add(build_id, 433019,
|
36
|
+
constraints: ["esi is the GOT address of libc", "eax == NULL"],
|
37
|
+
effect: "execl(\"/bin/sh\", eax)")
|
38
|
+
OneGadget::Gadget.add(build_id, 433020,
|
39
|
+
constraints: ["esi is the GOT address of libc", "[esp] == NULL"],
|
40
|
+
effect: "execl(\"/bin/sh\", [esp])")
|
41
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'one_gadget/gadget'
|
2
|
+
# https://gitlab.com/libcdb/libcdb/blob/master/libc/libc6_2.28-0ubuntu1_amd64/lib/x86_64-linux-gnu/libc-2.28.so
|
3
|
+
#
|
4
|
+
# Advanced Micro Devices X86-64
|
5
|
+
#
|
6
|
+
# GNU C Library (Ubuntu GLIBC 2.28-0ubuntu1) stable release version 2.28.
|
7
|
+
# Copyright (C) 2018 Free Software Foundation, Inc.
|
8
|
+
# This is free software; see the source for copying conditions.
|
9
|
+
# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
|
10
|
+
# PARTICULAR PURPOSE.
|
11
|
+
# Compiled by GNU CC version 8.2.0.
|
12
|
+
# libc ABIs: UNIQUE IFUNC ABSOLUTE
|
13
|
+
# For bug reporting instructions, please see:
|
14
|
+
# <https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
|
15
|
+
|
16
|
+
build_id = File.basename(__FILE__, '.rb').split('-').last
|
17
|
+
OneGadget::Gadget.add(build_id, 328070,
|
18
|
+
constraints: ["rcx == NULL"],
|
19
|
+
effect: "execve(\"/bin/sh\", rsp+0x40, environ)")
|
20
|
+
OneGadget::Gadget.add(build_id, 328163,
|
21
|
+
constraints: ["[rsp+0x40] == NULL"],
|
22
|
+
effect: "execve(\"/bin/sh\", rsp+0x40, environ)")
|
23
|
+
OneGadget::Gadget.add(build_id, 328175,
|
24
|
+
constraints: ["[rsi] == NULL || rsi == NULL", "[[rax]] == NULL || [rax] == NULL"],
|
25
|
+
effect: "execve(\"/bin/sh\", rsi, [rax])")
|
26
|
+
OneGadget::Gadget.add(build_id, 914335,
|
27
|
+
constraints: ["[rcx] == NULL || rcx == NULL", "[[rbp-0x70]] == NULL || [rbp-0x70] == NULL"],
|
28
|
+
effect: "execve(\"/bin/sh\", rcx, [rbp-0x70])")
|
29
|
+
OneGadget::Gadget.add(build_id, 914339,
|
30
|
+
constraints: ["[rcx] == NULL || rcx == NULL", "[rdx] == NULL || rdx == NULL"],
|
31
|
+
effect: "execve(\"/bin/sh\", rcx, rdx)")
|
32
|
+
OneGadget::Gadget.add(build_id, 914342,
|
33
|
+
constraints: ["[rsi] == NULL || rsi == NULL", "[rdx] == NULL || rdx == NULL"],
|
34
|
+
effect: "execve(\"/bin/sh\", rsi, rdx)")
|
35
|
+
OneGadget::Gadget.add(build_id, 1064784,
|
36
|
+
constraints: ["[rsp+0x70] == NULL"],
|
37
|
+
effect: "execve(\"/bin/sh\", rsp+0x70, environ)")
|
38
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'one_gadget/gadget'
|
2
|
+
# https://gitlab.com/libcdb/libcdb/blob/master/libc/libc6-amd64_2.28-0ubuntu1_i386/lib64/libc-2.28.so
|
3
|
+
#
|
4
|
+
# Advanced Micro Devices X86-64
|
5
|
+
#
|
6
|
+
# GNU C Library (Ubuntu GLIBC 2.28-0ubuntu1) stable release version 2.28.
|
7
|
+
# Copyright (C) 2018 Free Software Foundation, Inc.
|
8
|
+
# This is free software; see the source for copying conditions.
|
9
|
+
# There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
|
10
|
+
# PARTICULAR PURPOSE.
|
11
|
+
# Compiled by GNU CC version 8.2.0.
|
12
|
+
# libc ABIs: UNIQUE IFUNC ABSOLUTE
|
13
|
+
# For bug reporting instructions, please see:
|
14
|
+
# <https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
|
15
|
+
|
16
|
+
build_id = File.basename(__FILE__, '.rb').split('-').last
|
17
|
+
OneGadget::Gadget.add(build_id, 281407,
|
18
|
+
constraints: ["rax == NULL"],
|
19
|
+
effect: "execve(\"/bin/sh\", rsp+0x30, environ)")
|
20
|
+
OneGadget::Gadget.add(build_id, 281491,
|
21
|
+
constraints: ["[rsp+0x30] == NULL"],
|
22
|
+
effect: "execve(\"/bin/sh\", rsp+0x30, environ)")
|
23
|
+
OneGadget::Gadget.add(build_id, 281503,
|
24
|
+
constraints: ["[rsi] == NULL || rsi == NULL", "[[rax]] == NULL || [rax] == NULL"],
|
25
|
+
effect: "execve(\"/bin/sh\", rsi, [rax])")
|
26
|
+
OneGadget::Gadget.add(build_id, 816106,
|
27
|
+
constraints: ["[r13] == NULL || r13 == NULL", "[r12] == NULL || r12 == NULL"],
|
28
|
+
effect: "execve(\"/bin/sh\", r13, r12)")
|
29
|
+
OneGadget::Gadget.add(build_id, 816109,
|
30
|
+
constraints: ["[r13] == NULL || r13 == NULL", "[rdx] == NULL || rdx == NULL"],
|
31
|
+
effect: "execve(\"/bin/sh\", r13, rdx)")
|
32
|
+
OneGadget::Gadget.add(build_id, 816112,
|
33
|
+
constraints: ["[rsi] == NULL || rsi == NULL", "[rdx] == NULL || rdx == NULL"],
|
34
|
+
effect: "execve(\"/bin/sh\", rsi, rdx)")
|
35
|
+
OneGadget::Gadget.add(build_id, 939838,
|
36
|
+
constraints: ["[rsp+0x60] == NULL"],
|
37
|
+
effect: "execve(\"/bin/sh\", rsp+0x60, environ)")
|
38
|
+
|
@@ -0,0 +1,176 @@
|
|
1
|
+
require 'one_gadget/abi'
|
2
|
+
require 'one_gadget/emulators/instruction'
|
3
|
+
require 'one_gadget/emulators/processor'
|
4
|
+
|
5
|
+
module OneGadget
|
6
|
+
module Emulators
|
7
|
+
# Emulator of aarch64.
|
8
|
+
class AArch64 < Processor
|
9
|
+
# Instantiate a {AArch64} object.
|
10
|
+
def initialize
|
11
|
+
super(OneGadget::ABI.aarch64, 'sp')
|
12
|
+
# Constant registers
|
13
|
+
%w[xzr wzr].each { |r| @registers[r] = 0 }
|
14
|
+
@pc = 'pc'
|
15
|
+
end
|
16
|
+
|
17
|
+
# @see OneGadget::Emulators::X86#process!
|
18
|
+
def process!(cmd)
|
19
|
+
inst, args = parse(cmd.gsub(/#-?(0x)?[0-9a-f]+/) { |v| v[1..-1] })
|
20
|
+
sym = "inst_#{inst.inst}".to_sym
|
21
|
+
__send__(sym, *args) != :fail
|
22
|
+
end
|
23
|
+
|
24
|
+
# Supported instruction set.
|
25
|
+
# @return [Array<Instruction>] The supported instructions.
|
26
|
+
def instructions
|
27
|
+
[
|
28
|
+
Instruction.new('add', 3..4),
|
29
|
+
Instruction.new('adrp', 2),
|
30
|
+
Instruction.new('bl', 1),
|
31
|
+
Instruction.new('ldr', 2..3),
|
32
|
+
Instruction.new('mov', 2),
|
33
|
+
Instruction.new('stp', 3),
|
34
|
+
Instruction.new('str', 2..3)
|
35
|
+
]
|
36
|
+
end
|
37
|
+
|
38
|
+
# Return the argument value of calling a function.
|
39
|
+
# @param [Integer] idx
|
40
|
+
# @return [Lambda, Integer]
|
41
|
+
def argument(idx)
|
42
|
+
registers["x#{idx}"]
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def inst_add(dst, src, op2, mode = 'sxtw')
|
48
|
+
check_register!(dst)
|
49
|
+
|
50
|
+
src = OneGadget::Emulators::Lambda.parse(src, predefined: registers)
|
51
|
+
op2 = OneGadget::Emulators::Lambda.parse(op2, predefined: registers)
|
52
|
+
raise_unsupported('add', dst, src, op2) unless op2.is_a?(Integer) && mode == 'sxtw'
|
53
|
+
|
54
|
+
registers[dst] = src + op2
|
55
|
+
end
|
56
|
+
|
57
|
+
def inst_adrp(dst, imm)
|
58
|
+
check_register!(dst)
|
59
|
+
|
60
|
+
registers[dst] = libc_base + imm.to_i(16)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Handle some valid calls.
|
64
|
+
# For example, +sigprocmask+ will always be a valid call
|
65
|
+
# because it just invokes syscall.
|
66
|
+
def inst_bl(addr)
|
67
|
+
# This is the last call
|
68
|
+
return registers[pc] = addr if %w[execve execl].any? { |n| addr.include?(n) }
|
69
|
+
|
70
|
+
# TODO: handle some registers would be fucked after call
|
71
|
+
checker = {
|
72
|
+
'sigprocmask' => {},
|
73
|
+
'__sigaction' => { 2 => :zero? }
|
74
|
+
}
|
75
|
+
func = checker.keys.find { |n| addr.include?(n) }
|
76
|
+
return if func && checker[func].all? { |idx, sym| check_argument(idx, sym) }
|
77
|
+
|
78
|
+
# unhandled case or checker's condition fails
|
79
|
+
:fail
|
80
|
+
end
|
81
|
+
|
82
|
+
def inst_ldr(dst, src, index = 0)
|
83
|
+
check_register!(dst)
|
84
|
+
|
85
|
+
src_l = OneGadget::Emulators::Lambda.parse(src, predefined: registers)
|
86
|
+
registers[dst] = src_l
|
87
|
+
raise_unsupported('ldr', dst, src, index) unless OneGadget::Helper.integer?(index)
|
88
|
+
|
89
|
+
index = Integer(index)
|
90
|
+
return unless src.end_with?('!') || index.nonzero?
|
91
|
+
|
92
|
+
# Two cases:
|
93
|
+
# 1. pre-index mode, +src+ is [reg, imm]!
|
94
|
+
# 2. post-index mode, +src+ is [reg]
|
95
|
+
lmda = OneGadget::Emulators::Lambda.parse(src)
|
96
|
+
registers[lmda.obj] += lmda.immi + index
|
97
|
+
end
|
98
|
+
|
99
|
+
def inst_mov(dst, src)
|
100
|
+
check_register!(dst)
|
101
|
+
|
102
|
+
src = OneGadget::Emulators::Lambda.parse(src, predefined: registers)
|
103
|
+
registers[dst] = src
|
104
|
+
end
|
105
|
+
|
106
|
+
def inst_stp(reg1, reg2, dst)
|
107
|
+
raise_unsupported('stp', reg1, reg2, dst) unless reg64?(reg1) && reg64?(reg2)
|
108
|
+
|
109
|
+
dst_l = OneGadget::Emulators::Lambda.parse(dst, predefined: registers).ref!
|
110
|
+
raise_unsupported('stp', reg1, reg2, dst) unless dst_l.obj == sp && dst_l.deref_count.zero?
|
111
|
+
|
112
|
+
cur_top = dst_l.evaluate(eval_dict)
|
113
|
+
stack[cur_top] = registers[reg1]
|
114
|
+
stack[cur_top + size_t] = registers[reg2]
|
115
|
+
|
116
|
+
registers[sp] += OneGadget::Emulators::Lambda.parse(dst).immi if dst.end_with?('!')
|
117
|
+
end
|
118
|
+
|
119
|
+
def inst_str(src, dst, index = 0)
|
120
|
+
check_register!(src)
|
121
|
+
raise_unsupported('str', src, dst, index) unless OneGadget::Helper.integer?(index)
|
122
|
+
|
123
|
+
dst_l = OneGadget::Emulators::Lambda.parse(dst, predefined: registers).ref!
|
124
|
+
# Only stores on stack.
|
125
|
+
if dst_l.obj == sp && dst_l.deref_count.zero?
|
126
|
+
cur_top = dst_l.evaluate(eval_dict)
|
127
|
+
stack[cur_top] = registers[src]
|
128
|
+
else
|
129
|
+
# Unlike the stack case, don't know where to save the value.
|
130
|
+
# Simply add a constraint.
|
131
|
+
add_writable(dst_l)
|
132
|
+
end
|
133
|
+
|
134
|
+
index = Integer(index)
|
135
|
+
return unless dst.end_with?('!') || index.nonzero?
|
136
|
+
|
137
|
+
# Two cases:
|
138
|
+
# 1. pre-index mode, +dst+ is [reg, imm]!
|
139
|
+
# 2. post-index mode, +dst+ is [reg]
|
140
|
+
lmda = OneGadget::Emulators::Lambda.parse(dst)
|
141
|
+
registers[lmda.obj] += lmda.immi + index
|
142
|
+
end
|
143
|
+
|
144
|
+
def libc_base
|
145
|
+
@libc_base ||= OneGadget::Emulators::Lambda.new('$base')
|
146
|
+
end
|
147
|
+
|
148
|
+
# Checks if +reg+ is a 64-bit register.
|
149
|
+
def reg64?(reg)
|
150
|
+
register?(reg) && reg.start_with?('x')
|
151
|
+
end
|
152
|
+
|
153
|
+
# Override
|
154
|
+
# def global_var?(obj)
|
155
|
+
# str = obj.is_a?(OneGadget::Emulators::Lambda) ? obj.obj.to_s : obj.to_s
|
156
|
+
# # TODO: check if this assumption usually correct
|
157
|
+
# (%w[x19 x20 x21] << libc_base.obj).any? { |r| str.include?(r) }
|
158
|
+
# end
|
159
|
+
|
160
|
+
def add_writable(lmda)
|
161
|
+
# XXX: Better way is check LOAD segment of the libc ELF.
|
162
|
+
# XXX: Should also checks deref_count, but sometimes [[$base+xx]] is also writable..
|
163
|
+
return if lmda.obj == libc_base.obj
|
164
|
+
|
165
|
+
@constraints << [:writable, lmda]
|
166
|
+
end
|
167
|
+
|
168
|
+
class << self
|
169
|
+
# AArch64 is 64-bit.
|
170
|
+
def bits
|
171
|
+
64
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|