- 简介
- 一、基础知识篇
- 二、工具篇
- 三、分类专题篇
- 四、技巧篇
- 五、高级篇
- 六、题解篇
- 6.1 Pwn
- 6.1.1 pwn HCTF2016 brop
- 6.1.2 pwn NJCTF2017 pingme
- 6.1.3 pwn XDCTF2015 pwn200
- 6.1.4 pwn BackdoorCTF2017 Fun-Signals
- 6.1.5 pwn GreHackCTF2017 beerfighter
- 6.1.6 pwn DefconCTF2015 fuckup
- 6.1.7 pwn 0CTF2015 freenote
- 6.1.8 pwn DCTF2017 Flex
- 6.1.9 pwn RHme3 Exploitation
- 6.1.10 pwn 0CTF2017 BabyHeap2017
- 6.1.11 pwn 9447CTF2015 Search-Engine
- 6.1.12 pwn N1CTF2018 vote
- 6.1.13 pwn 34C3CTF2017 readme_revenge
- 6.1.14 pwn 32C3CTF2015 readme
- 6.1.15 pwn 34C3CTF2017 SimpleGC
- 6.1.16 pwn HITBCTF2017 1000levels
- 6.1.17 pwn SECCONCTF2016 jmper
- 6.1.18 pwn HITBCTF2017 Sentosa
- 6.1.19 pwn HITBCTF2018 gundam
- 6.1.20 pwn 33C3CTF2016 babyfengshui
- 6.1.21 pwn HITCONCTF2016 Secret_Holder
- 6.1.22 pwn HITCONCTF2016 Sleepy_Holder
- 6.1.23 pwn BCTF2016 bcloud
- 6.1.24 pwn HITCONCTF2016 HouseofOrange
- 6.1.25 pwn HCTF2017 babyprintf
- 6.1.26 pwn 34C3CTF2017 300
- 6.1.27 pwn SECCONCTF2016 tinypad
- 6.1.28 pwn ASISCTF2016 b00ks
- 6.1.29 pwn Insomni'hackteaserCTF2017 TheGreatEscapepart-3
- 6.1.30 pwn HITCONCTF2017 Ghostinthe_heap
- 6.1.31 pwn HITBCTF2018 mutepig
- 6.1.32 pwn SECCONCTF2017 vmnofun
- 6.1.33 pwn 34C3CTF2017 LFA
- 6.1.34 pwn N1CTF2018 memsafety
- 6.1.35 pwn 0CTF2018 heapstorm2
- 6.1.36 pwn NJCTF2017 messager
- 6.1.37 pwn sixstarctf2018 babystack
- 6.1.38 pwn HITCONCMT2017 pwn200
- 6.1.39 pwn BCTF2018 houseofAtum
- 6.1.40 pwn LCTF2016 pwn200
- 6.1.41 pwn PlaidCTF2015 PlaidDB
- 6.1.42 pwn hacklu2015 bookstore
- 6.1.43 pwn 0CTF2018 babyheap
- 6.1.44 pwn ASIS2017 start_hard
- 6.1.45 pwn LCTF2016 pwn100
- 6.2 Reverse
- 6.3 Web
- 6.1 Pwn
- 七、实战篇
- 7.1 CVE
- 7.1.1 CVE-2017-11543 tcpdump sliplink_print 栈溢出漏洞
- 7.1.2 CVE-2015-0235 glibc _nsshostnamedigitsdots 堆溢出漏洞
- 7.1.3 CVE-2016-4971 wget 任意文件上传漏洞
- 7.1.4 CVE-2017-13089 wget skipshortbody 栈溢出漏洞
- 7.1.5 CVE–2018-1000001 glibc realpath 缓冲区下溢漏洞
- 7.1.6 CVE-2017-9430 DNSTracer 栈溢出漏洞
- 7.1.7 CVE-2018-6323 GNU binutils elfobjectp 整型溢出漏洞
- 7.1.8 CVE-2010-2883 Adobe CoolType SING 表栈溢出漏洞
- 7.1.9 CVE-2010-3333 Microsoft Word RTF pFragments 栈溢出漏洞
- 7.1 CVE
- 八、学术篇
- 8.1 The Geometry of Innocent Flesh on the Bone: Return-into-libc without Function Calls (on the x86)
- 8.2 Return-Oriented Programming without Returns
- 8.3 Return-Oriented Rootkits: Bypassing Kernel Code Integrity Protection Mechanisms
- 8.4 ROPdefender: A Detection Tool to Defend Against Return-Oriented Programming Attacks
- 8.5 Data-Oriented Programming: On the Expressiveness of Non-Control Data Attacks
- 8.7 What Cannot Be Read, Cannot Be Leveraged? Revisiting Assumptions of JIT-ROP Defenses
- 8.9 Symbolic Execution for Software Testing: Three Decades Later
- 8.10 AEG: Automatic Exploit Generation
- 8.11 Address Space Layout Permutation (ASLP): Towards Fine-Grained Randomization of Commodity Software
- 8.13 New Frontiers of Reverse Engineering
- 8.14 Who Allocated My Memory? Detecting Custom Memory Allocators in C Binaries
- 8.21 Micro-Virtualization Memory Tracing to Detect and Prevent Spraying Attacks
- 8.22 Practical Memory Checking With Dr. Memory
- 8.23 Evaluating the Effectiveness of Current Anti-ROP Defenses
- 8.24 How to Make ASLR Win the Clone Wars: Runtime Re-Randomization
- 8.25 (State of) The Art of War: Offensive Techniques in Binary Analysis
- 8.26 Driller: Augmenting Fuzzing Through Selective Symbolic Execution
- 8.27 Firmalice - Automatic Detection of Authentication Bypass Vulnerabilities in Binary Firmware
- 8.28 Cross-Architecture Bug Search in Binary Executables
- 8.29 Dynamic Hooks: Hiding Control Flow Changes within Non-Control Data
- 8.30 Preventing brute force attacks against stack canary protection on networking servers
- 8.33 Under-Constrained Symbolic Execution: Correctness Checking for Real Code
- 8.34 Enhancing Symbolic Execution with Veritesting
- 8.38 TaintEraser: Protecting Sensitive Data Leaks Using Application-Level Taint Tracking
- 8.39 DART: Directed Automated Random Testing
- 8.40 EXE: Automatically Generating Inputs of Death
- 8.41 IntPatch: Automatically Fix Integer-Overflow-to-Buffer-Overflow Vulnerability at Compile-Time
- 8.42 Dynamic Taint Analysis for Automatic Detection, Analysis, and Signature Generation of Exploits on Commodity Software
- 8.43 DTA++: Dynamic Taint Analysis with Targeted Control-Flow Propagation
- 8.44 Superset Disassembly: Statically Rewriting x86 Binaries Without Heuristics
- 8.45 Ramblr: Making Reassembly Great Again
- 8.46 FreeGuard: A Faster Secure Heap Allocator
- 8.48 Reassembleable Disassembling
- 九、附录
4.2 Linux 命令行技巧
通配符
*
:匹配任意字符ls test*
?
:匹配任意单个字符ls test?
[...]
:匹配括号内的任意单个字符ls test[123]
[!...]
:匹配除括号内字符以外的单个字符ls test[!123]
重定向输入字符
有时候我们需要在 shell 里输入键盘上没有对应的字符,如 0x1F
,就需要使用重定向输入。下面是一个例子:
#include<stdio.h>
#include<string.h>
void main() {
char data[8];
char str[8];
printf("请输入十六进制为 0x1f 的字符: ");
sprintf(str, "%c", 31);
scanf("%s", data);
if (!strcmp((const char *)data, (const char *)str)) {
printf("correct\n");
} else {
printf("wrong\n");
}
}
$ gcc test.c
$ ./a.out
请输入十六进制为 0x1f 的字符: 0x1f
wrong
$ echo -e "\x1f"
$ echo -e "\x1f" | ./a.out
请输入十六进制为 0x1f 的字符: correct
从可执行文件中提取 shellcode
for i in `objdump -d print_flag | tr '\t' ' ' | tr ' ' '\n' | egrep '^[0-9a-f]{2}$' ` ; do echo -n "\x$i" ; done
注意:在 objdump 中空字节可能会被删除。
查看进程虚拟地址空间
有时我们需要知道一个进程的虚拟地址空间是如何使用的,以确定栈是否是可执行的。
$ cat /proc/<PID>/maps
下面我们分别来看看可执行栈和不可执行栈的不同:
$ cat hello.c
#include <stdio.h>
void main()
{
char buf[128];
scanf("hello, world: %s\n", buf);
}
$ gcc hello.c -o a.out1
$ ./a.out1 &
[1] 7403
$ cat /proc/7403/maps
555555554000-555555555000 r-xp 00000000 08:01 26389924 /home/firmy/a.out1
555555754000-555555755000 r--p 00000000 08:01 26389924 /home/firmy/a.out1
555555755000-555555756000 rw-p 00001000 08:01 26389924 /home/firmy/a.out1
555555756000-555555777000 rw-p 00000000 00:00 0 [heap]
7ffff7a33000-7ffff7bd0000 r-xp 00000000 08:01 21372436 /usr/lib/libc-2.25.so
7ffff7bd0000-7ffff7dcf000 ---p 0019d000 08:01 21372436 /usr/lib/libc-2.25.so
7ffff7dcf000-7ffff7dd3000 r--p 0019c000 08:01 21372436 /usr/lib/libc-2.25.so
7ffff7dd3000-7ffff7dd5000 rw-p 001a0000 08:01 21372436 /usr/lib/libc-2.25.so
7ffff7dd5000-7ffff7dd9000 rw-p 00000000 00:00 0
7ffff7dd9000-7ffff7dfc000 r-xp 00000000 08:01 21372338 /usr/lib/ld-2.25.so
7ffff7fbc000-7ffff7fbe000 rw-p 00000000 00:00 0
7ffff7ff8000-7ffff7ffa000 r--p 00000000 00:00 0 [vvar]
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r--p 00023000 08:01 21372338 /usr/lib/ld-2.25.so
7ffff7ffd000-7ffff7ffe000 rw-p 00024000 08:01 21372338 /usr/lib/ld-2.25.so
7ffff7ffe000-7ffff7fff000 rw-p 00000000 00:00 0
7ffffffde000-7ffffffff000 rw-p 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
[1]+ Stopped ./a.out1
$ gcc -z execstack hello.c -o a.out2
$ ./a.out2 &
[2] 7467
[firmy@manjaro ~]$ cat /proc/7467/maps
555555554000-555555555000 r-xp 00000000 08:01 26366643 /home/firmy/a.out2
555555754000-555555755000 r-xp 00000000 08:01 26366643 /home/firmy/a.out2
555555755000-555555756000 rwxp 00001000 08:01 26366643 /home/firmy/a.out2
555555756000-555555777000 rwxp 00000000 00:00 0 [heap]
7ffff7a33000-7ffff7bd0000 r-xp 00000000 08:01 21372436 /usr/lib/libc-2.25.so
7ffff7bd0000-7ffff7dcf000 ---p 0019d000 08:01 21372436 /usr/lib/libc-2.25.so
7ffff7dcf000-7ffff7dd3000 r-xp 0019c000 08:01 21372436 /usr/lib/libc-2.25.so
7ffff7dd3000-7ffff7dd5000 rwxp 001a0000 08:01 21372436 /usr/lib/libc-2.25.so
7ffff7dd5000-7ffff7dd9000 rwxp 00000000 00:00 0
7ffff7dd9000-7ffff7dfc000 r-xp 00000000 08:01 21372338 /usr/lib/ld-2.25.so
7ffff7fbc000-7ffff7fbe000 rwxp 00000000 00:00 0
7ffff7ff8000-7ffff7ffa000 r--p 00000000 00:00 0 [vvar]
7ffff7ffa000-7ffff7ffc000 r-xp 00000000 00:00 0 [vdso]
7ffff7ffc000-7ffff7ffd000 r-xp 00023000 08:01 21372338 /usr/lib/ld-2.25.so
7ffff7ffd000-7ffff7ffe000 rwxp 00024000 08:01 21372338 /usr/lib/ld-2.25.so
7ffff7ffe000-7ffff7fff000 rwxp 00000000 00:00 0
7ffffffde000-7ffffffff000 rwxp 00000000 00:00 0 [stack]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]
[2]+ Stopped ./a.out2
当使用 -z execstack
参数进行编译时,会关闭 Stack Protector
。我们可以看到在 a.out1
中的 stack
是 rw
的,而 a.out2
中则是 rwx
的。
maps
文件有 6 列,分别为:
- 地址:库在进程里地址范围
- 权限:虚拟内存的权限,r=读,w=写,x=执行,s=共享,p=私有
- 偏移量:库在进程里地址偏移量
- 设备:映像文件的主设备号和次设备号,可以通过通过
cat /proc/devices
查看设备号对应的设备名 - 节点:映像文件的节点号
- 路径: 映像文件的路径,经常同一个地址有两个地址范围,那是因为一段是
r-xp
为只读的代码段,一段是rwxp
为可读写的数据段
除了 /proc/<PID>/maps
之外,还有一些有用的设备和文件。
/proc/kcore
是 Linux 内核运行时的动态 core 文件。它是一个原始的内存转储,以 ELF core 文件的形式呈现,可以使用 GDB 来调试和分析内核。/boot/System.map
是一个特定内核的内核符号表。它是你当前运行的内核的 System.map 的链接。/proc/kallsyms
和System.map
很类似,但它在/proc
目录下,所以是由内核维护的,并可以动态更新。/proc/iomem
和/proc/<pid>/maps
类似,但它是用于系统内存的。如:# cat /proc/iomem | grep Kernel 01000000-01622d91 : Kernel code 01622d92-01b0ddff : Kernel data 01c56000-01d57fff : Kernel bss
ASCII 表
ASCII 表将键盘上的所有字符映射到固定的数字。有时候我们可能需要查看这张表:
$ man ascii
Oct Dec Hex Char Oct Dec Hex Char
────────────────────────────────────────────────────────────────────────
000 0 00 NUL '\0' (null character) 100 64 40 @
001 1 01 SOH (start of heading) 101 65 41 A
002 2 02 STX (start of text) 102 66 42 B
003 3 03 ETX (end of text) 103 67 43 C
004 4 04 EOT (end of transmission) 104 68 44 D
005 5 05 ENQ (enquiry) 105 69 45 E
006 6 06 ACK (acknowledge) 106 70 46 F
007 7 07 BEL '\a' (bell) 107 71 47 G
010 8 08 BS '\b' (backspace) 110 72 48 H
011 9 09 HT '\t' (horizontal tab) 111 73 49 I
012 10 0A LF '\n' (new line) 112 74 4A J
013 11 0B VT '\v' (vertical tab) 113 75 4B K
014 12 0C FF '\f' (form feed) 114 76 4C L
015 13 0D CR '\r' (carriage ret) 115 77 4D M
016 14 0E SO (shift out) 116 78 4E N
017 15 0F SI (shift in) 117 79 4F O
020 16 10 DLE (data link escape) 120 80 50 P
021 17 11 DC1 (device control 1) 121 81 51 Q
022 18 12 DC2 (device control 2) 122 82 52 R
023 19 13 DC3 (device control 3) 123 83 53 S
024 20 14 DC4 (device control 4) 124 84 54 T
025 21 15 NAK (negative ack.) 125 85 55 U
026 22 16 SYN (synchronous idle) 126 86 56 V
027 23 17 ETB (end of trans. blk) 127 87 57 W
030 24 18 CAN (cancel) 130 88 58 X
031 25 19 EM (end of medium) 131 89 59 Y
032 26 1A SUB (substitute) 132 90 5A Z
033 27 1B ESC (escape) 133 91 5B [
034 28 1C FS (file separator) 134 92 5C \ '\\'
035 29 1D GS (group separator) 135 93 5D ]
036 30 1E RS (record separator) 136 94 5E ^
037 31 1F US (unit separator) 137 95 5F _
040 32 20 SPACE 140 96 60 `
041 33 21 ! 141 97 61 a
042 34 22 " 142 98 62 b
043 35 23 # 143 99 63 c
044 36 24 $ 144 100 64 d
045 37 25 % 145 101 65 e
046 38 26 & 146 102 66 f
047 39 27 ' 147 103 67 g
050 40 28 ( 150 104 68 h
051 41 29 ) 151 105 69 i
052 42 2A * 152 106 6A j
053 43 2B + 153 107 6B k
054 44 2C , 154 108 6C l
055 45 2D - 155 109 6D m
056 46 2E . 156 110 6E n
057 47 2F / 157 111 6F o
060 48 30 0 160 112 70 p
061 49 31 1 161 113 71 q
062 50 32 2 162 114 72 r
063 51 33 3 163 115 73 s
064 52 34 4 164 116 74 t
065 53 35 5 165 117 75 u
066 54 36 6 166 118 76 v
067 55 37 7 167 119 77 w
070 56 38 8 170 120 78 x
071 57 39 9 171 121 79 y
072 58 3A : 172 122 7A z
073 59 3B ; 173 123 7B {
074 60 3C < 174 124 7C |
075 61 3D = 175 125 7D }
076 62 3E > 176 126 7E ~
077 63 3F ? 177 127 7F DEL
Tables
For convenience, below are more compact tables in hex and decimal.
2 3 4 5 6 7 30 40 50 60 70 80 90 100 110 120
------------- ---------------------------------
0: 0 @ P ` p 0: ( 2 < F P Z d n x
1: ! 1 A Q a q 1: ) 3 = G Q [ e o y
2: " 2 B R b r 2: * 4 > H R \ f p z
3: # 3 C S c s 3: ! + 5 ? I S ] g q {
4: $ 4 D T d t 4: " , 6 @ J T ^ h r |
5: % 5 E U e u 5: # - 7 A K U _ i s }
6: & 6 F V f v 6: $ . 8 B L V ` j t ~
7: ' 7 G W g w 7: % / 9 C M W a k u DEL
8: ( 8 H X h x 8: & 0 : D N X b l v
9: ) 9 I Y i y 9: ' 1 ; E O Y c m w
A: * : J Z j z
B: + ; K [ k {
C: , < L \ l |
D: - = M ] m }
E: . > N ^ n ~
F: / ? O _ o DEL
Hex 转 Char:
$ echo -e '\x41\x42\x43\x44'
$ printf '\x41\x42\x43\x44'
$ python -c 'print(u"\x41\x42\x43\x44")'
$ perl -e 'print "\x41\x42\x43\x44";'
Char 转 Hex:
$ python -c 'print(b"ABCD".hex())'
nohup 和 &
用 nohup
运行命令可以使命令永久的执行下去,和 Shell 没有关系,而 &
表示设置此进程为后台进程。默认情况下,进程是前台进程,这时就把 Shell 给占据了,我们无法进行其他操作,如果我们希望其在后台运行,可以使用 &
达到这个目的。
该命令的一般形式为:
$ nohup <command> &
前后台进程切换
可以通过 bg
(background)和 fg
(foreground)命令进行前后台进程切换。
显示Linux中的任务列表及任务状态:
$ jobs -l
[1]+ 9433 Stopped (tty input) ./a.out
将进程放到后台运行:
$ bg 1
将后台进程放到前台运行:
$ fg 1
cat -
通常使用 cat 时后面都会跟一个文件名,但如果没有,或者只有一个 -
,则表示从标准输入读取数据,它会保持标准输入开启,如:
$ cat -
hello world
hello world
^C
更进一步,如果你采用 cat file -
的用法,它会先输出 file 的内容,然后是标准输入,它将标准输入的数据复制到标准输出,并保持标准输入开启:
$ echo hello > text
$ cat text -
hello
world
world
^C
有时我们在向程序发送 paylaod 的时候,它执行完就直接退出了,并没有开启 shell,我们就可以利用上面的技巧:
$ cat payload | ./a.out
> Segmentation fault (core dumped)
$ cat payload - | ./a.out
whoami
firmy
^C
Segmentation fault (core dumped)
这样就得到了 shell。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论