첫 CCE 대회였는데 하필 여행일정에 대회날이 겹쳐서 차에서 대충 몇문제 풀었다...
대충 본문제는 네문제였고 그중 한문제는 좀 복잡해서 따로 공부좀 하고 Writeup을 올리겠다.
1. OSJarvis
자바로 짜여진 웹인데 활성화 되어있는 기능은 파일업로드 한가지 뿐이었다.
파일 업로드 코드는 다음과 같다.
public String execute() throws Exception {
if (uploadFileName != null) {
try {
String uploadDirectory = System.getProperty("user.dir") + "/uploads/";
File destFile = new File(uploadDirectory, uploadFileName);
FileUtils.copyFile(upload, destFile);
addActionMessage("File uploaded successfully to " + destFile.getAbsolutePath());
return SUCCESS;
} catch (Exception e) {
addActionError(e.getMessage());
e.printStackTrace();
return ERROR;
}
} else {
return INPUT;
}
}
사실상 파일 업로드 로직엔 딱히 취약점이 안보인다... 그래서 다른부분을 살펴보다가 web.xml에 struts를 사용하고 있다는 점을 확인했다.
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="struts_blank" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Struts Blank</display-name>
<filter>
<filter-name>struts2</filter-name>
<filter-class>
org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
struts 2.4버전을 사용중인데 내가 알기론 2.5버전 이하에서 Struts RCE 취약점이 터진다.
Struts RCE 취약점은 파일을 업로드할때 파일명을 상위폴더로 지정해서 웹셸을 업로드해 RCE하는 취약점이다.
RCE 공격은 아래 코드로 공격 가능하다.
https://github.com/jakabakos/CVE-2023-50164-Apache-Struts-RCE
바로 셸이 따와지고 flag를 확인 할 수 있다.
요 원리를 이용해서 패킷을 잡아 일일이 하는 방법도 있는데 이건 아래 글에서 잘 정리해두셔서 url만 참고로 올리겠다.
2. internal inspection
이번 웹 문제중 그나마 젤 쉬웠던 문제인듯 하다.
@app.route('/download', methods=['POST'])
def download():
xml_file = request.files['file']
xml_data = xml_file.read()
xml_data = xml_data.decode('UTF-8')
xml_data = xml_data.replace("SYSTEM", "system")
xml_data = xml_data.encode('UTF-8')
parser = etree.XMLParser(encoding='UTF-8')
try:
root = etree.fromstring(xml_data, parser=parser)
except:
root = etree.fromstring("<name>fail</name>", parser=parser)
data = []
try:
for member in root.findall('member'):
name = member.find('name').text
address = member.find('address').text
company = member.find('company').text
job = member.find('job').text
email = member.find('email').text
username = member.find('username').text
data.append([name, address, company, job, email, username])
df = pd.DataFrame(data, columns=['Name', 'Address', 'Company', 'Job', 'Email', 'Username'])
output = io.BytesIO()
df.to_excel(output, index=False, engine='openpyxl')
output.seek(0)
except:
output = str()
return send_file(output, as_attachment=True, mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', download_name='members.xlsx')
/download POST부분에서 XML Parsing을 하는데 여기서 xxe취약점이 터진다.
그런데 xxe payload에서 사용하는 SYSTEM을 system으로 변환시켜 일반적인 페이로드로는 작동을 못시키고 대신
PUBLIC을 사용해 xxe 공격을 할 수 있는 페이로드가 있다.
3. Precious My Asset
dll 파일 분석 문제이다.
dll 파일은 DotPeek 프로그램을 사용해 열 수 있다.
public static void Main(string[] args)
{
IWebHost iwebHost = Program.CreateWebHostBuilder(args).Build();
using (IServiceScope scope = ServiceProviderServiceExtensions.CreateScope(iwebHost.Services))
{
IServiceProvider serviceProvider = scope.ServiceProvider;
RelationalDatabaseFacadeExtensions.Migrate(((DbContext) ServiceProviderServiceExtensions.GetRequiredService<ApplicationDbContext>(serviceProvider)).Database);
ServiceProviderServiceExtensions.GetRequiredService<IConfiguration>(iwebHost.Services);
string cipherText = "M/AGmnYDZRQIOO6+xXpxwtZHpwE81Z6cYwf5B0xgyWA=";
string managerUserPw = "pkd#1kCLKdpe9814#1k3!";
ILogger<Program> requiredService = ServiceProviderServiceExtensions.GetRequiredService<ILogger<Program>>(serviceProvider);
string adminUserPw = AesEncryption.Decrypt(cipherText);
try
{
SeedData.Initialize(serviceProvider, adminUserPw, managerUserPw).Wait();
}
catch (Exception ex)
{
LoggerExtensions.LogError((ILogger) requiredService, ex.Message, new object[1]
{
(object) "An error occurred seeding the DB."
});
}
}
WebHostExtensions.Run(iwebHost);
}
코드가 좀 많긴한데 일단 Program main 코드부터 따와서 보면 adminUserPW랑 managerUserPW를 저장하는걸 확인 가능하다.
adminUserPW는 cipherText를 AES 복호화해서 따오는데 저 복호화 함수 들어가면 AES 암호화할때 사용하는 key와 iv 둘다 확인 가능해서 그거 따와서 복호화하면 admin 패스워드를 알 수 있다.
그리고 admin 아이디는 데이터 저장하는 쪽 코드 가보면 바로 확인 가능하다.
adminID : admin@asset.com
adminPW : ACCE2024ck03k1#!jk#14al
admin으로 접속하면 파일을 업로드 할 수 있는데 코드에서도 확인할 수 있지만 php, php3, jsp 등등 웹셸에 사용할만한 확장자는 다 필터링 시킨다. 근데 그 중 필터링 되지 않는 확장자들도 몇가지 있었는데 그중 난 phar를 사용했다.
phar파일을 업로드 시키고 코드를 보면은 uploads 폴더에다가 파일을 저장해서 /uploads/shell.phar로 접근해보았다.
그런데 허용된 확장자 예를들어 img, png 이런거 이외의 확장자로 접근하면 404 error가 뜬다.
그래서 여기서 써야할게 문제에서 사이트를 두가지를 줬는데 하나는 이 사이트고 다른 하나가 백업 사이트다.
보통 백업 사이트는 이 문제 사이트와 폴더를 공유하기 때문에 백업 사이트에서도 uploads로 접근이 가능할거다.
백업사이트에서 접근해보면은 에러가 뜨지 않고 접근이 가능해진다.
바로 RCE코드로 flag를 찾았다.
Writeup으로 작성해보니 쉬워보이는데.. 막상 대회에서 찾으려하면 좀 어려웠다.
나중엔 팀 구해서 제대로 나가봐야겠다.
'Web Hacking > WriteUp' 카테고리의 다른 글
ASIS CTF 2024 Web Writeup (0) | 2024.09.22 |
---|---|
WhiteHat School 2nd CTF SSH Tunneling Final Writeup (0) | 2024.09.05 |
Project Sekai CTF 2024 Web Writeup (0) | 2024.08.24 |
[CCE 2024] Advanced Login System WriteUp (0) | 2024.08.07 |
[Sechack.kr] Shop WriteUp (0) | 2024.07.19 |